xref: /openbsd-src/gnu/usr.bin/binutils-2.17/binutils/debug.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* debug.c -- Handle generic debugging information.
2*3d8817e4Smiod    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod    Written by Ian Lance Taylor <ian@cygnus.com>.
5*3d8817e4Smiod 
6*3d8817e4Smiod    This file is part of GNU Binutils.
7*3d8817e4Smiod 
8*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
9*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
10*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
11*3d8817e4Smiod    (at your option) any later version.
12*3d8817e4Smiod 
13*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
14*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*3d8817e4Smiod    GNU General Public License for more details.
17*3d8817e4Smiod 
18*3d8817e4Smiod    You should have received a copy of the GNU General Public License
19*3d8817e4Smiod    along with this program; if not, write to the Free Software
20*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21*3d8817e4Smiod    02110-1301, USA.  */
22*3d8817e4Smiod 
23*3d8817e4Smiod /* This file implements a generic debugging format.  We may eventually
24*3d8817e4Smiod    have readers which convert different formats into this generic
25*3d8817e4Smiod    format, and writers which write it out.  The initial impetus for
26*3d8817e4Smiod    this was writing a converter from stabs to HP IEEE-695 debugging
27*3d8817e4Smiod    format.  */
28*3d8817e4Smiod 
29*3d8817e4Smiod #include <stdio.h>
30*3d8817e4Smiod #include <assert.h>
31*3d8817e4Smiod 
32*3d8817e4Smiod #include "bfd.h"
33*3d8817e4Smiod #include "bucomm.h"
34*3d8817e4Smiod #include "libiberty.h"
35*3d8817e4Smiod #include "debug.h"
36*3d8817e4Smiod 
37*3d8817e4Smiod /* Global information we keep for debugging.  A pointer to this
38*3d8817e4Smiod    structure is the debugging handle passed to all the routines.  */
39*3d8817e4Smiod 
40*3d8817e4Smiod struct debug_handle
41*3d8817e4Smiod {
42*3d8817e4Smiod   /* A linked list of compilation units.  */
43*3d8817e4Smiod   struct debug_unit *units;
44*3d8817e4Smiod   /* The current compilation unit.  */
45*3d8817e4Smiod   struct debug_unit *current_unit;
46*3d8817e4Smiod   /* The current source file.  */
47*3d8817e4Smiod   struct debug_file *current_file;
48*3d8817e4Smiod   /* The current function.  */
49*3d8817e4Smiod   struct debug_function *current_function;
50*3d8817e4Smiod   /* The current block.  */
51*3d8817e4Smiod   struct debug_block *current_block;
52*3d8817e4Smiod   /* The current line number information for the current unit.  */
53*3d8817e4Smiod   struct debug_lineno *current_lineno;
54*3d8817e4Smiod   /* Mark.  This is used by debug_write.  */
55*3d8817e4Smiod   unsigned int mark;
56*3d8817e4Smiod   /* A struct/class ID used by debug_write.  */
57*3d8817e4Smiod   unsigned int class_id;
58*3d8817e4Smiod   /* The base for class_id for this call to debug_write.  */
59*3d8817e4Smiod   unsigned int base_id;
60*3d8817e4Smiod   /* The current line number in debug_write.  */
61*3d8817e4Smiod   struct debug_lineno *current_write_lineno;
62*3d8817e4Smiod   unsigned int current_write_lineno_index;
63*3d8817e4Smiod   /* A list of classes which have assigned ID's during debug_write.
64*3d8817e4Smiod      This is linked through the next_id field of debug_class_type.  */
65*3d8817e4Smiod   struct debug_class_id *id_list;
66*3d8817e4Smiod   /* A list used to avoid recursion during debug_type_samep.  */
67*3d8817e4Smiod   struct debug_type_compare_list *compare_list;
68*3d8817e4Smiod };
69*3d8817e4Smiod 
70*3d8817e4Smiod /* Information we keep for a single compilation unit.  */
71*3d8817e4Smiod 
72*3d8817e4Smiod struct debug_unit
73*3d8817e4Smiod {
74*3d8817e4Smiod   /* The next compilation unit.  */
75*3d8817e4Smiod   struct debug_unit *next;
76*3d8817e4Smiod   /* A list of files included in this compilation unit.  The first
77*3d8817e4Smiod      file is always the main one, and that is where the main file name
78*3d8817e4Smiod      is stored.  */
79*3d8817e4Smiod   struct debug_file *files;
80*3d8817e4Smiod   /* Line number information for this compilation unit.  This is not
81*3d8817e4Smiod      stored by function, because assembler code may have line number
82*3d8817e4Smiod      information without function information.  */
83*3d8817e4Smiod   struct debug_lineno *linenos;
84*3d8817e4Smiod };
85*3d8817e4Smiod 
86*3d8817e4Smiod /* Information kept for a single source file.  */
87*3d8817e4Smiod 
88*3d8817e4Smiod struct debug_file
89*3d8817e4Smiod {
90*3d8817e4Smiod   /* The next source file in this compilation unit.  */
91*3d8817e4Smiod   struct debug_file *next;
92*3d8817e4Smiod   /* The name of the source file.  */
93*3d8817e4Smiod   const char *filename;
94*3d8817e4Smiod   /* Global functions, variables, types, etc.  */
95*3d8817e4Smiod   struct debug_namespace *globals;
96*3d8817e4Smiod };
97*3d8817e4Smiod 
98*3d8817e4Smiod /* A type.  */
99*3d8817e4Smiod 
100*3d8817e4Smiod struct debug_type
101*3d8817e4Smiod {
102*3d8817e4Smiod   /* Kind of type.  */
103*3d8817e4Smiod   enum debug_type_kind kind;
104*3d8817e4Smiod   /* Size of type (0 if not known).  */
105*3d8817e4Smiod   unsigned int size;
106*3d8817e4Smiod   /* Type which is a pointer to this type.  */
107*3d8817e4Smiod   debug_type pointer;
108*3d8817e4Smiod   /* Tagged union with additional information about the type.  */
109*3d8817e4Smiod   union
110*3d8817e4Smiod     {
111*3d8817e4Smiod       /* DEBUG_KIND_INDIRECT.  */
112*3d8817e4Smiod       struct debug_indirect_type *kindirect;
113*3d8817e4Smiod       /* DEBUG_KIND_INT.  */
114*3d8817e4Smiod       /* Whether the integer is unsigned.  */
115*3d8817e4Smiod       bfd_boolean kint;
116*3d8817e4Smiod       /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS,
117*3d8817e4Smiod          DEBUG_KIND_UNION_CLASS.  */
118*3d8817e4Smiod       struct debug_class_type *kclass;
119*3d8817e4Smiod       /* DEBUG_KIND_ENUM.  */
120*3d8817e4Smiod       struct debug_enum_type *kenum;
121*3d8817e4Smiod       /* DEBUG_KIND_POINTER.  */
122*3d8817e4Smiod       struct debug_type *kpointer;
123*3d8817e4Smiod       /* DEBUG_KIND_FUNCTION.  */
124*3d8817e4Smiod       struct debug_function_type *kfunction;
125*3d8817e4Smiod       /* DEBUG_KIND_REFERENCE.  */
126*3d8817e4Smiod       struct debug_type *kreference;
127*3d8817e4Smiod       /* DEBUG_KIND_RANGE.  */
128*3d8817e4Smiod       struct debug_range_type *krange;
129*3d8817e4Smiod       /* DEBUG_KIND_ARRAY.  */
130*3d8817e4Smiod       struct debug_array_type *karray;
131*3d8817e4Smiod       /* DEBUG_KIND_SET.  */
132*3d8817e4Smiod       struct debug_set_type *kset;
133*3d8817e4Smiod       /* DEBUG_KIND_OFFSET.  */
134*3d8817e4Smiod       struct debug_offset_type *koffset;
135*3d8817e4Smiod       /* DEBUG_KIND_METHOD.  */
136*3d8817e4Smiod       struct debug_method_type *kmethod;
137*3d8817e4Smiod       /* DEBUG_KIND_CONST.  */
138*3d8817e4Smiod       struct debug_type *kconst;
139*3d8817e4Smiod       /* DEBUG_KIND_VOLATILE.  */
140*3d8817e4Smiod       struct debug_type *kvolatile;
141*3d8817e4Smiod       /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED.  */
142*3d8817e4Smiod       struct debug_named_type *knamed;
143*3d8817e4Smiod     } u;
144*3d8817e4Smiod };
145*3d8817e4Smiod 
146*3d8817e4Smiod /* Information kept for an indirect type.  */
147*3d8817e4Smiod 
148*3d8817e4Smiod struct debug_indirect_type
149*3d8817e4Smiod {
150*3d8817e4Smiod   /* Slot where the final type will appear.  */
151*3d8817e4Smiod   debug_type *slot;
152*3d8817e4Smiod   /* Tag.  */
153*3d8817e4Smiod   const char *tag;
154*3d8817e4Smiod };
155*3d8817e4Smiod 
156*3d8817e4Smiod /* Information kept for a struct, union, or class.  */
157*3d8817e4Smiod 
158*3d8817e4Smiod struct debug_class_type
159*3d8817e4Smiod {
160*3d8817e4Smiod   /* NULL terminated array of fields.  */
161*3d8817e4Smiod   debug_field *fields;
162*3d8817e4Smiod   /* A mark field which indicates whether the struct has already been
163*3d8817e4Smiod      printed.  */
164*3d8817e4Smiod   unsigned int mark;
165*3d8817e4Smiod   /* This is used to uniquely identify unnamed structs when printing.  */
166*3d8817e4Smiod   unsigned int id;
167*3d8817e4Smiod   /* The remaining fields are only used for DEBUG_KIND_CLASS and
168*3d8817e4Smiod      DEBUG_KIND_UNION_CLASS.  */
169*3d8817e4Smiod   /* NULL terminated array of base classes.  */
170*3d8817e4Smiod   debug_baseclass *baseclasses;
171*3d8817e4Smiod   /* NULL terminated array of methods.  */
172*3d8817e4Smiod   debug_method *methods;
173*3d8817e4Smiod   /* The type of the class providing the virtual function table for
174*3d8817e4Smiod      this class.  This may point to the type itself.  */
175*3d8817e4Smiod   debug_type vptrbase;
176*3d8817e4Smiod };
177*3d8817e4Smiod 
178*3d8817e4Smiod /* Information kept for an enum.  */
179*3d8817e4Smiod 
180*3d8817e4Smiod struct debug_enum_type
181*3d8817e4Smiod {
182*3d8817e4Smiod   /* NULL terminated array of names.  */
183*3d8817e4Smiod   const char **names;
184*3d8817e4Smiod   /* Array of corresponding values.  */
185*3d8817e4Smiod   bfd_signed_vma *values;
186*3d8817e4Smiod };
187*3d8817e4Smiod 
188*3d8817e4Smiod /* Information kept for a function.  FIXME: We should be able to
189*3d8817e4Smiod    record the parameter types.  */
190*3d8817e4Smiod 
191*3d8817e4Smiod struct debug_function_type
192*3d8817e4Smiod {
193*3d8817e4Smiod   /* Return type.  */
194*3d8817e4Smiod   debug_type return_type;
195*3d8817e4Smiod   /* NULL terminated array of argument types.  */
196*3d8817e4Smiod   debug_type *arg_types;
197*3d8817e4Smiod   /* Whether the function takes a variable number of arguments.  */
198*3d8817e4Smiod   bfd_boolean varargs;
199*3d8817e4Smiod };
200*3d8817e4Smiod 
201*3d8817e4Smiod /* Information kept for a range.  */
202*3d8817e4Smiod 
203*3d8817e4Smiod struct debug_range_type
204*3d8817e4Smiod {
205*3d8817e4Smiod   /* Range base type.  */
206*3d8817e4Smiod   debug_type type;
207*3d8817e4Smiod   /* Lower bound.  */
208*3d8817e4Smiod   bfd_signed_vma lower;
209*3d8817e4Smiod   /* Upper bound.  */
210*3d8817e4Smiod   bfd_signed_vma upper;
211*3d8817e4Smiod };
212*3d8817e4Smiod 
213*3d8817e4Smiod /* Information kept for an array.  */
214*3d8817e4Smiod 
215*3d8817e4Smiod struct debug_array_type
216*3d8817e4Smiod {
217*3d8817e4Smiod   /* Element type.  */
218*3d8817e4Smiod   debug_type element_type;
219*3d8817e4Smiod   /* Range type.  */
220*3d8817e4Smiod   debug_type range_type;
221*3d8817e4Smiod   /* Lower bound.  */
222*3d8817e4Smiod   bfd_signed_vma lower;
223*3d8817e4Smiod   /* Upper bound.  */
224*3d8817e4Smiod   bfd_signed_vma upper;
225*3d8817e4Smiod   /* Whether this array is really a string.  */
226*3d8817e4Smiod   bfd_boolean stringp;
227*3d8817e4Smiod };
228*3d8817e4Smiod 
229*3d8817e4Smiod /* Information kept for a set.  */
230*3d8817e4Smiod 
231*3d8817e4Smiod struct debug_set_type
232*3d8817e4Smiod {
233*3d8817e4Smiod   /* Base type.  */
234*3d8817e4Smiod   debug_type type;
235*3d8817e4Smiod   /* Whether this set is really a bitstring.  */
236*3d8817e4Smiod   bfd_boolean bitstringp;
237*3d8817e4Smiod };
238*3d8817e4Smiod 
239*3d8817e4Smiod /* Information kept for an offset type (a based pointer).  */
240*3d8817e4Smiod 
241*3d8817e4Smiod struct debug_offset_type
242*3d8817e4Smiod {
243*3d8817e4Smiod   /* The type the pointer is an offset from.  */
244*3d8817e4Smiod   debug_type base_type;
245*3d8817e4Smiod   /* The type the pointer points to.  */
246*3d8817e4Smiod   debug_type target_type;
247*3d8817e4Smiod };
248*3d8817e4Smiod 
249*3d8817e4Smiod /* Information kept for a method type.  */
250*3d8817e4Smiod 
251*3d8817e4Smiod struct debug_method_type
252*3d8817e4Smiod {
253*3d8817e4Smiod   /* The return type.  */
254*3d8817e4Smiod   debug_type return_type;
255*3d8817e4Smiod   /* The object type which this method is for.  */
256*3d8817e4Smiod   debug_type domain_type;
257*3d8817e4Smiod   /* A NULL terminated array of argument types.  */
258*3d8817e4Smiod   debug_type *arg_types;
259*3d8817e4Smiod   /* Whether the method takes a variable number of arguments.  */
260*3d8817e4Smiod   bfd_boolean varargs;
261*3d8817e4Smiod };
262*3d8817e4Smiod 
263*3d8817e4Smiod /* Information kept for a named type.  */
264*3d8817e4Smiod 
265*3d8817e4Smiod struct debug_named_type
266*3d8817e4Smiod {
267*3d8817e4Smiod   /* Name.  */
268*3d8817e4Smiod   struct debug_name *name;
269*3d8817e4Smiod   /* Real type.  */
270*3d8817e4Smiod   debug_type type;
271*3d8817e4Smiod };
272*3d8817e4Smiod 
273*3d8817e4Smiod /* A field in a struct or union.  */
274*3d8817e4Smiod 
275*3d8817e4Smiod struct debug_field
276*3d8817e4Smiod {
277*3d8817e4Smiod   /* Name of the field.  */
278*3d8817e4Smiod   const char *name;
279*3d8817e4Smiod   /* Type of the field.  */
280*3d8817e4Smiod   struct debug_type *type;
281*3d8817e4Smiod   /* Visibility of the field.  */
282*3d8817e4Smiod   enum debug_visibility visibility;
283*3d8817e4Smiod   /* Whether this is a static member.  */
284*3d8817e4Smiod   bfd_boolean static_member;
285*3d8817e4Smiod   union
286*3d8817e4Smiod     {
287*3d8817e4Smiod       /* If static_member is false.  */
288*3d8817e4Smiod       struct
289*3d8817e4Smiod 	{
290*3d8817e4Smiod 	  /* Bit position of the field in the struct.  */
291*3d8817e4Smiod 	  unsigned int bitpos;
292*3d8817e4Smiod 	  /* Size of the field in bits.  */
293*3d8817e4Smiod 	  unsigned int bitsize;
294*3d8817e4Smiod 	} f;
295*3d8817e4Smiod       /* If static_member is true.  */
296*3d8817e4Smiod       struct
297*3d8817e4Smiod 	{
298*3d8817e4Smiod 	  const char *physname;
299*3d8817e4Smiod 	} s;
300*3d8817e4Smiod     } u;
301*3d8817e4Smiod };
302*3d8817e4Smiod 
303*3d8817e4Smiod /* A base class for an object.  */
304*3d8817e4Smiod 
305*3d8817e4Smiod struct debug_baseclass
306*3d8817e4Smiod {
307*3d8817e4Smiod   /* Type of the base class.  */
308*3d8817e4Smiod   struct debug_type *type;
309*3d8817e4Smiod   /* Bit position of the base class in the object.  */
310*3d8817e4Smiod   unsigned int bitpos;
311*3d8817e4Smiod   /* Whether the base class is virtual.  */
312*3d8817e4Smiod   bfd_boolean virtual;
313*3d8817e4Smiod   /* Visibility of the base class.  */
314*3d8817e4Smiod   enum debug_visibility visibility;
315*3d8817e4Smiod };
316*3d8817e4Smiod 
317*3d8817e4Smiod /* A method of an object.  */
318*3d8817e4Smiod 
319*3d8817e4Smiod struct debug_method
320*3d8817e4Smiod {
321*3d8817e4Smiod   /* The name of the method.  */
322*3d8817e4Smiod   const char *name;
323*3d8817e4Smiod   /* A NULL terminated array of different types of variants.  */
324*3d8817e4Smiod   struct debug_method_variant **variants;
325*3d8817e4Smiod };
326*3d8817e4Smiod 
327*3d8817e4Smiod /* The variants of a method function of an object.  These indicate
328*3d8817e4Smiod    which method to run.  */
329*3d8817e4Smiod 
330*3d8817e4Smiod struct debug_method_variant
331*3d8817e4Smiod {
332*3d8817e4Smiod   /* The physical name of the function.  */
333*3d8817e4Smiod   const char *physname;
334*3d8817e4Smiod   /* The type of the function.  */
335*3d8817e4Smiod   struct debug_type *type;
336*3d8817e4Smiod   /* The visibility of the function.  */
337*3d8817e4Smiod   enum debug_visibility visibility;
338*3d8817e4Smiod   /* Whether the function is const.  */
339*3d8817e4Smiod   bfd_boolean constp;
340*3d8817e4Smiod   /* Whether the function is volatile.  */
341*3d8817e4Smiod   bfd_boolean volatilep;
342*3d8817e4Smiod   /* The offset to the function in the virtual function table.  */
343*3d8817e4Smiod   bfd_vma voffset;
344*3d8817e4Smiod   /* If voffset is VOFFSET_STATIC_METHOD, this is a static method.  */
345*3d8817e4Smiod #define VOFFSET_STATIC_METHOD ((bfd_vma) -1)
346*3d8817e4Smiod   /* Context of a virtual method function.  */
347*3d8817e4Smiod   struct debug_type *context;
348*3d8817e4Smiod };
349*3d8817e4Smiod 
350*3d8817e4Smiod /* A variable.  This is the information we keep for a variable object.
351*3d8817e4Smiod    This has no name; a name is associated with a variable in a
352*3d8817e4Smiod    debug_name structure.  */
353*3d8817e4Smiod 
354*3d8817e4Smiod struct debug_variable
355*3d8817e4Smiod {
356*3d8817e4Smiod   /* Kind of variable.  */
357*3d8817e4Smiod   enum debug_var_kind kind;
358*3d8817e4Smiod   /* Type.  */
359*3d8817e4Smiod   debug_type type;
360*3d8817e4Smiod   /* Value.  The interpretation of the value depends upon kind.  */
361*3d8817e4Smiod   bfd_vma val;
362*3d8817e4Smiod };
363*3d8817e4Smiod 
364*3d8817e4Smiod /* A function.  This has no name; a name is associated with a function
365*3d8817e4Smiod    in a debug_name structure.  */
366*3d8817e4Smiod 
367*3d8817e4Smiod struct debug_function
368*3d8817e4Smiod {
369*3d8817e4Smiod   /* Return type.  */
370*3d8817e4Smiod   debug_type return_type;
371*3d8817e4Smiod   /* Parameter information.  */
372*3d8817e4Smiod   struct debug_parameter *parameters;
373*3d8817e4Smiod   /* Block information.  The first structure on the list is the main
374*3d8817e4Smiod      block of the function, and describes function local variables.  */
375*3d8817e4Smiod   struct debug_block *blocks;
376*3d8817e4Smiod };
377*3d8817e4Smiod 
378*3d8817e4Smiod /* A function parameter.  */
379*3d8817e4Smiod 
380*3d8817e4Smiod struct debug_parameter
381*3d8817e4Smiod {
382*3d8817e4Smiod   /* Next parameter.  */
383*3d8817e4Smiod   struct debug_parameter *next;
384*3d8817e4Smiod   /* Name.  */
385*3d8817e4Smiod   const char *name;
386*3d8817e4Smiod   /* Type.  */
387*3d8817e4Smiod   debug_type type;
388*3d8817e4Smiod   /* Kind.  */
389*3d8817e4Smiod   enum debug_parm_kind kind;
390*3d8817e4Smiod   /* Value (meaning depends upon kind).  */
391*3d8817e4Smiod   bfd_vma val;
392*3d8817e4Smiod };
393*3d8817e4Smiod 
394*3d8817e4Smiod /* A typed constant.  */
395*3d8817e4Smiod 
396*3d8817e4Smiod struct debug_typed_constant
397*3d8817e4Smiod {
398*3d8817e4Smiod   /* Type.  */
399*3d8817e4Smiod   debug_type type;
400*3d8817e4Smiod   /* Value.  FIXME: We may eventually need to support non-integral
401*3d8817e4Smiod      values.  */
402*3d8817e4Smiod   bfd_vma val;
403*3d8817e4Smiod };
404*3d8817e4Smiod 
405*3d8817e4Smiod /* Information about a block within a function.  */
406*3d8817e4Smiod 
407*3d8817e4Smiod struct debug_block
408*3d8817e4Smiod {
409*3d8817e4Smiod   /* Next block with the same parent.  */
410*3d8817e4Smiod   struct debug_block *next;
411*3d8817e4Smiod   /* Parent block.  */
412*3d8817e4Smiod   struct debug_block *parent;
413*3d8817e4Smiod   /* List of child blocks.  */
414*3d8817e4Smiod   struct debug_block *children;
415*3d8817e4Smiod   /* Start address of the block.  */
416*3d8817e4Smiod   bfd_vma start;
417*3d8817e4Smiod   /* End address of the block.  */
418*3d8817e4Smiod   bfd_vma end;
419*3d8817e4Smiod   /* Local variables.  */
420*3d8817e4Smiod   struct debug_namespace *locals;
421*3d8817e4Smiod };
422*3d8817e4Smiod 
423*3d8817e4Smiod /* Line number information we keep for a compilation unit.  FIXME:
424*3d8817e4Smiod    This structure is easy to create, but can be very space
425*3d8817e4Smiod    inefficient.  */
426*3d8817e4Smiod 
427*3d8817e4Smiod struct debug_lineno
428*3d8817e4Smiod {
429*3d8817e4Smiod   /* More line number information for this block.  */
430*3d8817e4Smiod   struct debug_lineno *next;
431*3d8817e4Smiod   /* Source file.  */
432*3d8817e4Smiod   struct debug_file *file;
433*3d8817e4Smiod   /* Line numbers, terminated by a -1 or the end of the array.  */
434*3d8817e4Smiod #define DEBUG_LINENO_COUNT 10
435*3d8817e4Smiod   unsigned long linenos[DEBUG_LINENO_COUNT];
436*3d8817e4Smiod   /* Addresses for the line numbers.  */
437*3d8817e4Smiod   bfd_vma addrs[DEBUG_LINENO_COUNT];
438*3d8817e4Smiod };
439*3d8817e4Smiod 
440*3d8817e4Smiod /* A namespace.  This is a mapping from names to objects.  FIXME: This
441*3d8817e4Smiod    should be implemented as a hash table.  */
442*3d8817e4Smiod 
443*3d8817e4Smiod struct debug_namespace
444*3d8817e4Smiod {
445*3d8817e4Smiod   /* List of items in this namespace.  */
446*3d8817e4Smiod   struct debug_name *list;
447*3d8817e4Smiod   /* Pointer to where the next item in this namespace should go.  */
448*3d8817e4Smiod   struct debug_name **tail;
449*3d8817e4Smiod };
450*3d8817e4Smiod 
451*3d8817e4Smiod /* Kinds of objects that appear in a namespace.  */
452*3d8817e4Smiod 
453*3d8817e4Smiod enum debug_object_kind
454*3d8817e4Smiod {
455*3d8817e4Smiod   /* A type.  */
456*3d8817e4Smiod   DEBUG_OBJECT_TYPE,
457*3d8817e4Smiod   /* A tagged type (really a different sort of namespace).  */
458*3d8817e4Smiod   DEBUG_OBJECT_TAG,
459*3d8817e4Smiod   /* A variable.  */
460*3d8817e4Smiod   DEBUG_OBJECT_VARIABLE,
461*3d8817e4Smiod   /* A function.  */
462*3d8817e4Smiod   DEBUG_OBJECT_FUNCTION,
463*3d8817e4Smiod   /* An integer constant.  */
464*3d8817e4Smiod   DEBUG_OBJECT_INT_CONSTANT,
465*3d8817e4Smiod   /* A floating point constant.  */
466*3d8817e4Smiod   DEBUG_OBJECT_FLOAT_CONSTANT,
467*3d8817e4Smiod   /* A typed constant.  */
468*3d8817e4Smiod   DEBUG_OBJECT_TYPED_CONSTANT
469*3d8817e4Smiod };
470*3d8817e4Smiod 
471*3d8817e4Smiod /* Linkage of an object that appears in a namespace.  */
472*3d8817e4Smiod 
473*3d8817e4Smiod enum debug_object_linkage
474*3d8817e4Smiod {
475*3d8817e4Smiod   /* Local variable.  */
476*3d8817e4Smiod   DEBUG_LINKAGE_AUTOMATIC,
477*3d8817e4Smiod   /* Static--either file static or function static, depending upon the
478*3d8817e4Smiod      namespace is.  */
479*3d8817e4Smiod   DEBUG_LINKAGE_STATIC,
480*3d8817e4Smiod   /* Global.  */
481*3d8817e4Smiod   DEBUG_LINKAGE_GLOBAL,
482*3d8817e4Smiod   /* No linkage.  */
483*3d8817e4Smiod   DEBUG_LINKAGE_NONE
484*3d8817e4Smiod };
485*3d8817e4Smiod 
486*3d8817e4Smiod /* A name in a namespace.  */
487*3d8817e4Smiod 
488*3d8817e4Smiod struct debug_name
489*3d8817e4Smiod {
490*3d8817e4Smiod   /* Next name in this namespace.  */
491*3d8817e4Smiod   struct debug_name *next;
492*3d8817e4Smiod   /* Name.  */
493*3d8817e4Smiod   const char *name;
494*3d8817e4Smiod   /* Mark.  This is used by debug_write.  */
495*3d8817e4Smiod   unsigned int mark;
496*3d8817e4Smiod   /* Kind of object.  */
497*3d8817e4Smiod   enum debug_object_kind kind;
498*3d8817e4Smiod   /* Linkage of object.  */
499*3d8817e4Smiod   enum debug_object_linkage linkage;
500*3d8817e4Smiod   /* Tagged union with additional information about the object.  */
501*3d8817e4Smiod   union
502*3d8817e4Smiod     {
503*3d8817e4Smiod       /* DEBUG_OBJECT_TYPE.  */
504*3d8817e4Smiod       struct debug_type *type;
505*3d8817e4Smiod       /* DEBUG_OBJECT_TAG.  */
506*3d8817e4Smiod       struct debug_type *tag;
507*3d8817e4Smiod       /* DEBUG_OBJECT_VARIABLE.  */
508*3d8817e4Smiod       struct debug_variable *variable;
509*3d8817e4Smiod       /* DEBUG_OBJECT_FUNCTION.  */
510*3d8817e4Smiod       struct debug_function *function;
511*3d8817e4Smiod       /* DEBUG_OBJECT_INT_CONSTANT.  */
512*3d8817e4Smiod       bfd_vma int_constant;
513*3d8817e4Smiod       /* DEBUG_OBJECT_FLOAT_CONSTANT.  */
514*3d8817e4Smiod       double float_constant;
515*3d8817e4Smiod       /* DEBUG_OBJECT_TYPED_CONSTANT.  */
516*3d8817e4Smiod       struct debug_typed_constant *typed_constant;
517*3d8817e4Smiod     } u;
518*3d8817e4Smiod };
519*3d8817e4Smiod 
520*3d8817e4Smiod /* During debug_write, a linked list of these structures is used to
521*3d8817e4Smiod    keep track of ID numbers that have been assigned to classes.  */
522*3d8817e4Smiod 
523*3d8817e4Smiod struct debug_class_id
524*3d8817e4Smiod {
525*3d8817e4Smiod   /* Next ID number.  */
526*3d8817e4Smiod   struct debug_class_id *next;
527*3d8817e4Smiod   /* The type with the ID.  */
528*3d8817e4Smiod   struct debug_type *type;
529*3d8817e4Smiod   /* The tag; NULL if no tag.  */
530*3d8817e4Smiod   const char *tag;
531*3d8817e4Smiod };
532*3d8817e4Smiod 
533*3d8817e4Smiod /* During debug_type_samep, a linked list of these structures is kept
534*3d8817e4Smiod    on the stack to avoid infinite recursion.  */
535*3d8817e4Smiod 
536*3d8817e4Smiod struct debug_type_compare_list
537*3d8817e4Smiod {
538*3d8817e4Smiod   /* Next type on list.  */
539*3d8817e4Smiod   struct debug_type_compare_list *next;
540*3d8817e4Smiod   /* The types we are comparing.  */
541*3d8817e4Smiod   struct debug_type *t1;
542*3d8817e4Smiod   struct debug_type *t2;
543*3d8817e4Smiod };
544*3d8817e4Smiod 
545*3d8817e4Smiod /* During debug_get_real_type, a linked list of these structures is
546*3d8817e4Smiod    kept on the stack to avoid infinite recursion.  */
547*3d8817e4Smiod 
548*3d8817e4Smiod struct debug_type_real_list
549*3d8817e4Smiod {
550*3d8817e4Smiod   /* Next type on list.  */
551*3d8817e4Smiod   struct debug_type_real_list *next;
552*3d8817e4Smiod   /* The type we are checking.  */
553*3d8817e4Smiod   struct debug_type *t;
554*3d8817e4Smiod };
555*3d8817e4Smiod 
556*3d8817e4Smiod /* Local functions.  */
557*3d8817e4Smiod 
558*3d8817e4Smiod static void debug_error (const char *);
559*3d8817e4Smiod static struct debug_name *debug_add_to_namespace
560*3d8817e4Smiod   (struct debug_handle *, struct debug_namespace **, const char *,
561*3d8817e4Smiod    enum debug_object_kind, enum debug_object_linkage);
562*3d8817e4Smiod static struct debug_name *debug_add_to_current_namespace
563*3d8817e4Smiod   (struct debug_handle *, const char *, enum debug_object_kind,
564*3d8817e4Smiod    enum debug_object_linkage);
565*3d8817e4Smiod static struct debug_type *debug_make_type
566*3d8817e4Smiod   (struct debug_handle *, enum debug_type_kind, unsigned int);
567*3d8817e4Smiod static struct debug_type *debug_get_real_type
568*3d8817e4Smiod   (void *, debug_type, struct debug_type_real_list *);
569*3d8817e4Smiod static bfd_boolean debug_write_name
570*3d8817e4Smiod   (struct debug_handle *, const struct debug_write_fns *, void *,
571*3d8817e4Smiod    struct debug_name *);
572*3d8817e4Smiod static bfd_boolean debug_write_type
573*3d8817e4Smiod   (struct debug_handle *, const struct debug_write_fns *, void *,
574*3d8817e4Smiod    struct debug_type *, struct debug_name *);
575*3d8817e4Smiod static bfd_boolean debug_write_class_type
576*3d8817e4Smiod   (struct debug_handle *, const struct debug_write_fns *, void *,
577*3d8817e4Smiod    struct debug_type *, const char *);
578*3d8817e4Smiod static bfd_boolean debug_write_function
579*3d8817e4Smiod   (struct debug_handle *, const struct debug_write_fns *, void *,
580*3d8817e4Smiod    const char *, enum debug_object_linkage, struct debug_function *);
581*3d8817e4Smiod static bfd_boolean debug_write_block
582*3d8817e4Smiod   (struct debug_handle *, const struct debug_write_fns *, void *,
583*3d8817e4Smiod    struct debug_block *);
584*3d8817e4Smiod static bfd_boolean debug_write_linenos
585*3d8817e4Smiod   (struct debug_handle *, const struct debug_write_fns *, void *, bfd_vma);
586*3d8817e4Smiod static bfd_boolean debug_set_class_id
587*3d8817e4Smiod   (struct debug_handle *, const char *, struct debug_type *);
588*3d8817e4Smiod static bfd_boolean debug_type_samep
589*3d8817e4Smiod   (struct debug_handle *, struct debug_type *, struct debug_type *);
590*3d8817e4Smiod static bfd_boolean debug_class_type_samep
591*3d8817e4Smiod   (struct debug_handle *, struct debug_type *, struct debug_type *);
592*3d8817e4Smiod 
593*3d8817e4Smiod /* Issue an error message.  */
594*3d8817e4Smiod 
595*3d8817e4Smiod static void
debug_error(const char * message)596*3d8817e4Smiod debug_error (const char *message)
597*3d8817e4Smiod {
598*3d8817e4Smiod   fprintf (stderr, "%s\n", message);
599*3d8817e4Smiod }
600*3d8817e4Smiod 
601*3d8817e4Smiod /* Add an object to a namespace.  */
602*3d8817e4Smiod 
603*3d8817e4Smiod static struct debug_name *
debug_add_to_namespace(struct debug_handle * info ATTRIBUTE_UNUSED,struct debug_namespace ** nsp,const char * name,enum debug_object_kind kind,enum debug_object_linkage linkage)604*3d8817e4Smiod debug_add_to_namespace (struct debug_handle *info ATTRIBUTE_UNUSED,
605*3d8817e4Smiod 			struct debug_namespace **nsp, const char *name,
606*3d8817e4Smiod 			enum debug_object_kind kind,
607*3d8817e4Smiod 			enum debug_object_linkage linkage)
608*3d8817e4Smiod {
609*3d8817e4Smiod   struct debug_name *n;
610*3d8817e4Smiod   struct debug_namespace *ns;
611*3d8817e4Smiod 
612*3d8817e4Smiod   n = (struct debug_name *) xmalloc (sizeof *n);
613*3d8817e4Smiod   memset (n, 0, sizeof *n);
614*3d8817e4Smiod 
615*3d8817e4Smiod   n->name = name;
616*3d8817e4Smiod   n->kind = kind;
617*3d8817e4Smiod   n->linkage = linkage;
618*3d8817e4Smiod 
619*3d8817e4Smiod   ns = *nsp;
620*3d8817e4Smiod   if (ns == NULL)
621*3d8817e4Smiod     {
622*3d8817e4Smiod       ns = (struct debug_namespace *) xmalloc (sizeof *ns);
623*3d8817e4Smiod       memset (ns, 0, sizeof *ns);
624*3d8817e4Smiod 
625*3d8817e4Smiod       ns->tail = &ns->list;
626*3d8817e4Smiod 
627*3d8817e4Smiod       *nsp = ns;
628*3d8817e4Smiod     }
629*3d8817e4Smiod 
630*3d8817e4Smiod   *ns->tail = n;
631*3d8817e4Smiod   ns->tail = &n->next;
632*3d8817e4Smiod 
633*3d8817e4Smiod   return n;
634*3d8817e4Smiod }
635*3d8817e4Smiod 
636*3d8817e4Smiod /* Add an object to the current namespace.  */
637*3d8817e4Smiod 
638*3d8817e4Smiod static struct debug_name *
debug_add_to_current_namespace(struct debug_handle * info,const char * name,enum debug_object_kind kind,enum debug_object_linkage linkage)639*3d8817e4Smiod debug_add_to_current_namespace (struct debug_handle *info, const char *name,
640*3d8817e4Smiod 				enum debug_object_kind kind,
641*3d8817e4Smiod 				enum debug_object_linkage linkage)
642*3d8817e4Smiod {
643*3d8817e4Smiod   struct debug_namespace **nsp;
644*3d8817e4Smiod 
645*3d8817e4Smiod   if (info->current_unit == NULL
646*3d8817e4Smiod       || info->current_file == NULL)
647*3d8817e4Smiod     {
648*3d8817e4Smiod       debug_error (_("debug_add_to_current_namespace: no current file"));
649*3d8817e4Smiod       return NULL;
650*3d8817e4Smiod     }
651*3d8817e4Smiod 
652*3d8817e4Smiod   if (info->current_block != NULL)
653*3d8817e4Smiod     nsp = &info->current_block->locals;
654*3d8817e4Smiod   else
655*3d8817e4Smiod     nsp = &info->current_file->globals;
656*3d8817e4Smiod 
657*3d8817e4Smiod   return debug_add_to_namespace (info, nsp, name, kind, linkage);
658*3d8817e4Smiod }
659*3d8817e4Smiod 
660*3d8817e4Smiod /* Return a handle for debugging information.  */
661*3d8817e4Smiod 
662*3d8817e4Smiod void *
debug_init(void)663*3d8817e4Smiod debug_init (void)
664*3d8817e4Smiod {
665*3d8817e4Smiod   struct debug_handle *ret;
666*3d8817e4Smiod 
667*3d8817e4Smiod   ret = (struct debug_handle *) xmalloc (sizeof *ret);
668*3d8817e4Smiod   memset (ret, 0, sizeof *ret);
669*3d8817e4Smiod   return (void *) ret;
670*3d8817e4Smiod }
671*3d8817e4Smiod 
672*3d8817e4Smiod /* Set the source filename.  This implicitly starts a new compilation
673*3d8817e4Smiod    unit.  */
674*3d8817e4Smiod 
675*3d8817e4Smiod bfd_boolean
debug_set_filename(void * handle,const char * name)676*3d8817e4Smiod debug_set_filename (void *handle, const char *name)
677*3d8817e4Smiod {
678*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
679*3d8817e4Smiod   struct debug_file *nfile;
680*3d8817e4Smiod   struct debug_unit *nunit;
681*3d8817e4Smiod 
682*3d8817e4Smiod   if (name == NULL)
683*3d8817e4Smiod     name = "";
684*3d8817e4Smiod 
685*3d8817e4Smiod   nfile = (struct debug_file *) xmalloc (sizeof *nfile);
686*3d8817e4Smiod   memset (nfile, 0, sizeof *nfile);
687*3d8817e4Smiod 
688*3d8817e4Smiod   nfile->filename = name;
689*3d8817e4Smiod 
690*3d8817e4Smiod   nunit = (struct debug_unit *) xmalloc (sizeof *nunit);
691*3d8817e4Smiod   memset (nunit, 0, sizeof *nunit);
692*3d8817e4Smiod 
693*3d8817e4Smiod   nunit->files = nfile;
694*3d8817e4Smiod   info->current_file = nfile;
695*3d8817e4Smiod 
696*3d8817e4Smiod   if (info->current_unit != NULL)
697*3d8817e4Smiod     info->current_unit->next = nunit;
698*3d8817e4Smiod   else
699*3d8817e4Smiod     {
700*3d8817e4Smiod       assert (info->units == NULL);
701*3d8817e4Smiod       info->units = nunit;
702*3d8817e4Smiod     }
703*3d8817e4Smiod 
704*3d8817e4Smiod   info->current_unit = nunit;
705*3d8817e4Smiod 
706*3d8817e4Smiod   info->current_function = NULL;
707*3d8817e4Smiod   info->current_block = NULL;
708*3d8817e4Smiod   info->current_lineno = NULL;
709*3d8817e4Smiod 
710*3d8817e4Smiod   return TRUE;
711*3d8817e4Smiod }
712*3d8817e4Smiod 
713*3d8817e4Smiod /* Change source files to the given file name.  This is used for
714*3d8817e4Smiod    include files in a single compilation unit.  */
715*3d8817e4Smiod 
716*3d8817e4Smiod bfd_boolean
debug_start_source(void * handle,const char * name)717*3d8817e4Smiod debug_start_source (void *handle, const char *name)
718*3d8817e4Smiod {
719*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
720*3d8817e4Smiod   struct debug_file *f, **pf;
721*3d8817e4Smiod 
722*3d8817e4Smiod   if (name == NULL)
723*3d8817e4Smiod     name = "";
724*3d8817e4Smiod 
725*3d8817e4Smiod   if (info->current_unit == NULL)
726*3d8817e4Smiod     {
727*3d8817e4Smiod       debug_error (_("debug_start_source: no debug_set_filename call"));
728*3d8817e4Smiod       return FALSE;
729*3d8817e4Smiod     }
730*3d8817e4Smiod 
731*3d8817e4Smiod   for (f = info->current_unit->files; f != NULL; f = f->next)
732*3d8817e4Smiod     {
733*3d8817e4Smiod       if (f->filename[0] == name[0]
734*3d8817e4Smiod 	  && f->filename[1] == name[1]
735*3d8817e4Smiod 	  && strcmp (f->filename, name) == 0)
736*3d8817e4Smiod 	{
737*3d8817e4Smiod 	  info->current_file = f;
738*3d8817e4Smiod 	  return TRUE;
739*3d8817e4Smiod 	}
740*3d8817e4Smiod     }
741*3d8817e4Smiod 
742*3d8817e4Smiod   f = (struct debug_file *) xmalloc (sizeof *f);
743*3d8817e4Smiod   memset (f, 0, sizeof *f);
744*3d8817e4Smiod 
745*3d8817e4Smiod   f->filename = name;
746*3d8817e4Smiod 
747*3d8817e4Smiod   for (pf = &info->current_file->next;
748*3d8817e4Smiod        *pf != NULL;
749*3d8817e4Smiod        pf = &(*pf)->next)
750*3d8817e4Smiod     ;
751*3d8817e4Smiod   *pf = f;
752*3d8817e4Smiod 
753*3d8817e4Smiod   info->current_file = f;
754*3d8817e4Smiod 
755*3d8817e4Smiod   return TRUE;
756*3d8817e4Smiod }
757*3d8817e4Smiod 
758*3d8817e4Smiod /* Record a function definition.  This implicitly starts a function
759*3d8817e4Smiod    block.  The debug_type argument is the type of the return value.
760*3d8817e4Smiod    The boolean indicates whether the function is globally visible.
761*3d8817e4Smiod    The bfd_vma is the address of the start of the function.  Currently
762*3d8817e4Smiod    the parameter types are specified by calls to
763*3d8817e4Smiod    debug_record_parameter.  FIXME: There is no way to specify nested
764*3d8817e4Smiod    functions.  */
765*3d8817e4Smiod 
766*3d8817e4Smiod bfd_boolean
debug_record_function(void * handle,const char * name,debug_type return_type,bfd_boolean global,bfd_vma addr)767*3d8817e4Smiod debug_record_function (void *handle, const char *name,
768*3d8817e4Smiod 		       debug_type return_type, bfd_boolean global,
769*3d8817e4Smiod 		       bfd_vma addr)
770*3d8817e4Smiod {
771*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
772*3d8817e4Smiod   struct debug_function *f;
773*3d8817e4Smiod   struct debug_block *b;
774*3d8817e4Smiod   struct debug_name *n;
775*3d8817e4Smiod 
776*3d8817e4Smiod   if (name == NULL)
777*3d8817e4Smiod     name = "";
778*3d8817e4Smiod   if (return_type == NULL)
779*3d8817e4Smiod     return FALSE;
780*3d8817e4Smiod 
781*3d8817e4Smiod   if (info->current_unit == NULL)
782*3d8817e4Smiod     {
783*3d8817e4Smiod       debug_error (_("debug_record_function: no debug_set_filename call"));
784*3d8817e4Smiod       return FALSE;
785*3d8817e4Smiod     }
786*3d8817e4Smiod 
787*3d8817e4Smiod   f = (struct debug_function *) xmalloc (sizeof *f);
788*3d8817e4Smiod   memset (f, 0, sizeof *f);
789*3d8817e4Smiod 
790*3d8817e4Smiod   f->return_type = return_type;
791*3d8817e4Smiod 
792*3d8817e4Smiod   b = (struct debug_block *) xmalloc (sizeof *b);
793*3d8817e4Smiod   memset (b, 0, sizeof *b);
794*3d8817e4Smiod 
795*3d8817e4Smiod   b->start = addr;
796*3d8817e4Smiod   b->end = (bfd_vma) -1;
797*3d8817e4Smiod 
798*3d8817e4Smiod   f->blocks = b;
799*3d8817e4Smiod 
800*3d8817e4Smiod   info->current_function = f;
801*3d8817e4Smiod   info->current_block = b;
802*3d8817e4Smiod 
803*3d8817e4Smiod   /* FIXME: If we could handle nested functions, this would be the
804*3d8817e4Smiod      place: we would want to use a different namespace.  */
805*3d8817e4Smiod   n = debug_add_to_namespace (info,
806*3d8817e4Smiod 			      &info->current_file->globals,
807*3d8817e4Smiod 			      name,
808*3d8817e4Smiod 			      DEBUG_OBJECT_FUNCTION,
809*3d8817e4Smiod 			      (global
810*3d8817e4Smiod 			       ? DEBUG_LINKAGE_GLOBAL
811*3d8817e4Smiod 			       : DEBUG_LINKAGE_STATIC));
812*3d8817e4Smiod   if (n == NULL)
813*3d8817e4Smiod     return FALSE;
814*3d8817e4Smiod 
815*3d8817e4Smiod   n->u.function = f;
816*3d8817e4Smiod 
817*3d8817e4Smiod   return TRUE;
818*3d8817e4Smiod }
819*3d8817e4Smiod 
820*3d8817e4Smiod /* Record a parameter for the current function.  */
821*3d8817e4Smiod 
822*3d8817e4Smiod bfd_boolean
debug_record_parameter(void * handle,const char * name,debug_type type,enum debug_parm_kind kind,bfd_vma val)823*3d8817e4Smiod debug_record_parameter (void *handle, const char *name, debug_type type,
824*3d8817e4Smiod 			enum debug_parm_kind kind, bfd_vma val)
825*3d8817e4Smiod {
826*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
827*3d8817e4Smiod   struct debug_parameter *p, **pp;
828*3d8817e4Smiod 
829*3d8817e4Smiod   if (name == NULL || type == NULL)
830*3d8817e4Smiod     return FALSE;
831*3d8817e4Smiod 
832*3d8817e4Smiod   if (info->current_unit == NULL
833*3d8817e4Smiod       || info->current_function == NULL)
834*3d8817e4Smiod     {
835*3d8817e4Smiod       debug_error (_("debug_record_parameter: no current function"));
836*3d8817e4Smiod       return FALSE;
837*3d8817e4Smiod     }
838*3d8817e4Smiod 
839*3d8817e4Smiod   p = (struct debug_parameter *) xmalloc (sizeof *p);
840*3d8817e4Smiod   memset (p, 0, sizeof *p);
841*3d8817e4Smiod 
842*3d8817e4Smiod   p->name = name;
843*3d8817e4Smiod   p->type = type;
844*3d8817e4Smiod   p->kind = kind;
845*3d8817e4Smiod   p->val = val;
846*3d8817e4Smiod 
847*3d8817e4Smiod   for (pp = &info->current_function->parameters;
848*3d8817e4Smiod        *pp != NULL;
849*3d8817e4Smiod        pp = &(*pp)->next)
850*3d8817e4Smiod     ;
851*3d8817e4Smiod   *pp = p;
852*3d8817e4Smiod 
853*3d8817e4Smiod   return TRUE;
854*3d8817e4Smiod }
855*3d8817e4Smiod 
856*3d8817e4Smiod /* End a function.  FIXME: This should handle function nesting.  */
857*3d8817e4Smiod 
858*3d8817e4Smiod bfd_boolean
debug_end_function(void * handle,bfd_vma addr)859*3d8817e4Smiod debug_end_function (void *handle, bfd_vma addr)
860*3d8817e4Smiod {
861*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
862*3d8817e4Smiod 
863*3d8817e4Smiod   if (info->current_unit == NULL
864*3d8817e4Smiod       || info->current_block == NULL
865*3d8817e4Smiod       || info->current_function == NULL)
866*3d8817e4Smiod     {
867*3d8817e4Smiod       debug_error (_("debug_end_function: no current function"));
868*3d8817e4Smiod       return FALSE;
869*3d8817e4Smiod     }
870*3d8817e4Smiod 
871*3d8817e4Smiod   if (info->current_block->parent != NULL)
872*3d8817e4Smiod     {
873*3d8817e4Smiod       debug_error (_("debug_end_function: some blocks were not closed"));
874*3d8817e4Smiod       return FALSE;
875*3d8817e4Smiod     }
876*3d8817e4Smiod 
877*3d8817e4Smiod   info->current_block->end = addr;
878*3d8817e4Smiod 
879*3d8817e4Smiod   info->current_function = NULL;
880*3d8817e4Smiod   info->current_block = NULL;
881*3d8817e4Smiod 
882*3d8817e4Smiod   return TRUE;
883*3d8817e4Smiod }
884*3d8817e4Smiod 
885*3d8817e4Smiod /* Start a block in a function.  All local information will be
886*3d8817e4Smiod    recorded in this block, until the matching call to debug_end_block.
887*3d8817e4Smiod    debug_start_block and debug_end_block may be nested.  The bfd_vma
888*3d8817e4Smiod    argument is the address at which this block starts.  */
889*3d8817e4Smiod 
890*3d8817e4Smiod bfd_boolean
debug_start_block(void * handle,bfd_vma addr)891*3d8817e4Smiod debug_start_block (void *handle, bfd_vma addr)
892*3d8817e4Smiod {
893*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
894*3d8817e4Smiod   struct debug_block *b, **pb;
895*3d8817e4Smiod 
896*3d8817e4Smiod   /* We must always have a current block: debug_record_function sets
897*3d8817e4Smiod      one up.  */
898*3d8817e4Smiod   if (info->current_unit == NULL
899*3d8817e4Smiod       || info->current_block == NULL)
900*3d8817e4Smiod     {
901*3d8817e4Smiod       debug_error (_("debug_start_block: no current block"));
902*3d8817e4Smiod       return FALSE;
903*3d8817e4Smiod     }
904*3d8817e4Smiod 
905*3d8817e4Smiod   b = (struct debug_block *) xmalloc (sizeof *b);
906*3d8817e4Smiod   memset (b, 0, sizeof *b);
907*3d8817e4Smiod 
908*3d8817e4Smiod   b->parent = info->current_block;
909*3d8817e4Smiod   b->start = addr;
910*3d8817e4Smiod   b->end = (bfd_vma) -1;
911*3d8817e4Smiod 
912*3d8817e4Smiod   /* This new block is a child of the current block.  */
913*3d8817e4Smiod   for (pb = &info->current_block->children;
914*3d8817e4Smiod        *pb != NULL;
915*3d8817e4Smiod        pb = &(*pb)->next)
916*3d8817e4Smiod     ;
917*3d8817e4Smiod   *pb = b;
918*3d8817e4Smiod 
919*3d8817e4Smiod   info->current_block = b;
920*3d8817e4Smiod 
921*3d8817e4Smiod   return TRUE;
922*3d8817e4Smiod }
923*3d8817e4Smiod 
924*3d8817e4Smiod /* Finish a block in a function.  This matches the call to
925*3d8817e4Smiod    debug_start_block.  The argument is the address at which this block
926*3d8817e4Smiod    ends.  */
927*3d8817e4Smiod 
928*3d8817e4Smiod bfd_boolean
debug_end_block(void * handle,bfd_vma addr)929*3d8817e4Smiod debug_end_block (void *handle, bfd_vma addr)
930*3d8817e4Smiod {
931*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
932*3d8817e4Smiod   struct debug_block *parent;
933*3d8817e4Smiod 
934*3d8817e4Smiod   if (info->current_unit == NULL
935*3d8817e4Smiod       || info->current_block == NULL)
936*3d8817e4Smiod     {
937*3d8817e4Smiod       debug_error (_("debug_end_block: no current block"));
938*3d8817e4Smiod       return FALSE;
939*3d8817e4Smiod     }
940*3d8817e4Smiod 
941*3d8817e4Smiod   parent = info->current_block->parent;
942*3d8817e4Smiod   if (parent == NULL)
943*3d8817e4Smiod     {
944*3d8817e4Smiod       debug_error (_("debug_end_block: attempt to close top level block"));
945*3d8817e4Smiod       return FALSE;
946*3d8817e4Smiod     }
947*3d8817e4Smiod 
948*3d8817e4Smiod   info->current_block->end = addr;
949*3d8817e4Smiod 
950*3d8817e4Smiod   info->current_block = parent;
951*3d8817e4Smiod 
952*3d8817e4Smiod   return TRUE;
953*3d8817e4Smiod }
954*3d8817e4Smiod 
955*3d8817e4Smiod /* Associate a line number in the current source file and function
956*3d8817e4Smiod    with a given address.  */
957*3d8817e4Smiod 
958*3d8817e4Smiod bfd_boolean
debug_record_line(void * handle,unsigned long lineno,bfd_vma addr)959*3d8817e4Smiod debug_record_line (void *handle, unsigned long lineno, bfd_vma addr)
960*3d8817e4Smiod {
961*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
962*3d8817e4Smiod   struct debug_lineno *l;
963*3d8817e4Smiod   unsigned int i;
964*3d8817e4Smiod 
965*3d8817e4Smiod   if (info->current_unit == NULL)
966*3d8817e4Smiod     {
967*3d8817e4Smiod       debug_error (_("debug_record_line: no current unit"));
968*3d8817e4Smiod       return FALSE;
969*3d8817e4Smiod     }
970*3d8817e4Smiod 
971*3d8817e4Smiod   l = info->current_lineno;
972*3d8817e4Smiod   if (l != NULL && l->file == info->current_file)
973*3d8817e4Smiod     {
974*3d8817e4Smiod       for (i = 0; i < DEBUG_LINENO_COUNT; i++)
975*3d8817e4Smiod 	{
976*3d8817e4Smiod 	  if (l->linenos[i] == (unsigned long) -1)
977*3d8817e4Smiod 	    {
978*3d8817e4Smiod 	      l->linenos[i] = lineno;
979*3d8817e4Smiod 	      l->addrs[i] = addr;
980*3d8817e4Smiod 	      return TRUE;
981*3d8817e4Smiod 	    }
982*3d8817e4Smiod 	}
983*3d8817e4Smiod     }
984*3d8817e4Smiod 
985*3d8817e4Smiod   /* If we get here, then either 1) there is no current_lineno
986*3d8817e4Smiod      structure, which means this is the first line number in this
987*3d8817e4Smiod      compilation unit, 2) the current_lineno structure is for a
988*3d8817e4Smiod      different file, or 3) the current_lineno structure is full.
989*3d8817e4Smiod      Regardless, we want to allocate a new debug_lineno structure, put
990*3d8817e4Smiod      it in the right place, and make it the new current_lineno
991*3d8817e4Smiod      structure.  */
992*3d8817e4Smiod 
993*3d8817e4Smiod   l = (struct debug_lineno *) xmalloc (sizeof *l);
994*3d8817e4Smiod   memset (l, 0, sizeof *l);
995*3d8817e4Smiod 
996*3d8817e4Smiod   l->file = info->current_file;
997*3d8817e4Smiod   l->linenos[0] = lineno;
998*3d8817e4Smiod   l->addrs[0] = addr;
999*3d8817e4Smiod   for (i = 1; i < DEBUG_LINENO_COUNT; i++)
1000*3d8817e4Smiod     l->linenos[i] = (unsigned long) -1;
1001*3d8817e4Smiod 
1002*3d8817e4Smiod   if (info->current_lineno != NULL)
1003*3d8817e4Smiod     info->current_lineno->next = l;
1004*3d8817e4Smiod   else
1005*3d8817e4Smiod     info->current_unit->linenos = l;
1006*3d8817e4Smiod 
1007*3d8817e4Smiod   info->current_lineno = l;
1008*3d8817e4Smiod 
1009*3d8817e4Smiod   return TRUE;
1010*3d8817e4Smiod }
1011*3d8817e4Smiod 
1012*3d8817e4Smiod /* Start a named common block.  This is a block of variables that may
1013*3d8817e4Smiod    move in memory.  */
1014*3d8817e4Smiod 
1015*3d8817e4Smiod bfd_boolean
debug_start_common_block(void * handle ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED)1016*3d8817e4Smiod debug_start_common_block (void *handle ATTRIBUTE_UNUSED,
1017*3d8817e4Smiod 			  const char *name ATTRIBUTE_UNUSED)
1018*3d8817e4Smiod {
1019*3d8817e4Smiod   /* FIXME */
1020*3d8817e4Smiod   debug_error (_("debug_start_common_block: not implemented"));
1021*3d8817e4Smiod   return FALSE;
1022*3d8817e4Smiod }
1023*3d8817e4Smiod 
1024*3d8817e4Smiod /* End a named common block.  */
1025*3d8817e4Smiod 
1026*3d8817e4Smiod bfd_boolean
debug_end_common_block(void * handle ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED)1027*3d8817e4Smiod debug_end_common_block (void *handle ATTRIBUTE_UNUSED,
1028*3d8817e4Smiod 			const char *name ATTRIBUTE_UNUSED)
1029*3d8817e4Smiod {
1030*3d8817e4Smiod   /* FIXME */
1031*3d8817e4Smiod   debug_error (_("debug_end_common_block: not implemented"));
1032*3d8817e4Smiod   return FALSE;
1033*3d8817e4Smiod }
1034*3d8817e4Smiod 
1035*3d8817e4Smiod /* Record a named integer constant.  */
1036*3d8817e4Smiod 
1037*3d8817e4Smiod bfd_boolean
debug_record_int_const(void * handle,const char * name,bfd_vma val)1038*3d8817e4Smiod debug_record_int_const (void *handle, const char *name, bfd_vma val)
1039*3d8817e4Smiod {
1040*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1041*3d8817e4Smiod   struct debug_name *n;
1042*3d8817e4Smiod 
1043*3d8817e4Smiod   if (name == NULL)
1044*3d8817e4Smiod     return FALSE;
1045*3d8817e4Smiod 
1046*3d8817e4Smiod   n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT,
1047*3d8817e4Smiod 				      DEBUG_LINKAGE_NONE);
1048*3d8817e4Smiod   if (n == NULL)
1049*3d8817e4Smiod     return FALSE;
1050*3d8817e4Smiod 
1051*3d8817e4Smiod   n->u.int_constant = val;
1052*3d8817e4Smiod 
1053*3d8817e4Smiod   return TRUE;
1054*3d8817e4Smiod }
1055*3d8817e4Smiod 
1056*3d8817e4Smiod /* Record a named floating point constant.  */
1057*3d8817e4Smiod 
1058*3d8817e4Smiod bfd_boolean
debug_record_float_const(void * handle,const char * name,double val)1059*3d8817e4Smiod debug_record_float_const (void *handle, const char *name, double val)
1060*3d8817e4Smiod {
1061*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1062*3d8817e4Smiod   struct debug_name *n;
1063*3d8817e4Smiod 
1064*3d8817e4Smiod   if (name == NULL)
1065*3d8817e4Smiod     return FALSE;
1066*3d8817e4Smiod 
1067*3d8817e4Smiod   n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT,
1068*3d8817e4Smiod 				      DEBUG_LINKAGE_NONE);
1069*3d8817e4Smiod   if (n == NULL)
1070*3d8817e4Smiod     return FALSE;
1071*3d8817e4Smiod 
1072*3d8817e4Smiod   n->u.float_constant = val;
1073*3d8817e4Smiod 
1074*3d8817e4Smiod   return TRUE;
1075*3d8817e4Smiod }
1076*3d8817e4Smiod 
1077*3d8817e4Smiod /* Record a typed constant with an integral value.  */
1078*3d8817e4Smiod 
1079*3d8817e4Smiod bfd_boolean
debug_record_typed_const(void * handle,const char * name,debug_type type,bfd_vma val)1080*3d8817e4Smiod debug_record_typed_const (void *handle, const char *name, debug_type type,
1081*3d8817e4Smiod 			  bfd_vma val)
1082*3d8817e4Smiod {
1083*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1084*3d8817e4Smiod   struct debug_name *n;
1085*3d8817e4Smiod   struct debug_typed_constant *tc;
1086*3d8817e4Smiod 
1087*3d8817e4Smiod   if (name == NULL || type == NULL)
1088*3d8817e4Smiod     return FALSE;
1089*3d8817e4Smiod 
1090*3d8817e4Smiod   n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT,
1091*3d8817e4Smiod 				      DEBUG_LINKAGE_NONE);
1092*3d8817e4Smiod   if (n == NULL)
1093*3d8817e4Smiod     return FALSE;
1094*3d8817e4Smiod 
1095*3d8817e4Smiod   tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
1096*3d8817e4Smiod   memset (tc, 0, sizeof *tc);
1097*3d8817e4Smiod 
1098*3d8817e4Smiod   tc->type = type;
1099*3d8817e4Smiod   tc->val = val;
1100*3d8817e4Smiod 
1101*3d8817e4Smiod   n->u.typed_constant = tc;
1102*3d8817e4Smiod 
1103*3d8817e4Smiod   return TRUE;
1104*3d8817e4Smiod }
1105*3d8817e4Smiod 
1106*3d8817e4Smiod /* Record a label.  */
1107*3d8817e4Smiod 
1108*3d8817e4Smiod bfd_boolean
debug_record_label(void * handle ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED,debug_type type ATTRIBUTE_UNUSED,bfd_vma addr ATTRIBUTE_UNUSED)1109*3d8817e4Smiod debug_record_label (void *handle ATTRIBUTE_UNUSED,
1110*3d8817e4Smiod 		    const char *name ATTRIBUTE_UNUSED,
1111*3d8817e4Smiod 		    debug_type type ATTRIBUTE_UNUSED,
1112*3d8817e4Smiod 		    bfd_vma addr ATTRIBUTE_UNUSED)
1113*3d8817e4Smiod {
1114*3d8817e4Smiod   /* FIXME.  */
1115*3d8817e4Smiod   debug_error (_("debug_record_label: not implemented"));
1116*3d8817e4Smiod   return FALSE;
1117*3d8817e4Smiod }
1118*3d8817e4Smiod 
1119*3d8817e4Smiod /* Record a variable.  */
1120*3d8817e4Smiod 
1121*3d8817e4Smiod bfd_boolean
debug_record_variable(void * handle,const char * name,debug_type type,enum debug_var_kind kind,bfd_vma val)1122*3d8817e4Smiod debug_record_variable (void *handle, const char *name, debug_type type,
1123*3d8817e4Smiod 		       enum debug_var_kind kind, bfd_vma val)
1124*3d8817e4Smiod {
1125*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1126*3d8817e4Smiod   struct debug_namespace **nsp;
1127*3d8817e4Smiod   enum debug_object_linkage linkage;
1128*3d8817e4Smiod   struct debug_name *n;
1129*3d8817e4Smiod   struct debug_variable *v;
1130*3d8817e4Smiod 
1131*3d8817e4Smiod   if (name == NULL || type == NULL)
1132*3d8817e4Smiod     return FALSE;
1133*3d8817e4Smiod 
1134*3d8817e4Smiod   if (info->current_unit == NULL
1135*3d8817e4Smiod       || info->current_file == NULL)
1136*3d8817e4Smiod     {
1137*3d8817e4Smiod       debug_error (_("debug_record_variable: no current file"));
1138*3d8817e4Smiod       return FALSE;
1139*3d8817e4Smiod     }
1140*3d8817e4Smiod 
1141*3d8817e4Smiod   if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC)
1142*3d8817e4Smiod     {
1143*3d8817e4Smiod       nsp = &info->current_file->globals;
1144*3d8817e4Smiod       if (kind == DEBUG_GLOBAL)
1145*3d8817e4Smiod 	linkage = DEBUG_LINKAGE_GLOBAL;
1146*3d8817e4Smiod       else
1147*3d8817e4Smiod 	linkage = DEBUG_LINKAGE_STATIC;
1148*3d8817e4Smiod     }
1149*3d8817e4Smiod   else
1150*3d8817e4Smiod     {
1151*3d8817e4Smiod       if (info->current_block == NULL)
1152*3d8817e4Smiod 	nsp = &info->current_file->globals;
1153*3d8817e4Smiod       else
1154*3d8817e4Smiod 	nsp = &info->current_block->locals;
1155*3d8817e4Smiod       linkage = DEBUG_LINKAGE_AUTOMATIC;
1156*3d8817e4Smiod     }
1157*3d8817e4Smiod 
1158*3d8817e4Smiod   n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage);
1159*3d8817e4Smiod   if (n == NULL)
1160*3d8817e4Smiod     return FALSE;
1161*3d8817e4Smiod 
1162*3d8817e4Smiod   v = (struct debug_variable *) xmalloc (sizeof *v);
1163*3d8817e4Smiod   memset (v, 0, sizeof *v);
1164*3d8817e4Smiod 
1165*3d8817e4Smiod   v->kind = kind;
1166*3d8817e4Smiod   v->type = type;
1167*3d8817e4Smiod   v->val = val;
1168*3d8817e4Smiod 
1169*3d8817e4Smiod   n->u.variable = v;
1170*3d8817e4Smiod 
1171*3d8817e4Smiod   return TRUE;
1172*3d8817e4Smiod }
1173*3d8817e4Smiod 
1174*3d8817e4Smiod /* Make a type with a given kind and size.  */
1175*3d8817e4Smiod 
1176*3d8817e4Smiod static struct debug_type *
debug_make_type(struct debug_handle * info ATTRIBUTE_UNUSED,enum debug_type_kind kind,unsigned int size)1177*3d8817e4Smiod debug_make_type (struct debug_handle *info ATTRIBUTE_UNUSED,
1178*3d8817e4Smiod 		 enum debug_type_kind kind, unsigned int size)
1179*3d8817e4Smiod {
1180*3d8817e4Smiod   struct debug_type *t;
1181*3d8817e4Smiod 
1182*3d8817e4Smiod   t = (struct debug_type *) xmalloc (sizeof *t);
1183*3d8817e4Smiod   memset (t, 0, sizeof *t);
1184*3d8817e4Smiod 
1185*3d8817e4Smiod   t->kind = kind;
1186*3d8817e4Smiod   t->size = size;
1187*3d8817e4Smiod 
1188*3d8817e4Smiod   return t;
1189*3d8817e4Smiod }
1190*3d8817e4Smiod 
1191*3d8817e4Smiod /* Make an indirect type which may be used as a placeholder for a type
1192*3d8817e4Smiod    which is referenced before it is defined.  */
1193*3d8817e4Smiod 
1194*3d8817e4Smiod debug_type
debug_make_indirect_type(void * handle,debug_type * slot,const char * tag)1195*3d8817e4Smiod debug_make_indirect_type (void *handle, debug_type *slot, const char *tag)
1196*3d8817e4Smiod {
1197*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1198*3d8817e4Smiod   struct debug_type *t;
1199*3d8817e4Smiod   struct debug_indirect_type *i;
1200*3d8817e4Smiod 
1201*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0);
1202*3d8817e4Smiod   if (t == NULL)
1203*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1204*3d8817e4Smiod 
1205*3d8817e4Smiod   i = (struct debug_indirect_type *) xmalloc (sizeof *i);
1206*3d8817e4Smiod   memset (i, 0, sizeof *i);
1207*3d8817e4Smiod 
1208*3d8817e4Smiod   i->slot = slot;
1209*3d8817e4Smiod   i->tag = tag;
1210*3d8817e4Smiod 
1211*3d8817e4Smiod   t->u.kindirect = i;
1212*3d8817e4Smiod 
1213*3d8817e4Smiod   return t;
1214*3d8817e4Smiod }
1215*3d8817e4Smiod 
1216*3d8817e4Smiod /* Make a void type.  There is only one of these.  */
1217*3d8817e4Smiod 
1218*3d8817e4Smiod debug_type
debug_make_void_type(void * handle)1219*3d8817e4Smiod debug_make_void_type (void *handle)
1220*3d8817e4Smiod {
1221*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1222*3d8817e4Smiod 
1223*3d8817e4Smiod   return debug_make_type (info, DEBUG_KIND_VOID, 0);
1224*3d8817e4Smiod }
1225*3d8817e4Smiod 
1226*3d8817e4Smiod /* Make an integer type of a given size.  The boolean argument is true
1227*3d8817e4Smiod    if the integer is unsigned.  */
1228*3d8817e4Smiod 
1229*3d8817e4Smiod debug_type
debug_make_int_type(void * handle,unsigned int size,bfd_boolean unsignedp)1230*3d8817e4Smiod debug_make_int_type (void *handle, unsigned int size, bfd_boolean unsignedp)
1231*3d8817e4Smiod {
1232*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1233*3d8817e4Smiod   struct debug_type *t;
1234*3d8817e4Smiod 
1235*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_INT, size);
1236*3d8817e4Smiod   if (t == NULL)
1237*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1238*3d8817e4Smiod 
1239*3d8817e4Smiod   t->u.kint = unsignedp;
1240*3d8817e4Smiod 
1241*3d8817e4Smiod   return t;
1242*3d8817e4Smiod }
1243*3d8817e4Smiod 
1244*3d8817e4Smiod /* Make a floating point type of a given size.  FIXME: On some
1245*3d8817e4Smiod    platforms, like an Alpha, you probably need to be able to specify
1246*3d8817e4Smiod    the format.  */
1247*3d8817e4Smiod 
1248*3d8817e4Smiod debug_type
debug_make_float_type(void * handle,unsigned int size)1249*3d8817e4Smiod debug_make_float_type (void *handle, unsigned int size)
1250*3d8817e4Smiod {
1251*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1252*3d8817e4Smiod 
1253*3d8817e4Smiod   return debug_make_type (info, DEBUG_KIND_FLOAT, size);
1254*3d8817e4Smiod }
1255*3d8817e4Smiod 
1256*3d8817e4Smiod /* Make a boolean type of a given size.  */
1257*3d8817e4Smiod 
1258*3d8817e4Smiod debug_type
debug_make_bool_type(void * handle,unsigned int size)1259*3d8817e4Smiod debug_make_bool_type (void *handle, unsigned int size)
1260*3d8817e4Smiod {
1261*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1262*3d8817e4Smiod 
1263*3d8817e4Smiod   return debug_make_type (info, DEBUG_KIND_BOOL, size);
1264*3d8817e4Smiod }
1265*3d8817e4Smiod 
1266*3d8817e4Smiod /* Make a complex type of a given size.  */
1267*3d8817e4Smiod 
1268*3d8817e4Smiod debug_type
debug_make_complex_type(void * handle,unsigned int size)1269*3d8817e4Smiod debug_make_complex_type (void *handle, unsigned int size)
1270*3d8817e4Smiod {
1271*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1272*3d8817e4Smiod 
1273*3d8817e4Smiod   return debug_make_type (info, DEBUG_KIND_COMPLEX, size);
1274*3d8817e4Smiod }
1275*3d8817e4Smiod 
1276*3d8817e4Smiod /* Make a structure type.  The second argument is true for a struct,
1277*3d8817e4Smiod    false for a union.  The third argument is the size of the struct.
1278*3d8817e4Smiod    The fourth argument is a NULL terminated array of fields.  */
1279*3d8817e4Smiod 
1280*3d8817e4Smiod debug_type
debug_make_struct_type(void * handle,bfd_boolean structp,bfd_vma size,debug_field * fields)1281*3d8817e4Smiod debug_make_struct_type (void *handle, bfd_boolean structp, bfd_vma size,
1282*3d8817e4Smiod 			debug_field *fields)
1283*3d8817e4Smiod {
1284*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1285*3d8817e4Smiod   struct debug_type *t;
1286*3d8817e4Smiod   struct debug_class_type *c;
1287*3d8817e4Smiod 
1288*3d8817e4Smiod   t = debug_make_type (info,
1289*3d8817e4Smiod 		       structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION,
1290*3d8817e4Smiod 		       size);
1291*3d8817e4Smiod   if (t == NULL)
1292*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1293*3d8817e4Smiod 
1294*3d8817e4Smiod   c = (struct debug_class_type *) xmalloc (sizeof *c);
1295*3d8817e4Smiod   memset (c, 0, sizeof *c);
1296*3d8817e4Smiod 
1297*3d8817e4Smiod   c->fields = fields;
1298*3d8817e4Smiod 
1299*3d8817e4Smiod   t->u.kclass = c;
1300*3d8817e4Smiod 
1301*3d8817e4Smiod   return t;
1302*3d8817e4Smiod }
1303*3d8817e4Smiod 
1304*3d8817e4Smiod /* Make an object type.  The first three arguments after the handle
1305*3d8817e4Smiod    are the same as for debug_make_struct_type.  The next arguments are
1306*3d8817e4Smiod    a NULL terminated array of base classes, a NULL terminated array of
1307*3d8817e4Smiod    methods, the type of the object holding the virtual function table
1308*3d8817e4Smiod    if it is not this object, and a boolean which is true if this
1309*3d8817e4Smiod    object has its own virtual function table.  */
1310*3d8817e4Smiod 
1311*3d8817e4Smiod debug_type
debug_make_object_type(void * handle,bfd_boolean structp,bfd_vma size,debug_field * fields,debug_baseclass * baseclasses,debug_method * methods,debug_type vptrbase,bfd_boolean ownvptr)1312*3d8817e4Smiod debug_make_object_type (void *handle, bfd_boolean structp, bfd_vma size,
1313*3d8817e4Smiod 			debug_field *fields, debug_baseclass *baseclasses,
1314*3d8817e4Smiod 			debug_method *methods, debug_type vptrbase,
1315*3d8817e4Smiod 			bfd_boolean ownvptr)
1316*3d8817e4Smiod {
1317*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1318*3d8817e4Smiod   struct debug_type *t;
1319*3d8817e4Smiod   struct debug_class_type *c;
1320*3d8817e4Smiod 
1321*3d8817e4Smiod   t = debug_make_type (info,
1322*3d8817e4Smiod 		       structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS,
1323*3d8817e4Smiod 		       size);
1324*3d8817e4Smiod   if (t == NULL)
1325*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1326*3d8817e4Smiod 
1327*3d8817e4Smiod   c = (struct debug_class_type *) xmalloc (sizeof *c);
1328*3d8817e4Smiod   memset (c, 0, sizeof *c);
1329*3d8817e4Smiod 
1330*3d8817e4Smiod   c->fields = fields;
1331*3d8817e4Smiod   c->baseclasses = baseclasses;
1332*3d8817e4Smiod   c->methods = methods;
1333*3d8817e4Smiod   if (ownvptr)
1334*3d8817e4Smiod     c->vptrbase = t;
1335*3d8817e4Smiod   else
1336*3d8817e4Smiod     c->vptrbase = vptrbase;
1337*3d8817e4Smiod 
1338*3d8817e4Smiod   t->u.kclass = c;
1339*3d8817e4Smiod 
1340*3d8817e4Smiod   return t;
1341*3d8817e4Smiod }
1342*3d8817e4Smiod 
1343*3d8817e4Smiod /* Make an enumeration type.  The arguments are a null terminated
1344*3d8817e4Smiod    array of strings, and an array of corresponding values.  */
1345*3d8817e4Smiod 
1346*3d8817e4Smiod debug_type
debug_make_enum_type(void * handle,const char ** names,bfd_signed_vma * values)1347*3d8817e4Smiod debug_make_enum_type (void *handle, const char **names,
1348*3d8817e4Smiod 		      bfd_signed_vma *values)
1349*3d8817e4Smiod {
1350*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1351*3d8817e4Smiod   struct debug_type *t;
1352*3d8817e4Smiod   struct debug_enum_type *e;
1353*3d8817e4Smiod 
1354*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_ENUM, 0);
1355*3d8817e4Smiod   if (t == NULL)
1356*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1357*3d8817e4Smiod 
1358*3d8817e4Smiod   e = (struct debug_enum_type *) xmalloc (sizeof *e);
1359*3d8817e4Smiod   memset (e, 0, sizeof *e);
1360*3d8817e4Smiod 
1361*3d8817e4Smiod   e->names = names;
1362*3d8817e4Smiod   e->values = values;
1363*3d8817e4Smiod 
1364*3d8817e4Smiod   t->u.kenum = e;
1365*3d8817e4Smiod 
1366*3d8817e4Smiod   return t;
1367*3d8817e4Smiod }
1368*3d8817e4Smiod 
1369*3d8817e4Smiod /* Make a pointer to a given type.  */
1370*3d8817e4Smiod 
1371*3d8817e4Smiod debug_type
debug_make_pointer_type(void * handle,debug_type type)1372*3d8817e4Smiod debug_make_pointer_type (void *handle, debug_type type)
1373*3d8817e4Smiod {
1374*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1375*3d8817e4Smiod   struct debug_type *t;
1376*3d8817e4Smiod 
1377*3d8817e4Smiod   if (type == NULL)
1378*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1379*3d8817e4Smiod 
1380*3d8817e4Smiod   if (type->pointer != DEBUG_TYPE_NULL)
1381*3d8817e4Smiod     return type->pointer;
1382*3d8817e4Smiod 
1383*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_POINTER, 0);
1384*3d8817e4Smiod   if (t == NULL)
1385*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1386*3d8817e4Smiod 
1387*3d8817e4Smiod   t->u.kpointer = type;
1388*3d8817e4Smiod 
1389*3d8817e4Smiod   type->pointer = t;
1390*3d8817e4Smiod 
1391*3d8817e4Smiod   return t;
1392*3d8817e4Smiod }
1393*3d8817e4Smiod 
1394*3d8817e4Smiod /* Make a function returning a given type.  FIXME: We should be able
1395*3d8817e4Smiod    to record the parameter types.  */
1396*3d8817e4Smiod 
1397*3d8817e4Smiod debug_type
debug_make_function_type(void * handle,debug_type type,debug_type * arg_types,bfd_boolean varargs)1398*3d8817e4Smiod debug_make_function_type (void *handle, debug_type type,
1399*3d8817e4Smiod 			  debug_type *arg_types, bfd_boolean varargs)
1400*3d8817e4Smiod {
1401*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1402*3d8817e4Smiod   struct debug_type *t;
1403*3d8817e4Smiod   struct debug_function_type *f;
1404*3d8817e4Smiod 
1405*3d8817e4Smiod   if (type == NULL)
1406*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1407*3d8817e4Smiod 
1408*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0);
1409*3d8817e4Smiod   if (t == NULL)
1410*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1411*3d8817e4Smiod 
1412*3d8817e4Smiod   f = (struct debug_function_type *) xmalloc (sizeof *f);
1413*3d8817e4Smiod   memset (f, 0, sizeof *f);
1414*3d8817e4Smiod 
1415*3d8817e4Smiod   f->return_type = type;
1416*3d8817e4Smiod   f->arg_types = arg_types;
1417*3d8817e4Smiod   f->varargs = varargs;
1418*3d8817e4Smiod 
1419*3d8817e4Smiod   t->u.kfunction = f;
1420*3d8817e4Smiod 
1421*3d8817e4Smiod   return t;
1422*3d8817e4Smiod }
1423*3d8817e4Smiod 
1424*3d8817e4Smiod /* Make a reference to a given type.  */
1425*3d8817e4Smiod 
1426*3d8817e4Smiod debug_type
debug_make_reference_type(void * handle,debug_type type)1427*3d8817e4Smiod debug_make_reference_type (void *handle, debug_type type)
1428*3d8817e4Smiod {
1429*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1430*3d8817e4Smiod   struct debug_type *t;
1431*3d8817e4Smiod 
1432*3d8817e4Smiod   if (type == NULL)
1433*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1434*3d8817e4Smiod 
1435*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0);
1436*3d8817e4Smiod   if (t == NULL)
1437*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1438*3d8817e4Smiod 
1439*3d8817e4Smiod   t->u.kreference = type;
1440*3d8817e4Smiod 
1441*3d8817e4Smiod   return t;
1442*3d8817e4Smiod }
1443*3d8817e4Smiod 
1444*3d8817e4Smiod /* Make a range of a given type from a lower to an upper bound.  */
1445*3d8817e4Smiod 
1446*3d8817e4Smiod debug_type
debug_make_range_type(void * handle,debug_type type,bfd_signed_vma lower,bfd_signed_vma upper)1447*3d8817e4Smiod debug_make_range_type (void *handle, debug_type type, bfd_signed_vma lower,
1448*3d8817e4Smiod 		       bfd_signed_vma upper)
1449*3d8817e4Smiod {
1450*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1451*3d8817e4Smiod   struct debug_type *t;
1452*3d8817e4Smiod   struct debug_range_type *r;
1453*3d8817e4Smiod 
1454*3d8817e4Smiod   if (type == NULL)
1455*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1456*3d8817e4Smiod 
1457*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_RANGE, 0);
1458*3d8817e4Smiod   if (t == NULL)
1459*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1460*3d8817e4Smiod 
1461*3d8817e4Smiod   r = (struct debug_range_type *) xmalloc (sizeof *r);
1462*3d8817e4Smiod   memset (r, 0, sizeof *r);
1463*3d8817e4Smiod 
1464*3d8817e4Smiod   r->type = type;
1465*3d8817e4Smiod   r->lower = lower;
1466*3d8817e4Smiod   r->upper = upper;
1467*3d8817e4Smiod 
1468*3d8817e4Smiod   t->u.krange = r;
1469*3d8817e4Smiod 
1470*3d8817e4Smiod   return t;
1471*3d8817e4Smiod }
1472*3d8817e4Smiod 
1473*3d8817e4Smiod /* Make an array type.  The second argument is the type of an element
1474*3d8817e4Smiod    of the array.  The third argument is the type of a range of the
1475*3d8817e4Smiod    array.  The fourth and fifth argument are the lower and upper
1476*3d8817e4Smiod    bounds, respectively.  The sixth argument is true if this array is
1477*3d8817e4Smiod    actually a string, as in C.  */
1478*3d8817e4Smiod 
1479*3d8817e4Smiod debug_type
debug_make_array_type(void * handle,debug_type element_type,debug_type range_type,bfd_signed_vma lower,bfd_signed_vma upper,bfd_boolean stringp)1480*3d8817e4Smiod debug_make_array_type (void *handle, debug_type element_type,
1481*3d8817e4Smiod 		       debug_type range_type, bfd_signed_vma lower,
1482*3d8817e4Smiod 		       bfd_signed_vma upper, bfd_boolean stringp)
1483*3d8817e4Smiod {
1484*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1485*3d8817e4Smiod   struct debug_type *t;
1486*3d8817e4Smiod   struct debug_array_type *a;
1487*3d8817e4Smiod 
1488*3d8817e4Smiod   if (element_type == NULL || range_type == NULL)
1489*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1490*3d8817e4Smiod 
1491*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_ARRAY, 0);
1492*3d8817e4Smiod   if (t == NULL)
1493*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1494*3d8817e4Smiod 
1495*3d8817e4Smiod   a = (struct debug_array_type *) xmalloc (sizeof *a);
1496*3d8817e4Smiod   memset (a, 0, sizeof *a);
1497*3d8817e4Smiod 
1498*3d8817e4Smiod   a->element_type = element_type;
1499*3d8817e4Smiod   a->range_type = range_type;
1500*3d8817e4Smiod   a->lower = lower;
1501*3d8817e4Smiod   a->upper = upper;
1502*3d8817e4Smiod   a->stringp = stringp;
1503*3d8817e4Smiod 
1504*3d8817e4Smiod   t->u.karray = a;
1505*3d8817e4Smiod 
1506*3d8817e4Smiod   return t;
1507*3d8817e4Smiod }
1508*3d8817e4Smiod 
1509*3d8817e4Smiod /* Make a set of a given type.  For example, a Pascal set type.  The
1510*3d8817e4Smiod    boolean argument is true if this set is actually a bitstring, as in
1511*3d8817e4Smiod    CHILL.  */
1512*3d8817e4Smiod 
1513*3d8817e4Smiod debug_type
debug_make_set_type(void * handle,debug_type type,bfd_boolean bitstringp)1514*3d8817e4Smiod debug_make_set_type (void *handle, debug_type type, bfd_boolean bitstringp)
1515*3d8817e4Smiod {
1516*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1517*3d8817e4Smiod   struct debug_type *t;
1518*3d8817e4Smiod   struct debug_set_type *s;
1519*3d8817e4Smiod 
1520*3d8817e4Smiod   if (type == NULL)
1521*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1522*3d8817e4Smiod 
1523*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_SET, 0);
1524*3d8817e4Smiod   if (t == NULL)
1525*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1526*3d8817e4Smiod 
1527*3d8817e4Smiod   s = (struct debug_set_type *) xmalloc (sizeof *s);
1528*3d8817e4Smiod   memset (s, 0, sizeof *s);
1529*3d8817e4Smiod 
1530*3d8817e4Smiod   s->type = type;
1531*3d8817e4Smiod   s->bitstringp = bitstringp;
1532*3d8817e4Smiod 
1533*3d8817e4Smiod   t->u.kset = s;
1534*3d8817e4Smiod 
1535*3d8817e4Smiod   return t;
1536*3d8817e4Smiod }
1537*3d8817e4Smiod 
1538*3d8817e4Smiod /* Make a type for a pointer which is relative to an object.  The
1539*3d8817e4Smiod    second argument is the type of the object to which the pointer is
1540*3d8817e4Smiod    relative.  The third argument is the type that the pointer points
1541*3d8817e4Smiod    to.  */
1542*3d8817e4Smiod 
1543*3d8817e4Smiod debug_type
debug_make_offset_type(void * handle,debug_type base_type,debug_type target_type)1544*3d8817e4Smiod debug_make_offset_type (void *handle, debug_type base_type,
1545*3d8817e4Smiod 			debug_type target_type)
1546*3d8817e4Smiod {
1547*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1548*3d8817e4Smiod   struct debug_type *t;
1549*3d8817e4Smiod   struct debug_offset_type *o;
1550*3d8817e4Smiod 
1551*3d8817e4Smiod   if (base_type == NULL || target_type == NULL)
1552*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1553*3d8817e4Smiod 
1554*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_OFFSET, 0);
1555*3d8817e4Smiod   if (t == NULL)
1556*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1557*3d8817e4Smiod 
1558*3d8817e4Smiod   o = (struct debug_offset_type *) xmalloc (sizeof *o);
1559*3d8817e4Smiod   memset (o, 0, sizeof *o);
1560*3d8817e4Smiod 
1561*3d8817e4Smiod   o->base_type = base_type;
1562*3d8817e4Smiod   o->target_type = target_type;
1563*3d8817e4Smiod 
1564*3d8817e4Smiod   t->u.koffset = o;
1565*3d8817e4Smiod 
1566*3d8817e4Smiod   return t;
1567*3d8817e4Smiod }
1568*3d8817e4Smiod 
1569*3d8817e4Smiod /* Make a type for a method function.  The second argument is the
1570*3d8817e4Smiod    return type, the third argument is the domain, and the fourth
1571*3d8817e4Smiod    argument is a NULL terminated array of argument types.  */
1572*3d8817e4Smiod 
1573*3d8817e4Smiod debug_type
debug_make_method_type(void * handle,debug_type return_type,debug_type domain_type,debug_type * arg_types,bfd_boolean varargs)1574*3d8817e4Smiod debug_make_method_type (void *handle, debug_type return_type,
1575*3d8817e4Smiod 			debug_type domain_type, debug_type *arg_types,
1576*3d8817e4Smiod 			bfd_boolean varargs)
1577*3d8817e4Smiod {
1578*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1579*3d8817e4Smiod   struct debug_type *t;
1580*3d8817e4Smiod   struct debug_method_type *m;
1581*3d8817e4Smiod 
1582*3d8817e4Smiod   if (return_type == NULL)
1583*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1584*3d8817e4Smiod 
1585*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_METHOD, 0);
1586*3d8817e4Smiod   if (t == NULL)
1587*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1588*3d8817e4Smiod 
1589*3d8817e4Smiod   m = (struct debug_method_type *) xmalloc (sizeof *m);
1590*3d8817e4Smiod   memset (m, 0, sizeof *m);
1591*3d8817e4Smiod 
1592*3d8817e4Smiod   m->return_type = return_type;
1593*3d8817e4Smiod   m->domain_type = domain_type;
1594*3d8817e4Smiod   m->arg_types = arg_types;
1595*3d8817e4Smiod   m->varargs = varargs;
1596*3d8817e4Smiod 
1597*3d8817e4Smiod   t->u.kmethod = m;
1598*3d8817e4Smiod 
1599*3d8817e4Smiod   return t;
1600*3d8817e4Smiod }
1601*3d8817e4Smiod 
1602*3d8817e4Smiod /* Make a const qualified version of a given type.  */
1603*3d8817e4Smiod 
1604*3d8817e4Smiod debug_type
debug_make_const_type(void * handle,debug_type type)1605*3d8817e4Smiod debug_make_const_type (void *handle, debug_type type)
1606*3d8817e4Smiod {
1607*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1608*3d8817e4Smiod   struct debug_type *t;
1609*3d8817e4Smiod 
1610*3d8817e4Smiod   if (type == NULL)
1611*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1612*3d8817e4Smiod 
1613*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_CONST, 0);
1614*3d8817e4Smiod   if (t == NULL)
1615*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1616*3d8817e4Smiod 
1617*3d8817e4Smiod   t->u.kconst = type;
1618*3d8817e4Smiod 
1619*3d8817e4Smiod   return t;
1620*3d8817e4Smiod }
1621*3d8817e4Smiod 
1622*3d8817e4Smiod /* Make a volatile qualified version of a given type.  */
1623*3d8817e4Smiod 
1624*3d8817e4Smiod debug_type
debug_make_volatile_type(void * handle,debug_type type)1625*3d8817e4Smiod debug_make_volatile_type (void *handle, debug_type type)
1626*3d8817e4Smiod {
1627*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1628*3d8817e4Smiod   struct debug_type *t;
1629*3d8817e4Smiod 
1630*3d8817e4Smiod   if (type == NULL)
1631*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1632*3d8817e4Smiod 
1633*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0);
1634*3d8817e4Smiod   if (t == NULL)
1635*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1636*3d8817e4Smiod 
1637*3d8817e4Smiod   t->u.kvolatile = type;
1638*3d8817e4Smiod 
1639*3d8817e4Smiod   return t;
1640*3d8817e4Smiod }
1641*3d8817e4Smiod 
1642*3d8817e4Smiod /* Make an undefined tagged type.  For example, a struct which has
1643*3d8817e4Smiod    been mentioned, but not defined.  */
1644*3d8817e4Smiod 
1645*3d8817e4Smiod debug_type
debug_make_undefined_tagged_type(void * handle,const char * name,enum debug_type_kind kind)1646*3d8817e4Smiod debug_make_undefined_tagged_type (void *handle, const char *name,
1647*3d8817e4Smiod 				  enum debug_type_kind kind)
1648*3d8817e4Smiod {
1649*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1650*3d8817e4Smiod   struct debug_type *t;
1651*3d8817e4Smiod 
1652*3d8817e4Smiod   if (name == NULL)
1653*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1654*3d8817e4Smiod 
1655*3d8817e4Smiod   switch (kind)
1656*3d8817e4Smiod     {
1657*3d8817e4Smiod     case DEBUG_KIND_STRUCT:
1658*3d8817e4Smiod     case DEBUG_KIND_UNION:
1659*3d8817e4Smiod     case DEBUG_KIND_CLASS:
1660*3d8817e4Smiod     case DEBUG_KIND_UNION_CLASS:
1661*3d8817e4Smiod     case DEBUG_KIND_ENUM:
1662*3d8817e4Smiod       break;
1663*3d8817e4Smiod 
1664*3d8817e4Smiod     default:
1665*3d8817e4Smiod       debug_error (_("debug_make_undefined_type: unsupported kind"));
1666*3d8817e4Smiod       return DEBUG_TYPE_NULL;
1667*3d8817e4Smiod     }
1668*3d8817e4Smiod 
1669*3d8817e4Smiod   t = debug_make_type (info, kind, 0);
1670*3d8817e4Smiod   if (t == NULL)
1671*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1672*3d8817e4Smiod 
1673*3d8817e4Smiod   return debug_tag_type (handle, name, t);
1674*3d8817e4Smiod }
1675*3d8817e4Smiod 
1676*3d8817e4Smiod /* Make a base class for an object.  The second argument is the base
1677*3d8817e4Smiod    class type.  The third argument is the bit position of this base
1678*3d8817e4Smiod    class in the object (always 0 unless doing multiple inheritance).
1679*3d8817e4Smiod    The fourth argument is whether this is a virtual class.  The fifth
1680*3d8817e4Smiod    argument is the visibility of the base class.  */
1681*3d8817e4Smiod 
1682*3d8817e4Smiod debug_baseclass
debug_make_baseclass(void * handle ATTRIBUTE_UNUSED,debug_type type,bfd_vma bitpos,bfd_boolean virtual,enum debug_visibility visibility)1683*3d8817e4Smiod debug_make_baseclass (void *handle ATTRIBUTE_UNUSED, debug_type type,
1684*3d8817e4Smiod 		      bfd_vma bitpos, bfd_boolean virtual,
1685*3d8817e4Smiod 		      enum debug_visibility visibility)
1686*3d8817e4Smiod {
1687*3d8817e4Smiod   struct debug_baseclass *b;
1688*3d8817e4Smiod 
1689*3d8817e4Smiod   b = (struct debug_baseclass *) xmalloc (sizeof *b);
1690*3d8817e4Smiod   memset (b, 0, sizeof *b);
1691*3d8817e4Smiod 
1692*3d8817e4Smiod   b->type = type;
1693*3d8817e4Smiod   b->bitpos = bitpos;
1694*3d8817e4Smiod   b->virtual = virtual;
1695*3d8817e4Smiod   b->visibility = visibility;
1696*3d8817e4Smiod 
1697*3d8817e4Smiod   return b;
1698*3d8817e4Smiod }
1699*3d8817e4Smiod 
1700*3d8817e4Smiod /* Make a field for a struct.  The second argument is the name.  The
1701*3d8817e4Smiod    third argument is the type of the field.  The fourth argument is
1702*3d8817e4Smiod    the bit position of the field.  The fifth argument is the size of
1703*3d8817e4Smiod    the field (it may be zero).  The sixth argument is the visibility
1704*3d8817e4Smiod    of the field.  */
1705*3d8817e4Smiod 
1706*3d8817e4Smiod debug_field
debug_make_field(void * handle ATTRIBUTE_UNUSED,const char * name,debug_type type,bfd_vma bitpos,bfd_vma bitsize,enum debug_visibility visibility)1707*3d8817e4Smiod debug_make_field (void *handle ATTRIBUTE_UNUSED, const char *name,
1708*3d8817e4Smiod 		  debug_type type, bfd_vma bitpos, bfd_vma bitsize,
1709*3d8817e4Smiod 		  enum debug_visibility visibility)
1710*3d8817e4Smiod {
1711*3d8817e4Smiod   struct debug_field *f;
1712*3d8817e4Smiod 
1713*3d8817e4Smiod   f = (struct debug_field *) xmalloc (sizeof *f);
1714*3d8817e4Smiod   memset (f, 0, sizeof *f);
1715*3d8817e4Smiod 
1716*3d8817e4Smiod   f->name = name;
1717*3d8817e4Smiod   f->type = type;
1718*3d8817e4Smiod   f->static_member = FALSE;
1719*3d8817e4Smiod   f->u.f.bitpos = bitpos;
1720*3d8817e4Smiod   f->u.f.bitsize = bitsize;
1721*3d8817e4Smiod   f->visibility = visibility;
1722*3d8817e4Smiod 
1723*3d8817e4Smiod   return f;
1724*3d8817e4Smiod }
1725*3d8817e4Smiod 
1726*3d8817e4Smiod /* Make a static member of an object.  The second argument is the
1727*3d8817e4Smiod    name.  The third argument is the type of the member.  The fourth
1728*3d8817e4Smiod    argument is the physical name of the member (i.e., the name as a
1729*3d8817e4Smiod    global variable).  The fifth argument is the visibility of the
1730*3d8817e4Smiod    member.  */
1731*3d8817e4Smiod 
1732*3d8817e4Smiod debug_field
debug_make_static_member(void * handle ATTRIBUTE_UNUSED,const char * name,debug_type type,const char * physname,enum debug_visibility visibility)1733*3d8817e4Smiod debug_make_static_member (void *handle ATTRIBUTE_UNUSED, const char *name,
1734*3d8817e4Smiod 			  debug_type type, const char *physname,
1735*3d8817e4Smiod 			  enum debug_visibility visibility)
1736*3d8817e4Smiod {
1737*3d8817e4Smiod   struct debug_field *f;
1738*3d8817e4Smiod 
1739*3d8817e4Smiod   f = (struct debug_field *) xmalloc (sizeof *f);
1740*3d8817e4Smiod   memset (f, 0, sizeof *f);
1741*3d8817e4Smiod 
1742*3d8817e4Smiod   f->name = name;
1743*3d8817e4Smiod   f->type = type;
1744*3d8817e4Smiod   f->static_member = TRUE;
1745*3d8817e4Smiod   f->u.s.physname = physname;
1746*3d8817e4Smiod   f->visibility = visibility;
1747*3d8817e4Smiod 
1748*3d8817e4Smiod   return f;
1749*3d8817e4Smiod }
1750*3d8817e4Smiod 
1751*3d8817e4Smiod /* Make a method.  The second argument is the name, and the third
1752*3d8817e4Smiod    argument is a NULL terminated array of method variants.  */
1753*3d8817e4Smiod 
1754*3d8817e4Smiod debug_method
debug_make_method(void * handle ATTRIBUTE_UNUSED,const char * name,debug_method_variant * variants)1755*3d8817e4Smiod debug_make_method (void *handle ATTRIBUTE_UNUSED, const char *name,
1756*3d8817e4Smiod 		   debug_method_variant *variants)
1757*3d8817e4Smiod {
1758*3d8817e4Smiod   struct debug_method *m;
1759*3d8817e4Smiod 
1760*3d8817e4Smiod   m = (struct debug_method *) xmalloc (sizeof *m);
1761*3d8817e4Smiod   memset (m, 0, sizeof *m);
1762*3d8817e4Smiod 
1763*3d8817e4Smiod   m->name = name;
1764*3d8817e4Smiod   m->variants = variants;
1765*3d8817e4Smiod 
1766*3d8817e4Smiod   return m;
1767*3d8817e4Smiod }
1768*3d8817e4Smiod 
1769*3d8817e4Smiod /* Make a method argument.  The second argument is the real name of
1770*3d8817e4Smiod    the function.  The third argument is the type of the function.  The
1771*3d8817e4Smiod    fourth argument is the visibility.  The fifth argument is whether
1772*3d8817e4Smiod    this is a const function.  The sixth argument is whether this is a
1773*3d8817e4Smiod    volatile function.  The seventh argument is the offset in the
1774*3d8817e4Smiod    virtual function table, if any.  The eighth argument is the virtual
1775*3d8817e4Smiod    function context.  FIXME: Are the const and volatile arguments
1776*3d8817e4Smiod    necessary?  Could we just use debug_make_const_type?  */
1777*3d8817e4Smiod 
1778*3d8817e4Smiod debug_method_variant
debug_make_method_variant(void * handle ATTRIBUTE_UNUSED,const char * physname,debug_type type,enum debug_visibility visibility,bfd_boolean constp,bfd_boolean volatilep,bfd_vma voffset,debug_type context)1779*3d8817e4Smiod debug_make_method_variant (void *handle ATTRIBUTE_UNUSED,
1780*3d8817e4Smiod 			   const char *physname, debug_type type,
1781*3d8817e4Smiod 			   enum debug_visibility visibility,
1782*3d8817e4Smiod 			   bfd_boolean constp, bfd_boolean volatilep,
1783*3d8817e4Smiod 			   bfd_vma voffset, debug_type context)
1784*3d8817e4Smiod {
1785*3d8817e4Smiod   struct debug_method_variant *m;
1786*3d8817e4Smiod 
1787*3d8817e4Smiod   m = (struct debug_method_variant *) xmalloc (sizeof *m);
1788*3d8817e4Smiod   memset (m, 0, sizeof *m);
1789*3d8817e4Smiod 
1790*3d8817e4Smiod   m->physname = physname;
1791*3d8817e4Smiod   m->type = type;
1792*3d8817e4Smiod   m->visibility = visibility;
1793*3d8817e4Smiod   m->constp = constp;
1794*3d8817e4Smiod   m->volatilep = volatilep;
1795*3d8817e4Smiod   m->voffset = voffset;
1796*3d8817e4Smiod   m->context = context;
1797*3d8817e4Smiod 
1798*3d8817e4Smiod   return m;
1799*3d8817e4Smiod }
1800*3d8817e4Smiod 
1801*3d8817e4Smiod /* Make a static method argument.  The arguments are the same as for
1802*3d8817e4Smiod    debug_make_method_variant, except that the last two are omitted
1803*3d8817e4Smiod    since a static method can not also be virtual.  */
1804*3d8817e4Smiod 
1805*3d8817e4Smiod debug_method_variant
debug_make_static_method_variant(void * handle ATTRIBUTE_UNUSED,const char * physname,debug_type type,enum debug_visibility visibility,bfd_boolean constp,bfd_boolean volatilep)1806*3d8817e4Smiod debug_make_static_method_variant (void *handle ATTRIBUTE_UNUSED,
1807*3d8817e4Smiod 				  const char *physname, debug_type type,
1808*3d8817e4Smiod 				  enum debug_visibility visibility,
1809*3d8817e4Smiod 				  bfd_boolean constp, bfd_boolean volatilep)
1810*3d8817e4Smiod {
1811*3d8817e4Smiod   struct debug_method_variant *m;
1812*3d8817e4Smiod 
1813*3d8817e4Smiod   m = (struct debug_method_variant *) xmalloc (sizeof *m);
1814*3d8817e4Smiod   memset (m, 0, sizeof *m);
1815*3d8817e4Smiod 
1816*3d8817e4Smiod   m->physname = physname;
1817*3d8817e4Smiod   m->type = type;
1818*3d8817e4Smiod   m->visibility = visibility;
1819*3d8817e4Smiod   m->constp = constp;
1820*3d8817e4Smiod   m->volatilep = volatilep;
1821*3d8817e4Smiod   m->voffset = VOFFSET_STATIC_METHOD;
1822*3d8817e4Smiod 
1823*3d8817e4Smiod   return m;
1824*3d8817e4Smiod }
1825*3d8817e4Smiod 
1826*3d8817e4Smiod /* Name a type.  */
1827*3d8817e4Smiod 
1828*3d8817e4Smiod debug_type
debug_name_type(void * handle,const char * name,debug_type type)1829*3d8817e4Smiod debug_name_type (void *handle, const char *name, debug_type type)
1830*3d8817e4Smiod {
1831*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1832*3d8817e4Smiod   struct debug_type *t;
1833*3d8817e4Smiod   struct debug_named_type *n;
1834*3d8817e4Smiod   struct debug_name *nm;
1835*3d8817e4Smiod 
1836*3d8817e4Smiod   if (name == NULL || type == NULL)
1837*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1838*3d8817e4Smiod 
1839*3d8817e4Smiod   if (info->current_unit == NULL
1840*3d8817e4Smiod       || info->current_file == NULL)
1841*3d8817e4Smiod     {
1842*3d8817e4Smiod       debug_error (_("debug_name_type: no current file"));
1843*3d8817e4Smiod       return DEBUG_TYPE_NULL;
1844*3d8817e4Smiod     }
1845*3d8817e4Smiod 
1846*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
1847*3d8817e4Smiod   if (t == NULL)
1848*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1849*3d8817e4Smiod 
1850*3d8817e4Smiod   n = (struct debug_named_type *) xmalloc (sizeof *n);
1851*3d8817e4Smiod   memset (n, 0, sizeof *n);
1852*3d8817e4Smiod 
1853*3d8817e4Smiod   n->type = type;
1854*3d8817e4Smiod 
1855*3d8817e4Smiod   t->u.knamed = n;
1856*3d8817e4Smiod 
1857*3d8817e4Smiod   /* We always add the name to the global namespace.  This is probably
1858*3d8817e4Smiod      wrong in some cases, but it seems to be right for stabs.  FIXME.  */
1859*3d8817e4Smiod 
1860*3d8817e4Smiod   nm = debug_add_to_namespace (info, &info->current_file->globals, name,
1861*3d8817e4Smiod 			       DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
1862*3d8817e4Smiod   if (nm == NULL)
1863*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1864*3d8817e4Smiod 
1865*3d8817e4Smiod   nm->u.type = t;
1866*3d8817e4Smiod 
1867*3d8817e4Smiod   n->name = nm;
1868*3d8817e4Smiod 
1869*3d8817e4Smiod   return t;
1870*3d8817e4Smiod }
1871*3d8817e4Smiod 
1872*3d8817e4Smiod /* Tag a type.  */
1873*3d8817e4Smiod 
1874*3d8817e4Smiod debug_type
debug_tag_type(void * handle,const char * name,debug_type type)1875*3d8817e4Smiod debug_tag_type (void *handle, const char *name, debug_type type)
1876*3d8817e4Smiod {
1877*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1878*3d8817e4Smiod   struct debug_type *t;
1879*3d8817e4Smiod   struct debug_named_type *n;
1880*3d8817e4Smiod   struct debug_name *nm;
1881*3d8817e4Smiod 
1882*3d8817e4Smiod   if (name == NULL || type == NULL)
1883*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1884*3d8817e4Smiod 
1885*3d8817e4Smiod   if (info->current_file == NULL)
1886*3d8817e4Smiod     {
1887*3d8817e4Smiod       debug_error (_("debug_tag_type: no current file"));
1888*3d8817e4Smiod       return DEBUG_TYPE_NULL;
1889*3d8817e4Smiod     }
1890*3d8817e4Smiod 
1891*3d8817e4Smiod   if (type->kind == DEBUG_KIND_TAGGED)
1892*3d8817e4Smiod     {
1893*3d8817e4Smiod       if (strcmp (type->u.knamed->name->name, name) == 0)
1894*3d8817e4Smiod 	return type;
1895*3d8817e4Smiod       debug_error (_("debug_tag_type: extra tag attempted"));
1896*3d8817e4Smiod       return DEBUG_TYPE_NULL;
1897*3d8817e4Smiod     }
1898*3d8817e4Smiod 
1899*3d8817e4Smiod   t = debug_make_type (info, DEBUG_KIND_TAGGED, 0);
1900*3d8817e4Smiod   if (t == NULL)
1901*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1902*3d8817e4Smiod 
1903*3d8817e4Smiod   n = (struct debug_named_type *) xmalloc (sizeof *n);
1904*3d8817e4Smiod   memset (n, 0, sizeof *n);
1905*3d8817e4Smiod 
1906*3d8817e4Smiod   n->type = type;
1907*3d8817e4Smiod 
1908*3d8817e4Smiod   t->u.knamed = n;
1909*3d8817e4Smiod 
1910*3d8817e4Smiod   /* We keep a global namespace of tags for each compilation unit.  I
1911*3d8817e4Smiod      don't know if that is the right thing to do.  */
1912*3d8817e4Smiod 
1913*3d8817e4Smiod   nm = debug_add_to_namespace (info, &info->current_file->globals, name,
1914*3d8817e4Smiod 			       DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE);
1915*3d8817e4Smiod   if (nm == NULL)
1916*3d8817e4Smiod     return DEBUG_TYPE_NULL;
1917*3d8817e4Smiod 
1918*3d8817e4Smiod   nm->u.tag = t;
1919*3d8817e4Smiod 
1920*3d8817e4Smiod   n->name = nm;
1921*3d8817e4Smiod 
1922*3d8817e4Smiod   return t;
1923*3d8817e4Smiod }
1924*3d8817e4Smiod 
1925*3d8817e4Smiod /* Record the size of a given type.  */
1926*3d8817e4Smiod 
1927*3d8817e4Smiod bfd_boolean
debug_record_type_size(void * handle ATTRIBUTE_UNUSED,debug_type type,unsigned int size)1928*3d8817e4Smiod debug_record_type_size (void *handle ATTRIBUTE_UNUSED, debug_type type,
1929*3d8817e4Smiod 			unsigned int size)
1930*3d8817e4Smiod {
1931*3d8817e4Smiod   if (type->size != 0 && type->size != size)
1932*3d8817e4Smiod     fprintf (stderr, _("Warning: changing type size from %d to %d\n"),
1933*3d8817e4Smiod 	     type->size, size);
1934*3d8817e4Smiod 
1935*3d8817e4Smiod   type->size = size;
1936*3d8817e4Smiod 
1937*3d8817e4Smiod   return TRUE;
1938*3d8817e4Smiod }
1939*3d8817e4Smiod 
1940*3d8817e4Smiod /* Find a named type.  */
1941*3d8817e4Smiod 
1942*3d8817e4Smiod debug_type
debug_find_named_type(void * handle,const char * name)1943*3d8817e4Smiod debug_find_named_type (void *handle, const char *name)
1944*3d8817e4Smiod {
1945*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
1946*3d8817e4Smiod   struct debug_block *b;
1947*3d8817e4Smiod   struct debug_file *f;
1948*3d8817e4Smiod 
1949*3d8817e4Smiod   /* We only search the current compilation unit.  I don't know if
1950*3d8817e4Smiod      this is right or not.  */
1951*3d8817e4Smiod 
1952*3d8817e4Smiod   if (info->current_unit == NULL)
1953*3d8817e4Smiod     {
1954*3d8817e4Smiod       debug_error (_("debug_find_named_type: no current compilation unit"));
1955*3d8817e4Smiod       return DEBUG_TYPE_NULL;
1956*3d8817e4Smiod     }
1957*3d8817e4Smiod 
1958*3d8817e4Smiod   for (b = info->current_block; b != NULL; b = b->parent)
1959*3d8817e4Smiod     {
1960*3d8817e4Smiod       if (b->locals != NULL)
1961*3d8817e4Smiod 	{
1962*3d8817e4Smiod 	  struct debug_name *n;
1963*3d8817e4Smiod 
1964*3d8817e4Smiod 	  for (n = b->locals->list; n != NULL; n = n->next)
1965*3d8817e4Smiod 	    {
1966*3d8817e4Smiod 	      if (n->kind == DEBUG_OBJECT_TYPE
1967*3d8817e4Smiod 		  && n->name[0] == name[0]
1968*3d8817e4Smiod 		  && strcmp (n->name, name) == 0)
1969*3d8817e4Smiod 		return n->u.type;
1970*3d8817e4Smiod 	    }
1971*3d8817e4Smiod 	}
1972*3d8817e4Smiod     }
1973*3d8817e4Smiod 
1974*3d8817e4Smiod   for (f = info->current_unit->files; f != NULL; f = f->next)
1975*3d8817e4Smiod     {
1976*3d8817e4Smiod       if (f->globals != NULL)
1977*3d8817e4Smiod 	{
1978*3d8817e4Smiod 	  struct debug_name *n;
1979*3d8817e4Smiod 
1980*3d8817e4Smiod 	  for (n = f->globals->list; n != NULL; n = n->next)
1981*3d8817e4Smiod 	    {
1982*3d8817e4Smiod 	      if (n->kind == DEBUG_OBJECT_TYPE
1983*3d8817e4Smiod 		  && n->name[0] == name[0]
1984*3d8817e4Smiod 		  && strcmp (n->name, name) == 0)
1985*3d8817e4Smiod 		return n->u.type;
1986*3d8817e4Smiod 	    }
1987*3d8817e4Smiod 	}
1988*3d8817e4Smiod     }
1989*3d8817e4Smiod 
1990*3d8817e4Smiod   return DEBUG_TYPE_NULL;
1991*3d8817e4Smiod }
1992*3d8817e4Smiod 
1993*3d8817e4Smiod /* Find a tagged type.  */
1994*3d8817e4Smiod 
1995*3d8817e4Smiod debug_type
debug_find_tagged_type(void * handle,const char * name,enum debug_type_kind kind)1996*3d8817e4Smiod debug_find_tagged_type (void *handle, const char *name,
1997*3d8817e4Smiod 			enum debug_type_kind kind)
1998*3d8817e4Smiod {
1999*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
2000*3d8817e4Smiod   struct debug_unit *u;
2001*3d8817e4Smiod 
2002*3d8817e4Smiod   /* We search the globals of all the compilation units.  I don't know
2003*3d8817e4Smiod      if this is correct or not.  It would be easy to change.  */
2004*3d8817e4Smiod 
2005*3d8817e4Smiod   for (u = info->units; u != NULL; u = u->next)
2006*3d8817e4Smiod     {
2007*3d8817e4Smiod       struct debug_file *f;
2008*3d8817e4Smiod 
2009*3d8817e4Smiod       for (f = u->files; f != NULL; f = f->next)
2010*3d8817e4Smiod 	{
2011*3d8817e4Smiod 	  struct debug_name *n;
2012*3d8817e4Smiod 
2013*3d8817e4Smiod 	  if (f->globals != NULL)
2014*3d8817e4Smiod 	    {
2015*3d8817e4Smiod 	      for (n = f->globals->list; n != NULL; n = n->next)
2016*3d8817e4Smiod 		{
2017*3d8817e4Smiod 		  if (n->kind == DEBUG_OBJECT_TAG
2018*3d8817e4Smiod 		      && (kind == DEBUG_KIND_ILLEGAL
2019*3d8817e4Smiod 			  || n->u.tag->kind == kind)
2020*3d8817e4Smiod 		      && n->name[0] == name[0]
2021*3d8817e4Smiod 		      && strcmp (n->name, name) == 0)
2022*3d8817e4Smiod 		    return n->u.tag;
2023*3d8817e4Smiod 		}
2024*3d8817e4Smiod 	    }
2025*3d8817e4Smiod 	}
2026*3d8817e4Smiod     }
2027*3d8817e4Smiod 
2028*3d8817e4Smiod   return DEBUG_TYPE_NULL;
2029*3d8817e4Smiod }
2030*3d8817e4Smiod 
2031*3d8817e4Smiod /* Get a base type.  We build a linked list on the stack to avoid
2032*3d8817e4Smiod    crashing if the type is defined circularly.  */
2033*3d8817e4Smiod 
2034*3d8817e4Smiod static struct debug_type *
debug_get_real_type(void * handle,debug_type type,struct debug_type_real_list * list)2035*3d8817e4Smiod debug_get_real_type (void *handle, debug_type type,
2036*3d8817e4Smiod 		     struct debug_type_real_list *list)
2037*3d8817e4Smiod {
2038*3d8817e4Smiod   struct debug_type_real_list *l;
2039*3d8817e4Smiod   struct debug_type_real_list rl;
2040*3d8817e4Smiod 
2041*3d8817e4Smiod   switch (type->kind)
2042*3d8817e4Smiod     {
2043*3d8817e4Smiod     default:
2044*3d8817e4Smiod       return type;
2045*3d8817e4Smiod 
2046*3d8817e4Smiod     case DEBUG_KIND_INDIRECT:
2047*3d8817e4Smiod     case DEBUG_KIND_NAMED:
2048*3d8817e4Smiod     case DEBUG_KIND_TAGGED:
2049*3d8817e4Smiod       break;
2050*3d8817e4Smiod     }
2051*3d8817e4Smiod 
2052*3d8817e4Smiod   for (l = list; l != NULL; l = l->next)
2053*3d8817e4Smiod     {
2054*3d8817e4Smiod       if (l->t == type || l == l->next)
2055*3d8817e4Smiod 	{
2056*3d8817e4Smiod 	  fprintf (stderr,
2057*3d8817e4Smiod 		   _("debug_get_real_type: circular debug information for %s\n"),
2058*3d8817e4Smiod 		   debug_get_type_name (handle, type));
2059*3d8817e4Smiod 	  return NULL;
2060*3d8817e4Smiod 	}
2061*3d8817e4Smiod     }
2062*3d8817e4Smiod 
2063*3d8817e4Smiod   rl.next = list;
2064*3d8817e4Smiod   rl.t = type;
2065*3d8817e4Smiod 
2066*3d8817e4Smiod   switch (type->kind)
2067*3d8817e4Smiod     {
2068*3d8817e4Smiod       /* The default case is just here to avoid warnings.  */
2069*3d8817e4Smiod     default:
2070*3d8817e4Smiod     case DEBUG_KIND_INDIRECT:
2071*3d8817e4Smiod       if (*type->u.kindirect->slot != NULL)
2072*3d8817e4Smiod 	return debug_get_real_type (handle, *type->u.kindirect->slot, &rl);
2073*3d8817e4Smiod       return type;
2074*3d8817e4Smiod     case DEBUG_KIND_NAMED:
2075*3d8817e4Smiod     case DEBUG_KIND_TAGGED:
2076*3d8817e4Smiod       return debug_get_real_type (handle, type->u.knamed->type, &rl);
2077*3d8817e4Smiod     }
2078*3d8817e4Smiod   /*NOTREACHED*/
2079*3d8817e4Smiod }
2080*3d8817e4Smiod 
2081*3d8817e4Smiod /* Get the kind of a type.  */
2082*3d8817e4Smiod 
2083*3d8817e4Smiod enum debug_type_kind
debug_get_type_kind(void * handle,debug_type type)2084*3d8817e4Smiod debug_get_type_kind (void *handle, debug_type type)
2085*3d8817e4Smiod {
2086*3d8817e4Smiod   if (type == NULL)
2087*3d8817e4Smiod     return DEBUG_KIND_ILLEGAL;
2088*3d8817e4Smiod   type = debug_get_real_type (handle, type, NULL);
2089*3d8817e4Smiod   if (type == NULL)
2090*3d8817e4Smiod     return DEBUG_KIND_ILLEGAL;
2091*3d8817e4Smiod   return type->kind;
2092*3d8817e4Smiod }
2093*3d8817e4Smiod 
2094*3d8817e4Smiod /* Get the name of a type.  */
2095*3d8817e4Smiod 
2096*3d8817e4Smiod const char *
debug_get_type_name(void * handle,debug_type type)2097*3d8817e4Smiod debug_get_type_name (void *handle, debug_type type)
2098*3d8817e4Smiod {
2099*3d8817e4Smiod   if (type->kind == DEBUG_KIND_INDIRECT)
2100*3d8817e4Smiod     {
2101*3d8817e4Smiod       if (*type->u.kindirect->slot != NULL)
2102*3d8817e4Smiod 	return debug_get_type_name (handle, *type->u.kindirect->slot);
2103*3d8817e4Smiod       return type->u.kindirect->tag;
2104*3d8817e4Smiod     }
2105*3d8817e4Smiod   if (type->kind == DEBUG_KIND_NAMED
2106*3d8817e4Smiod       || type->kind == DEBUG_KIND_TAGGED)
2107*3d8817e4Smiod     return type->u.knamed->name->name;
2108*3d8817e4Smiod   return NULL;
2109*3d8817e4Smiod }
2110*3d8817e4Smiod 
2111*3d8817e4Smiod /* Get the size of a type.  */
2112*3d8817e4Smiod 
2113*3d8817e4Smiod bfd_vma
debug_get_type_size(void * handle,debug_type type)2114*3d8817e4Smiod debug_get_type_size (void *handle, debug_type type)
2115*3d8817e4Smiod {
2116*3d8817e4Smiod   if (type == NULL)
2117*3d8817e4Smiod     return 0;
2118*3d8817e4Smiod 
2119*3d8817e4Smiod   /* We don't call debug_get_real_type, because somebody might have
2120*3d8817e4Smiod      called debug_record_type_size on a named or indirect type.  */
2121*3d8817e4Smiod 
2122*3d8817e4Smiod   if (type->size != 0)
2123*3d8817e4Smiod     return type->size;
2124*3d8817e4Smiod 
2125*3d8817e4Smiod   switch (type->kind)
2126*3d8817e4Smiod     {
2127*3d8817e4Smiod     default:
2128*3d8817e4Smiod       return 0;
2129*3d8817e4Smiod     case DEBUG_KIND_INDIRECT:
2130*3d8817e4Smiod       if (*type->u.kindirect->slot != NULL)
2131*3d8817e4Smiod 	return debug_get_type_size (handle, *type->u.kindirect->slot);
2132*3d8817e4Smiod       return 0;
2133*3d8817e4Smiod     case DEBUG_KIND_NAMED:
2134*3d8817e4Smiod     case DEBUG_KIND_TAGGED:
2135*3d8817e4Smiod       return debug_get_type_size (handle, type->u.knamed->type);
2136*3d8817e4Smiod     }
2137*3d8817e4Smiod   /*NOTREACHED*/
2138*3d8817e4Smiod }
2139*3d8817e4Smiod 
2140*3d8817e4Smiod /* Get the return type of a function or method type.  */
2141*3d8817e4Smiod 
2142*3d8817e4Smiod debug_type
debug_get_return_type(void * handle,debug_type type)2143*3d8817e4Smiod debug_get_return_type (void *handle, debug_type type)
2144*3d8817e4Smiod {
2145*3d8817e4Smiod   if (type == NULL)
2146*3d8817e4Smiod     return DEBUG_TYPE_NULL;
2147*3d8817e4Smiod 
2148*3d8817e4Smiod   type = debug_get_real_type (handle, type, NULL);
2149*3d8817e4Smiod   if (type == NULL)
2150*3d8817e4Smiod     return DEBUG_TYPE_NULL;
2151*3d8817e4Smiod 
2152*3d8817e4Smiod   switch (type->kind)
2153*3d8817e4Smiod     {
2154*3d8817e4Smiod     default:
2155*3d8817e4Smiod       return DEBUG_TYPE_NULL;
2156*3d8817e4Smiod     case DEBUG_KIND_FUNCTION:
2157*3d8817e4Smiod       return type->u.kfunction->return_type;
2158*3d8817e4Smiod     case DEBUG_KIND_METHOD:
2159*3d8817e4Smiod       return type->u.kmethod->return_type;
2160*3d8817e4Smiod     }
2161*3d8817e4Smiod   /*NOTREACHED*/
2162*3d8817e4Smiod }
2163*3d8817e4Smiod 
2164*3d8817e4Smiod /* Get the parameter types of a function or method type (except that
2165*3d8817e4Smiod    we don't currently store the parameter types of a function).  */
2166*3d8817e4Smiod 
2167*3d8817e4Smiod const debug_type *
debug_get_parameter_types(void * handle,debug_type type,bfd_boolean * pvarargs)2168*3d8817e4Smiod debug_get_parameter_types (void *handle, debug_type type,
2169*3d8817e4Smiod 			   bfd_boolean *pvarargs)
2170*3d8817e4Smiod {
2171*3d8817e4Smiod   if (type == NULL)
2172*3d8817e4Smiod     return NULL;
2173*3d8817e4Smiod 
2174*3d8817e4Smiod   type = debug_get_real_type (handle, type, NULL);
2175*3d8817e4Smiod   if (type == NULL)
2176*3d8817e4Smiod     return NULL;
2177*3d8817e4Smiod 
2178*3d8817e4Smiod   switch (type->kind)
2179*3d8817e4Smiod     {
2180*3d8817e4Smiod     default:
2181*3d8817e4Smiod       return NULL;
2182*3d8817e4Smiod     case DEBUG_KIND_FUNCTION:
2183*3d8817e4Smiod       *pvarargs = type->u.kfunction->varargs;
2184*3d8817e4Smiod       return type->u.kfunction->arg_types;
2185*3d8817e4Smiod     case DEBUG_KIND_METHOD:
2186*3d8817e4Smiod       *pvarargs = type->u.kmethod->varargs;
2187*3d8817e4Smiod       return type->u.kmethod->arg_types;
2188*3d8817e4Smiod     }
2189*3d8817e4Smiod   /*NOTREACHED*/
2190*3d8817e4Smiod }
2191*3d8817e4Smiod 
2192*3d8817e4Smiod /* Get the target type of a type.  */
2193*3d8817e4Smiod 
2194*3d8817e4Smiod debug_type
debug_get_target_type(void * handle,debug_type type)2195*3d8817e4Smiod debug_get_target_type (void *handle, debug_type type)
2196*3d8817e4Smiod {
2197*3d8817e4Smiod   if (type == NULL)
2198*3d8817e4Smiod     return NULL;
2199*3d8817e4Smiod 
2200*3d8817e4Smiod   type = debug_get_real_type (handle, type, NULL);
2201*3d8817e4Smiod   if (type == NULL)
2202*3d8817e4Smiod     return NULL;
2203*3d8817e4Smiod 
2204*3d8817e4Smiod   switch (type->kind)
2205*3d8817e4Smiod     {
2206*3d8817e4Smiod     default:
2207*3d8817e4Smiod       return NULL;
2208*3d8817e4Smiod     case DEBUG_KIND_POINTER:
2209*3d8817e4Smiod       return type->u.kpointer;
2210*3d8817e4Smiod     case DEBUG_KIND_REFERENCE:
2211*3d8817e4Smiod       return type->u.kreference;
2212*3d8817e4Smiod     case DEBUG_KIND_CONST:
2213*3d8817e4Smiod       return type->u.kconst;
2214*3d8817e4Smiod     case DEBUG_KIND_VOLATILE:
2215*3d8817e4Smiod       return type->u.kvolatile;
2216*3d8817e4Smiod     }
2217*3d8817e4Smiod   /*NOTREACHED*/
2218*3d8817e4Smiod }
2219*3d8817e4Smiod 
2220*3d8817e4Smiod /* Get the NULL terminated array of fields for a struct, union, or
2221*3d8817e4Smiod    class.  */
2222*3d8817e4Smiod 
2223*3d8817e4Smiod const debug_field *
debug_get_fields(void * handle,debug_type type)2224*3d8817e4Smiod debug_get_fields (void *handle, debug_type type)
2225*3d8817e4Smiod {
2226*3d8817e4Smiod   if (type == NULL)
2227*3d8817e4Smiod     return NULL;
2228*3d8817e4Smiod 
2229*3d8817e4Smiod   type = debug_get_real_type (handle, type, NULL);
2230*3d8817e4Smiod   if (type == NULL)
2231*3d8817e4Smiod     return NULL;
2232*3d8817e4Smiod 
2233*3d8817e4Smiod   switch (type->kind)
2234*3d8817e4Smiod     {
2235*3d8817e4Smiod     default:
2236*3d8817e4Smiod       return NULL;
2237*3d8817e4Smiod     case DEBUG_KIND_STRUCT:
2238*3d8817e4Smiod     case DEBUG_KIND_UNION:
2239*3d8817e4Smiod     case DEBUG_KIND_CLASS:
2240*3d8817e4Smiod     case DEBUG_KIND_UNION_CLASS:
2241*3d8817e4Smiod       return type->u.kclass->fields;
2242*3d8817e4Smiod     }
2243*3d8817e4Smiod   /*NOTREACHED*/
2244*3d8817e4Smiod }
2245*3d8817e4Smiod 
2246*3d8817e4Smiod /* Get the type of a field.  */
2247*3d8817e4Smiod 
2248*3d8817e4Smiod debug_type
debug_get_field_type(void * handle ATTRIBUTE_UNUSED,debug_field field)2249*3d8817e4Smiod debug_get_field_type (void *handle ATTRIBUTE_UNUSED, debug_field field)
2250*3d8817e4Smiod {
2251*3d8817e4Smiod   if (field == NULL)
2252*3d8817e4Smiod     return NULL;
2253*3d8817e4Smiod   return field->type;
2254*3d8817e4Smiod }
2255*3d8817e4Smiod 
2256*3d8817e4Smiod /* Get the name of a field.  */
2257*3d8817e4Smiod 
2258*3d8817e4Smiod const char *
debug_get_field_name(void * handle ATTRIBUTE_UNUSED,debug_field field)2259*3d8817e4Smiod debug_get_field_name (void *handle ATTRIBUTE_UNUSED, debug_field field)
2260*3d8817e4Smiod {
2261*3d8817e4Smiod   if (field == NULL)
2262*3d8817e4Smiod     return NULL;
2263*3d8817e4Smiod   return field->name;
2264*3d8817e4Smiod }
2265*3d8817e4Smiod 
2266*3d8817e4Smiod /* Get the bit position of a field.  */
2267*3d8817e4Smiod 
2268*3d8817e4Smiod bfd_vma
debug_get_field_bitpos(void * handle ATTRIBUTE_UNUSED,debug_field field)2269*3d8817e4Smiod debug_get_field_bitpos (void *handle ATTRIBUTE_UNUSED, debug_field field)
2270*3d8817e4Smiod {
2271*3d8817e4Smiod   if (field == NULL || field->static_member)
2272*3d8817e4Smiod     return (bfd_vma) -1;
2273*3d8817e4Smiod   return field->u.f.bitpos;
2274*3d8817e4Smiod }
2275*3d8817e4Smiod 
2276*3d8817e4Smiod /* Get the bit size of a field.  */
2277*3d8817e4Smiod 
2278*3d8817e4Smiod bfd_vma
debug_get_field_bitsize(void * handle ATTRIBUTE_UNUSED,debug_field field)2279*3d8817e4Smiod debug_get_field_bitsize (void *handle ATTRIBUTE_UNUSED, debug_field field)
2280*3d8817e4Smiod {
2281*3d8817e4Smiod   if (field == NULL || field->static_member)
2282*3d8817e4Smiod     return (bfd_vma) -1;
2283*3d8817e4Smiod   return field->u.f.bitsize;
2284*3d8817e4Smiod }
2285*3d8817e4Smiod 
2286*3d8817e4Smiod /* Get the visibility of a field.  */
2287*3d8817e4Smiod 
2288*3d8817e4Smiod enum debug_visibility
debug_get_field_visibility(void * handle ATTRIBUTE_UNUSED,debug_field field)2289*3d8817e4Smiod debug_get_field_visibility (void *handle ATTRIBUTE_UNUSED, debug_field field)
2290*3d8817e4Smiod {
2291*3d8817e4Smiod   if (field == NULL)
2292*3d8817e4Smiod     return DEBUG_VISIBILITY_IGNORE;
2293*3d8817e4Smiod   return field->visibility;
2294*3d8817e4Smiod }
2295*3d8817e4Smiod 
2296*3d8817e4Smiod /* Get the physical name of a field.  */
2297*3d8817e4Smiod 
2298*3d8817e4Smiod const char *
debug_get_field_physname(void * handle ATTRIBUTE_UNUSED,debug_field field)2299*3d8817e4Smiod debug_get_field_physname (void *handle ATTRIBUTE_UNUSED, debug_field field)
2300*3d8817e4Smiod {
2301*3d8817e4Smiod   if (field == NULL || ! field->static_member)
2302*3d8817e4Smiod     return NULL;
2303*3d8817e4Smiod   return field->u.s.physname;
2304*3d8817e4Smiod }
2305*3d8817e4Smiod 
2306*3d8817e4Smiod /* Write out the debugging information.  This is given a handle to
2307*3d8817e4Smiod    debugging information, and a set of function pointers to call.  */
2308*3d8817e4Smiod 
2309*3d8817e4Smiod bfd_boolean
debug_write(void * handle,const struct debug_write_fns * fns,void * fhandle)2310*3d8817e4Smiod debug_write (void *handle, const struct debug_write_fns *fns, void *fhandle)
2311*3d8817e4Smiod {
2312*3d8817e4Smiod   struct debug_handle *info = (struct debug_handle *) handle;
2313*3d8817e4Smiod   struct debug_unit *u;
2314*3d8817e4Smiod 
2315*3d8817e4Smiod   /* We use a mark to tell whether we have already written out a
2316*3d8817e4Smiod      particular name.  We use an integer, so that we don't have to
2317*3d8817e4Smiod      clear the mark fields if we happen to write out the same
2318*3d8817e4Smiod      information more than once.  */
2319*3d8817e4Smiod   ++info->mark;
2320*3d8817e4Smiod 
2321*3d8817e4Smiod   /* The base_id field holds an ID value which will never be used, so
2322*3d8817e4Smiod      that we can tell whether we have assigned an ID during this call
2323*3d8817e4Smiod      to debug_write.  */
2324*3d8817e4Smiod   info->base_id = info->class_id;
2325*3d8817e4Smiod 
2326*3d8817e4Smiod   /* We keep a linked list of classes for which was have assigned ID's
2327*3d8817e4Smiod      during this call to debug_write.  */
2328*3d8817e4Smiod   info->id_list = NULL;
2329*3d8817e4Smiod 
2330*3d8817e4Smiod   for (u = info->units; u != NULL; u = u->next)
2331*3d8817e4Smiod     {
2332*3d8817e4Smiod       struct debug_file *f;
2333*3d8817e4Smiod       bfd_boolean first_file;
2334*3d8817e4Smiod 
2335*3d8817e4Smiod       info->current_write_lineno = u->linenos;
2336*3d8817e4Smiod       info->current_write_lineno_index = 0;
2337*3d8817e4Smiod 
2338*3d8817e4Smiod       if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
2339*3d8817e4Smiod 	return FALSE;
2340*3d8817e4Smiod 
2341*3d8817e4Smiod       first_file = TRUE;
2342*3d8817e4Smiod       for (f = u->files; f != NULL; f = f->next)
2343*3d8817e4Smiod 	{
2344*3d8817e4Smiod 	  struct debug_name *n;
2345*3d8817e4Smiod 
2346*3d8817e4Smiod 	  if (first_file)
2347*3d8817e4Smiod 	    first_file = FALSE;
2348*3d8817e4Smiod 	  else if (! (*fns->start_source) (fhandle, f->filename))
2349*3d8817e4Smiod 	    return FALSE;
2350*3d8817e4Smiod 
2351*3d8817e4Smiod 	  if (f->globals != NULL)
2352*3d8817e4Smiod 	    for (n = f->globals->list; n != NULL; n = n->next)
2353*3d8817e4Smiod 	      if (! debug_write_name (info, fns, fhandle, n))
2354*3d8817e4Smiod 		return FALSE;
2355*3d8817e4Smiod 	}
2356*3d8817e4Smiod 
2357*3d8817e4Smiod       /* Output any line number information which hasn't already been
2358*3d8817e4Smiod          handled.  */
2359*3d8817e4Smiod       if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1))
2360*3d8817e4Smiod 	return FALSE;
2361*3d8817e4Smiod     }
2362*3d8817e4Smiod 
2363*3d8817e4Smiod   return TRUE;
2364*3d8817e4Smiod }
2365*3d8817e4Smiod 
2366*3d8817e4Smiod /* Write out an element in a namespace.  */
2367*3d8817e4Smiod 
2368*3d8817e4Smiod static bfd_boolean
debug_write_name(struct debug_handle * info,const struct debug_write_fns * fns,void * fhandle,struct debug_name * n)2369*3d8817e4Smiod debug_write_name (struct debug_handle *info,
2370*3d8817e4Smiod 		  const struct debug_write_fns *fns, void *fhandle,
2371*3d8817e4Smiod 		  struct debug_name *n)
2372*3d8817e4Smiod {
2373*3d8817e4Smiod   switch (n->kind)
2374*3d8817e4Smiod     {
2375*3d8817e4Smiod     case DEBUG_OBJECT_TYPE:
2376*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, n->u.type, n)
2377*3d8817e4Smiod 	  || ! (*fns->typdef) (fhandle, n->name))
2378*3d8817e4Smiod 	return FALSE;
2379*3d8817e4Smiod       return TRUE;
2380*3d8817e4Smiod     case DEBUG_OBJECT_TAG:
2381*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, n->u.tag, n))
2382*3d8817e4Smiod 	return FALSE;
2383*3d8817e4Smiod       return (*fns->tag) (fhandle, n->name);
2384*3d8817e4Smiod     case DEBUG_OBJECT_VARIABLE:
2385*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, n->u.variable->type,
2386*3d8817e4Smiod 			      (struct debug_name *) NULL))
2387*3d8817e4Smiod 	return FALSE;
2388*3d8817e4Smiod       return (*fns->variable) (fhandle, n->name, n->u.variable->kind,
2389*3d8817e4Smiod 			       n->u.variable->val);
2390*3d8817e4Smiod     case DEBUG_OBJECT_FUNCTION:
2391*3d8817e4Smiod       return debug_write_function (info, fns, fhandle, n->name,
2392*3d8817e4Smiod 				   n->linkage, n->u.function);
2393*3d8817e4Smiod     case DEBUG_OBJECT_INT_CONSTANT:
2394*3d8817e4Smiod       return (*fns->int_constant) (fhandle, n->name, n->u.int_constant);
2395*3d8817e4Smiod     case DEBUG_OBJECT_FLOAT_CONSTANT:
2396*3d8817e4Smiod       return (*fns->float_constant) (fhandle, n->name, n->u.float_constant);
2397*3d8817e4Smiod     case DEBUG_OBJECT_TYPED_CONSTANT:
2398*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type,
2399*3d8817e4Smiod 			      (struct debug_name *) NULL))
2400*3d8817e4Smiod 	return FALSE;
2401*3d8817e4Smiod       return (*fns->typed_constant) (fhandle, n->name,
2402*3d8817e4Smiod 				     n->u.typed_constant->val);
2403*3d8817e4Smiod     default:
2404*3d8817e4Smiod       abort ();
2405*3d8817e4Smiod       return FALSE;
2406*3d8817e4Smiod     }
2407*3d8817e4Smiod   /*NOTREACHED*/
2408*3d8817e4Smiod }
2409*3d8817e4Smiod 
2410*3d8817e4Smiod /* Write out a type.  If the type is DEBUG_KIND_NAMED or
2411*3d8817e4Smiod    DEBUG_KIND_TAGGED, then the name argument is the name for which we
2412*3d8817e4Smiod    are about to call typedef or tag.  If the type is anything else,
2413*3d8817e4Smiod    then the name argument is a tag from a DEBUG_KIND_TAGGED type which
2414*3d8817e4Smiod    points to this one.  */
2415*3d8817e4Smiod 
2416*3d8817e4Smiod static bfd_boolean
debug_write_type(struct debug_handle * info,const struct debug_write_fns * fns,void * fhandle,struct debug_type * type,struct debug_name * name)2417*3d8817e4Smiod debug_write_type (struct debug_handle *info,
2418*3d8817e4Smiod 		  const struct debug_write_fns *fns, void *fhandle,
2419*3d8817e4Smiod 		  struct debug_type *type, struct debug_name *name)
2420*3d8817e4Smiod {
2421*3d8817e4Smiod   unsigned int i;
2422*3d8817e4Smiod   int is;
2423*3d8817e4Smiod   const char *tag = NULL;
2424*3d8817e4Smiod 
2425*3d8817e4Smiod   /* If we have a name for this type, just output it.  We only output
2426*3d8817e4Smiod      typedef names after they have been defined.  We output type tags
2427*3d8817e4Smiod      whenever we are not actually defining them.  */
2428*3d8817e4Smiod   if ((type->kind == DEBUG_KIND_NAMED
2429*3d8817e4Smiod        || type->kind == DEBUG_KIND_TAGGED)
2430*3d8817e4Smiod       && (type->u.knamed->name->mark == info->mark
2431*3d8817e4Smiod 	  || (type->kind == DEBUG_KIND_TAGGED
2432*3d8817e4Smiod 	      && type->u.knamed->name != name)))
2433*3d8817e4Smiod     {
2434*3d8817e4Smiod       if (type->kind == DEBUG_KIND_NAMED)
2435*3d8817e4Smiod 	return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);
2436*3d8817e4Smiod       else
2437*3d8817e4Smiod 	{
2438*3d8817e4Smiod 	  struct debug_type *real;
2439*3d8817e4Smiod 	  unsigned int id;
2440*3d8817e4Smiod 
2441*3d8817e4Smiod 	  real = debug_get_real_type ((void *) info, type, NULL);
2442*3d8817e4Smiod 	  if (real == NULL)
2443*3d8817e4Smiod 	    return (*fns->empty_type) (fhandle);
2444*3d8817e4Smiod 	  id = 0;
2445*3d8817e4Smiod 	  if ((real->kind == DEBUG_KIND_STRUCT
2446*3d8817e4Smiod 	       || real->kind == DEBUG_KIND_UNION
2447*3d8817e4Smiod 	       || real->kind == DEBUG_KIND_CLASS
2448*3d8817e4Smiod 	       || real->kind == DEBUG_KIND_UNION_CLASS)
2449*3d8817e4Smiod 	      && real->u.kclass != NULL)
2450*3d8817e4Smiod 	    {
2451*3d8817e4Smiod 	      if (real->u.kclass->id <= info->base_id)
2452*3d8817e4Smiod 		{
2453*3d8817e4Smiod 		  if (! debug_set_class_id (info,
2454*3d8817e4Smiod 					    type->u.knamed->name->name,
2455*3d8817e4Smiod 					    real))
2456*3d8817e4Smiod 		    return FALSE;
2457*3d8817e4Smiod 		}
2458*3d8817e4Smiod 	      id = real->u.kclass->id;
2459*3d8817e4Smiod 	    }
2460*3d8817e4Smiod 
2461*3d8817e4Smiod 	  return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id,
2462*3d8817e4Smiod 				   real->kind);
2463*3d8817e4Smiod 	}
2464*3d8817e4Smiod     }
2465*3d8817e4Smiod 
2466*3d8817e4Smiod   /* Mark the name after we have already looked for a known name, so
2467*3d8817e4Smiod      that we don't just define a type in terms of itself.  We need to
2468*3d8817e4Smiod      mark the name here so that a struct containing a pointer to
2469*3d8817e4Smiod      itself will work.  */
2470*3d8817e4Smiod   if (name != NULL)
2471*3d8817e4Smiod     name->mark = info->mark;
2472*3d8817e4Smiod 
2473*3d8817e4Smiod   if (name != NULL
2474*3d8817e4Smiod       && type->kind != DEBUG_KIND_NAMED
2475*3d8817e4Smiod       && type->kind != DEBUG_KIND_TAGGED)
2476*3d8817e4Smiod     {
2477*3d8817e4Smiod       assert (name->kind == DEBUG_OBJECT_TAG);
2478*3d8817e4Smiod       tag = name->name;
2479*3d8817e4Smiod     }
2480*3d8817e4Smiod 
2481*3d8817e4Smiod   switch (type->kind)
2482*3d8817e4Smiod     {
2483*3d8817e4Smiod     case DEBUG_KIND_ILLEGAL:
2484*3d8817e4Smiod       debug_error (_("debug_write_type: illegal type encountered"));
2485*3d8817e4Smiod       return FALSE;
2486*3d8817e4Smiod     case DEBUG_KIND_INDIRECT:
2487*3d8817e4Smiod       if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
2488*3d8817e4Smiod 	return (*fns->empty_type) (fhandle);
2489*3d8817e4Smiod       return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot,
2490*3d8817e4Smiod 			       name);
2491*3d8817e4Smiod     case DEBUG_KIND_VOID:
2492*3d8817e4Smiod       return (*fns->void_type) (fhandle);
2493*3d8817e4Smiod     case DEBUG_KIND_INT:
2494*3d8817e4Smiod       return (*fns->int_type) (fhandle, type->size, type->u.kint);
2495*3d8817e4Smiod     case DEBUG_KIND_FLOAT:
2496*3d8817e4Smiod       return (*fns->float_type) (fhandle, type->size);
2497*3d8817e4Smiod     case DEBUG_KIND_COMPLEX:
2498*3d8817e4Smiod       return (*fns->complex_type) (fhandle, type->size);
2499*3d8817e4Smiod     case DEBUG_KIND_BOOL:
2500*3d8817e4Smiod       return (*fns->bool_type) (fhandle, type->size);
2501*3d8817e4Smiod     case DEBUG_KIND_STRUCT:
2502*3d8817e4Smiod     case DEBUG_KIND_UNION:
2503*3d8817e4Smiod       if (type->u.kclass != NULL)
2504*3d8817e4Smiod 	{
2505*3d8817e4Smiod 	  if (type->u.kclass->id <= info->base_id)
2506*3d8817e4Smiod 	    {
2507*3d8817e4Smiod 	      if (! debug_set_class_id (info, tag, type))
2508*3d8817e4Smiod 		return FALSE;
2509*3d8817e4Smiod 	    }
2510*3d8817e4Smiod 
2511*3d8817e4Smiod 	  if (info->mark == type->u.kclass->mark)
2512*3d8817e4Smiod 	    {
2513*3d8817e4Smiod 	      /* We are currently outputting this struct, or we have
2514*3d8817e4Smiod 		 already output it.  I don't know if this can happen,
2515*3d8817e4Smiod 		 but it can happen for a class.  */
2516*3d8817e4Smiod 	      assert (type->u.kclass->id > info->base_id);
2517*3d8817e4Smiod 	      return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
2518*3d8817e4Smiod 				       type->kind);
2519*3d8817e4Smiod 	    }
2520*3d8817e4Smiod 	  type->u.kclass->mark = info->mark;
2521*3d8817e4Smiod 	}
2522*3d8817e4Smiod 
2523*3d8817e4Smiod       if (! (*fns->start_struct_type) (fhandle, tag,
2524*3d8817e4Smiod 				       (type->u.kclass != NULL
2525*3d8817e4Smiod 					? type->u.kclass->id
2526*3d8817e4Smiod 					: 0),
2527*3d8817e4Smiod 				       type->kind == DEBUG_KIND_STRUCT,
2528*3d8817e4Smiod 				       type->size))
2529*3d8817e4Smiod 	return FALSE;
2530*3d8817e4Smiod       if (type->u.kclass != NULL
2531*3d8817e4Smiod 	  && type->u.kclass->fields != NULL)
2532*3d8817e4Smiod 	{
2533*3d8817e4Smiod 	  for (i = 0; type->u.kclass->fields[i] != NULL; i++)
2534*3d8817e4Smiod 	    {
2535*3d8817e4Smiod 	      struct debug_field *f;
2536*3d8817e4Smiod 
2537*3d8817e4Smiod 	      f = type->u.kclass->fields[i];
2538*3d8817e4Smiod 	      if (! debug_write_type (info, fns, fhandle, f->type,
2539*3d8817e4Smiod 				      (struct debug_name *) NULL)
2540*3d8817e4Smiod 		  || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
2541*3d8817e4Smiod 					     f->u.f.bitsize, f->visibility))
2542*3d8817e4Smiod 		return FALSE;
2543*3d8817e4Smiod 	    }
2544*3d8817e4Smiod 	}
2545*3d8817e4Smiod       return (*fns->end_struct_type) (fhandle);
2546*3d8817e4Smiod     case DEBUG_KIND_CLASS:
2547*3d8817e4Smiod     case DEBUG_KIND_UNION_CLASS:
2548*3d8817e4Smiod       return debug_write_class_type (info, fns, fhandle, type, tag);
2549*3d8817e4Smiod     case DEBUG_KIND_ENUM:
2550*3d8817e4Smiod       if (type->u.kenum == NULL)
2551*3d8817e4Smiod 	return (*fns->enum_type) (fhandle, tag, (const char **) NULL,
2552*3d8817e4Smiod 				  (bfd_signed_vma *) NULL);
2553*3d8817e4Smiod       return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
2554*3d8817e4Smiod 				type->u.kenum->values);
2555*3d8817e4Smiod     case DEBUG_KIND_POINTER:
2556*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
2557*3d8817e4Smiod 			      (struct debug_name *) NULL))
2558*3d8817e4Smiod 	return FALSE;
2559*3d8817e4Smiod       return (*fns->pointer_type) (fhandle);
2560*3d8817e4Smiod     case DEBUG_KIND_FUNCTION:
2561*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle,
2562*3d8817e4Smiod 			      type->u.kfunction->return_type,
2563*3d8817e4Smiod 			      (struct debug_name *) NULL))
2564*3d8817e4Smiod 	return FALSE;
2565*3d8817e4Smiod       if (type->u.kfunction->arg_types == NULL)
2566*3d8817e4Smiod 	is = -1;
2567*3d8817e4Smiod       else
2568*3d8817e4Smiod 	{
2569*3d8817e4Smiod 	  for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++)
2570*3d8817e4Smiod 	    if (! debug_write_type (info, fns, fhandle,
2571*3d8817e4Smiod 				    type->u.kfunction->arg_types[is],
2572*3d8817e4Smiod 				    (struct debug_name *) NULL))
2573*3d8817e4Smiod 	      return FALSE;
2574*3d8817e4Smiod 	}
2575*3d8817e4Smiod       return (*fns->function_type) (fhandle, is,
2576*3d8817e4Smiod 				    type->u.kfunction->varargs);
2577*3d8817e4Smiod     case DEBUG_KIND_REFERENCE:
2578*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.kreference,
2579*3d8817e4Smiod 			      (struct debug_name *) NULL))
2580*3d8817e4Smiod 	return FALSE;
2581*3d8817e4Smiod       return (*fns->reference_type) (fhandle);
2582*3d8817e4Smiod     case DEBUG_KIND_RANGE:
2583*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.krange->type,
2584*3d8817e4Smiod 			      (struct debug_name *) NULL))
2585*3d8817e4Smiod 	return FALSE;
2586*3d8817e4Smiod       return (*fns->range_type) (fhandle, type->u.krange->lower,
2587*3d8817e4Smiod 				 type->u.krange->upper);
2588*3d8817e4Smiod     case DEBUG_KIND_ARRAY:
2589*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type,
2590*3d8817e4Smiod 			      (struct debug_name *) NULL)
2591*3d8817e4Smiod 	  || ! debug_write_type (info, fns, fhandle,
2592*3d8817e4Smiod 				 type->u.karray->range_type,
2593*3d8817e4Smiod 				 (struct debug_name *) NULL))
2594*3d8817e4Smiod 	return FALSE;
2595*3d8817e4Smiod       return (*fns->array_type) (fhandle, type->u.karray->lower,
2596*3d8817e4Smiod 				 type->u.karray->upper,
2597*3d8817e4Smiod 				 type->u.karray->stringp);
2598*3d8817e4Smiod     case DEBUG_KIND_SET:
2599*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.kset->type,
2600*3d8817e4Smiod 			      (struct debug_name *) NULL))
2601*3d8817e4Smiod 	return FALSE;
2602*3d8817e4Smiod       return (*fns->set_type) (fhandle, type->u.kset->bitstringp);
2603*3d8817e4Smiod     case DEBUG_KIND_OFFSET:
2604*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type,
2605*3d8817e4Smiod 			      (struct debug_name *) NULL)
2606*3d8817e4Smiod 	  || ! debug_write_type (info, fns, fhandle,
2607*3d8817e4Smiod 				 type->u.koffset->target_type,
2608*3d8817e4Smiod 				 (struct debug_name *) NULL))
2609*3d8817e4Smiod 	return FALSE;
2610*3d8817e4Smiod       return (*fns->offset_type) (fhandle);
2611*3d8817e4Smiod     case DEBUG_KIND_METHOD:
2612*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle,
2613*3d8817e4Smiod 			      type->u.kmethod->return_type,
2614*3d8817e4Smiod 			      (struct debug_name *) NULL))
2615*3d8817e4Smiod 	return FALSE;
2616*3d8817e4Smiod       if (type->u.kmethod->arg_types == NULL)
2617*3d8817e4Smiod 	is = -1;
2618*3d8817e4Smiod       else
2619*3d8817e4Smiod 	{
2620*3d8817e4Smiod 	  for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++)
2621*3d8817e4Smiod 	    if (! debug_write_type (info, fns, fhandle,
2622*3d8817e4Smiod 				    type->u.kmethod->arg_types[is],
2623*3d8817e4Smiod 				    (struct debug_name *) NULL))
2624*3d8817e4Smiod 	      return FALSE;
2625*3d8817e4Smiod 	}
2626*3d8817e4Smiod       if (type->u.kmethod->domain_type != NULL)
2627*3d8817e4Smiod 	{
2628*3d8817e4Smiod 	  if (! debug_write_type (info, fns, fhandle,
2629*3d8817e4Smiod 				  type->u.kmethod->domain_type,
2630*3d8817e4Smiod 				  (struct debug_name *) NULL))
2631*3d8817e4Smiod 	    return FALSE;
2632*3d8817e4Smiod 	}
2633*3d8817e4Smiod       return (*fns->method_type) (fhandle,
2634*3d8817e4Smiod 				  type->u.kmethod->domain_type != NULL,
2635*3d8817e4Smiod 				  is,
2636*3d8817e4Smiod 				  type->u.kmethod->varargs);
2637*3d8817e4Smiod     case DEBUG_KIND_CONST:
2638*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.kconst,
2639*3d8817e4Smiod 			      (struct debug_name *) NULL))
2640*3d8817e4Smiod 	return FALSE;
2641*3d8817e4Smiod       return (*fns->const_type) (fhandle);
2642*3d8817e4Smiod     case DEBUG_KIND_VOLATILE:
2643*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, type->u.kvolatile,
2644*3d8817e4Smiod 			      (struct debug_name *) NULL))
2645*3d8817e4Smiod 	return FALSE;
2646*3d8817e4Smiod       return (*fns->volatile_type) (fhandle);
2647*3d8817e4Smiod     case DEBUG_KIND_NAMED:
2648*3d8817e4Smiod       return debug_write_type (info, fns, fhandle, type->u.knamed->type,
2649*3d8817e4Smiod 			       (struct debug_name *) NULL);
2650*3d8817e4Smiod     case DEBUG_KIND_TAGGED:
2651*3d8817e4Smiod       return debug_write_type (info, fns, fhandle, type->u.knamed->type,
2652*3d8817e4Smiod 			       type->u.knamed->name);
2653*3d8817e4Smiod     default:
2654*3d8817e4Smiod       abort ();
2655*3d8817e4Smiod       return FALSE;
2656*3d8817e4Smiod     }
2657*3d8817e4Smiod }
2658*3d8817e4Smiod 
2659*3d8817e4Smiod /* Write out a class type.  */
2660*3d8817e4Smiod 
2661*3d8817e4Smiod static bfd_boolean
debug_write_class_type(struct debug_handle * info,const struct debug_write_fns * fns,void * fhandle,struct debug_type * type,const char * tag)2662*3d8817e4Smiod debug_write_class_type (struct debug_handle *info,
2663*3d8817e4Smiod 			const struct debug_write_fns *fns, void *fhandle,
2664*3d8817e4Smiod 			struct debug_type *type, const char *tag)
2665*3d8817e4Smiod {
2666*3d8817e4Smiod   unsigned int i;
2667*3d8817e4Smiod   unsigned int id;
2668*3d8817e4Smiod   struct debug_type *vptrbase;
2669*3d8817e4Smiod 
2670*3d8817e4Smiod   if (type->u.kclass == NULL)
2671*3d8817e4Smiod     {
2672*3d8817e4Smiod       id = 0;
2673*3d8817e4Smiod       vptrbase = NULL;
2674*3d8817e4Smiod     }
2675*3d8817e4Smiod   else
2676*3d8817e4Smiod     {
2677*3d8817e4Smiod       if (type->u.kclass->id <= info->base_id)
2678*3d8817e4Smiod 	{
2679*3d8817e4Smiod 	  if (! debug_set_class_id (info, tag, type))
2680*3d8817e4Smiod 	    return FALSE;
2681*3d8817e4Smiod 	}
2682*3d8817e4Smiod 
2683*3d8817e4Smiod       if (info->mark == type->u.kclass->mark)
2684*3d8817e4Smiod 	{
2685*3d8817e4Smiod 	  /* We are currently outputting this class, or we have
2686*3d8817e4Smiod 	     already output it.  This can happen when there are
2687*3d8817e4Smiod 	     methods for an anonymous class.  */
2688*3d8817e4Smiod 	  assert (type->u.kclass->id > info->base_id);
2689*3d8817e4Smiod 	  return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
2690*3d8817e4Smiod 				   type->kind);
2691*3d8817e4Smiod 	}
2692*3d8817e4Smiod       type->u.kclass->mark = info->mark;
2693*3d8817e4Smiod       id = type->u.kclass->id;
2694*3d8817e4Smiod 
2695*3d8817e4Smiod       vptrbase = type->u.kclass->vptrbase;
2696*3d8817e4Smiod       if (vptrbase != NULL && vptrbase != type)
2697*3d8817e4Smiod 	{
2698*3d8817e4Smiod 	  if (! debug_write_type (info, fns, fhandle, vptrbase,
2699*3d8817e4Smiod 				  (struct debug_name *) NULL))
2700*3d8817e4Smiod 	    return FALSE;
2701*3d8817e4Smiod 	}
2702*3d8817e4Smiod     }
2703*3d8817e4Smiod 
2704*3d8817e4Smiod   if (! (*fns->start_class_type) (fhandle, tag, id,
2705*3d8817e4Smiod 				  type->kind == DEBUG_KIND_CLASS,
2706*3d8817e4Smiod 				  type->size,
2707*3d8817e4Smiod 				  vptrbase != NULL,
2708*3d8817e4Smiod 				  vptrbase == type))
2709*3d8817e4Smiod     return FALSE;
2710*3d8817e4Smiod 
2711*3d8817e4Smiod   if (type->u.kclass != NULL)
2712*3d8817e4Smiod     {
2713*3d8817e4Smiod       if (type->u.kclass->fields != NULL)
2714*3d8817e4Smiod 	{
2715*3d8817e4Smiod 	  for (i = 0; type->u.kclass->fields[i] != NULL; i++)
2716*3d8817e4Smiod 	    {
2717*3d8817e4Smiod 	      struct debug_field *f;
2718*3d8817e4Smiod 
2719*3d8817e4Smiod 	      f = type->u.kclass->fields[i];
2720*3d8817e4Smiod 	      if (! debug_write_type (info, fns, fhandle, f->type,
2721*3d8817e4Smiod 				      (struct debug_name *) NULL))
2722*3d8817e4Smiod 		return FALSE;
2723*3d8817e4Smiod 	      if (f->static_member)
2724*3d8817e4Smiod 		{
2725*3d8817e4Smiod 		  if (! (*fns->class_static_member) (fhandle, f->name,
2726*3d8817e4Smiod 						     f->u.s.physname,
2727*3d8817e4Smiod 						     f->visibility))
2728*3d8817e4Smiod 		    return FALSE;
2729*3d8817e4Smiod 		}
2730*3d8817e4Smiod 	      else
2731*3d8817e4Smiod 		{
2732*3d8817e4Smiod 		  if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
2733*3d8817e4Smiod 					      f->u.f.bitsize, f->visibility))
2734*3d8817e4Smiod 		    return FALSE;
2735*3d8817e4Smiod 		}
2736*3d8817e4Smiod 	    }
2737*3d8817e4Smiod 	}
2738*3d8817e4Smiod 
2739*3d8817e4Smiod       if (type->u.kclass->baseclasses != NULL)
2740*3d8817e4Smiod 	{
2741*3d8817e4Smiod 	  for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
2742*3d8817e4Smiod 	    {
2743*3d8817e4Smiod 	      struct debug_baseclass *b;
2744*3d8817e4Smiod 
2745*3d8817e4Smiod 	      b = type->u.kclass->baseclasses[i];
2746*3d8817e4Smiod 	      if (! debug_write_type (info, fns, fhandle, b->type,
2747*3d8817e4Smiod 				      (struct debug_name *) NULL))
2748*3d8817e4Smiod 		return FALSE;
2749*3d8817e4Smiod 	      if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
2750*3d8817e4Smiod 					     b->visibility))
2751*3d8817e4Smiod 		return FALSE;
2752*3d8817e4Smiod 	    }
2753*3d8817e4Smiod 	}
2754*3d8817e4Smiod 
2755*3d8817e4Smiod       if (type->u.kclass->methods != NULL)
2756*3d8817e4Smiod 	{
2757*3d8817e4Smiod 	  for (i = 0; type->u.kclass->methods[i] != NULL; i++)
2758*3d8817e4Smiod 	    {
2759*3d8817e4Smiod 	      struct debug_method *m;
2760*3d8817e4Smiod 	      unsigned int j;
2761*3d8817e4Smiod 
2762*3d8817e4Smiod 	      m = type->u.kclass->methods[i];
2763*3d8817e4Smiod 	      if (! (*fns->class_start_method) (fhandle, m->name))
2764*3d8817e4Smiod 		return FALSE;
2765*3d8817e4Smiod 	      for (j = 0; m->variants[j] != NULL; j++)
2766*3d8817e4Smiod 		{
2767*3d8817e4Smiod 		  struct debug_method_variant *v;
2768*3d8817e4Smiod 
2769*3d8817e4Smiod 		  v = m->variants[j];
2770*3d8817e4Smiod 		  if (v->context != NULL)
2771*3d8817e4Smiod 		    {
2772*3d8817e4Smiod 		      if (! debug_write_type (info, fns, fhandle, v->context,
2773*3d8817e4Smiod 					      (struct debug_name *) NULL))
2774*3d8817e4Smiod 			return FALSE;
2775*3d8817e4Smiod 		    }
2776*3d8817e4Smiod 		  if (! debug_write_type (info, fns, fhandle, v->type,
2777*3d8817e4Smiod 					  (struct debug_name *) NULL))
2778*3d8817e4Smiod 		    return FALSE;
2779*3d8817e4Smiod 		  if (v->voffset != VOFFSET_STATIC_METHOD)
2780*3d8817e4Smiod 		    {
2781*3d8817e4Smiod 		      if (! (*fns->class_method_variant) (fhandle, v->physname,
2782*3d8817e4Smiod 							  v->visibility,
2783*3d8817e4Smiod 							  v->constp,
2784*3d8817e4Smiod 							  v->volatilep,
2785*3d8817e4Smiod 							  v->voffset,
2786*3d8817e4Smiod 							  v->context != NULL))
2787*3d8817e4Smiod 			return FALSE;
2788*3d8817e4Smiod 		    }
2789*3d8817e4Smiod 		  else
2790*3d8817e4Smiod 		    {
2791*3d8817e4Smiod 		      if (! (*fns->class_static_method_variant) (fhandle,
2792*3d8817e4Smiod 								 v->physname,
2793*3d8817e4Smiod 								 v->visibility,
2794*3d8817e4Smiod 								 v->constp,
2795*3d8817e4Smiod 								 v->volatilep))
2796*3d8817e4Smiod 			return FALSE;
2797*3d8817e4Smiod 		    }
2798*3d8817e4Smiod 		}
2799*3d8817e4Smiod 	      if (! (*fns->class_end_method) (fhandle))
2800*3d8817e4Smiod 		return FALSE;
2801*3d8817e4Smiod 	    }
2802*3d8817e4Smiod 	}
2803*3d8817e4Smiod     }
2804*3d8817e4Smiod 
2805*3d8817e4Smiod   return (*fns->end_class_type) (fhandle);
2806*3d8817e4Smiod }
2807*3d8817e4Smiod 
2808*3d8817e4Smiod /* Write out information for a function.  */
2809*3d8817e4Smiod 
2810*3d8817e4Smiod static bfd_boolean
debug_write_function(struct debug_handle * info,const struct debug_write_fns * fns,void * fhandle,const char * name,enum debug_object_linkage linkage,struct debug_function * function)2811*3d8817e4Smiod debug_write_function (struct debug_handle *info,
2812*3d8817e4Smiod 		      const struct debug_write_fns *fns, void *fhandle,
2813*3d8817e4Smiod 		      const char *name, enum debug_object_linkage linkage,
2814*3d8817e4Smiod 		      struct debug_function *function)
2815*3d8817e4Smiod {
2816*3d8817e4Smiod   struct debug_parameter *p;
2817*3d8817e4Smiod   struct debug_block *b;
2818*3d8817e4Smiod 
2819*3d8817e4Smiod   if (! debug_write_linenos (info, fns, fhandle, function->blocks->start))
2820*3d8817e4Smiod     return FALSE;
2821*3d8817e4Smiod 
2822*3d8817e4Smiod   if (! debug_write_type (info, fns, fhandle, function->return_type,
2823*3d8817e4Smiod 			  (struct debug_name *) NULL))
2824*3d8817e4Smiod     return FALSE;
2825*3d8817e4Smiod 
2826*3d8817e4Smiod   if (! (*fns->start_function) (fhandle, name,
2827*3d8817e4Smiod 				linkage == DEBUG_LINKAGE_GLOBAL))
2828*3d8817e4Smiod     return FALSE;
2829*3d8817e4Smiod 
2830*3d8817e4Smiod   for (p = function->parameters; p != NULL; p = p->next)
2831*3d8817e4Smiod     {
2832*3d8817e4Smiod       if (! debug_write_type (info, fns, fhandle, p->type,
2833*3d8817e4Smiod 			      (struct debug_name *) NULL)
2834*3d8817e4Smiod 	  || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val))
2835*3d8817e4Smiod 	return FALSE;
2836*3d8817e4Smiod     }
2837*3d8817e4Smiod 
2838*3d8817e4Smiod   for (b = function->blocks; b != NULL; b = b->next)
2839*3d8817e4Smiod     {
2840*3d8817e4Smiod       if (! debug_write_block (info, fns, fhandle, b))
2841*3d8817e4Smiod 	return FALSE;
2842*3d8817e4Smiod     }
2843*3d8817e4Smiod 
2844*3d8817e4Smiod   return (*fns->end_function) (fhandle);
2845*3d8817e4Smiod }
2846*3d8817e4Smiod 
2847*3d8817e4Smiod /* Write out information for a block.  */
2848*3d8817e4Smiod 
2849*3d8817e4Smiod static bfd_boolean
debug_write_block(struct debug_handle * info,const struct debug_write_fns * fns,void * fhandle,struct debug_block * block)2850*3d8817e4Smiod debug_write_block (struct debug_handle *info,
2851*3d8817e4Smiod 		   const struct debug_write_fns *fns, void *fhandle,
2852*3d8817e4Smiod 		   struct debug_block *block)
2853*3d8817e4Smiod {
2854*3d8817e4Smiod   struct debug_name *n;
2855*3d8817e4Smiod   struct debug_block *b;
2856*3d8817e4Smiod 
2857*3d8817e4Smiod   if (! debug_write_linenos (info, fns, fhandle, block->start))
2858*3d8817e4Smiod     return FALSE;
2859*3d8817e4Smiod 
2860*3d8817e4Smiod   /* I can't see any point to writing out a block with no local
2861*3d8817e4Smiod      variables, so we don't bother, except for the top level block.  */
2862*3d8817e4Smiod   if (block->locals != NULL || block->parent == NULL)
2863*3d8817e4Smiod     {
2864*3d8817e4Smiod       if (! (*fns->start_block) (fhandle, block->start))
2865*3d8817e4Smiod 	return FALSE;
2866*3d8817e4Smiod     }
2867*3d8817e4Smiod 
2868*3d8817e4Smiod   if (block->locals != NULL)
2869*3d8817e4Smiod     {
2870*3d8817e4Smiod       for (n = block->locals->list; n != NULL; n = n->next)
2871*3d8817e4Smiod 	{
2872*3d8817e4Smiod 	  if (! debug_write_name (info, fns, fhandle, n))
2873*3d8817e4Smiod 	    return FALSE;
2874*3d8817e4Smiod 	}
2875*3d8817e4Smiod     }
2876*3d8817e4Smiod 
2877*3d8817e4Smiod   for (b = block->children; b != NULL; b = b->next)
2878*3d8817e4Smiod     {
2879*3d8817e4Smiod       if (! debug_write_block (info, fns, fhandle, b))
2880*3d8817e4Smiod 	return FALSE;
2881*3d8817e4Smiod     }
2882*3d8817e4Smiod 
2883*3d8817e4Smiod   if (! debug_write_linenos (info, fns, fhandle, block->end))
2884*3d8817e4Smiod     return FALSE;
2885*3d8817e4Smiod 
2886*3d8817e4Smiod   if (block->locals != NULL || block->parent == NULL)
2887*3d8817e4Smiod     {
2888*3d8817e4Smiod       if (! (*fns->end_block) (fhandle, block->end))
2889*3d8817e4Smiod 	return FALSE;
2890*3d8817e4Smiod     }
2891*3d8817e4Smiod 
2892*3d8817e4Smiod   return TRUE;
2893*3d8817e4Smiod }
2894*3d8817e4Smiod 
2895*3d8817e4Smiod /* Write out line number information up to ADDRESS.  */
2896*3d8817e4Smiod 
2897*3d8817e4Smiod static bfd_boolean
debug_write_linenos(struct debug_handle * info,const struct debug_write_fns * fns,void * fhandle,bfd_vma address)2898*3d8817e4Smiod debug_write_linenos (struct debug_handle *info,
2899*3d8817e4Smiod 		     const struct debug_write_fns *fns, void *fhandle,
2900*3d8817e4Smiod 		     bfd_vma address)
2901*3d8817e4Smiod {
2902*3d8817e4Smiod   while (info->current_write_lineno != NULL)
2903*3d8817e4Smiod     {
2904*3d8817e4Smiod       struct debug_lineno *l;
2905*3d8817e4Smiod 
2906*3d8817e4Smiod       l = info->current_write_lineno;
2907*3d8817e4Smiod 
2908*3d8817e4Smiod       while (info->current_write_lineno_index < DEBUG_LINENO_COUNT)
2909*3d8817e4Smiod 	{
2910*3d8817e4Smiod 	  if (l->linenos[info->current_write_lineno_index]
2911*3d8817e4Smiod 	      == (unsigned long) -1)
2912*3d8817e4Smiod 	    break;
2913*3d8817e4Smiod 
2914*3d8817e4Smiod 	  if (l->addrs[info->current_write_lineno_index] >= address)
2915*3d8817e4Smiod 	    return TRUE;
2916*3d8817e4Smiod 
2917*3d8817e4Smiod 	  if (! (*fns->lineno) (fhandle, l->file->filename,
2918*3d8817e4Smiod 				l->linenos[info->current_write_lineno_index],
2919*3d8817e4Smiod 				l->addrs[info->current_write_lineno_index]))
2920*3d8817e4Smiod 	    return FALSE;
2921*3d8817e4Smiod 
2922*3d8817e4Smiod 	  ++info->current_write_lineno_index;
2923*3d8817e4Smiod 	}
2924*3d8817e4Smiod 
2925*3d8817e4Smiod       info->current_write_lineno = l->next;
2926*3d8817e4Smiod       info->current_write_lineno_index = 0;
2927*3d8817e4Smiod     }
2928*3d8817e4Smiod 
2929*3d8817e4Smiod   return TRUE;
2930*3d8817e4Smiod }
2931*3d8817e4Smiod 
2932*3d8817e4Smiod /* Get the ID number for a class.  If during the same call to
2933*3d8817e4Smiod    debug_write we find a struct with the same definition with the same
2934*3d8817e4Smiod    name, we use the same ID.  This type of things happens because the
2935*3d8817e4Smiod    same struct will be defined by multiple compilation units.  */
2936*3d8817e4Smiod 
2937*3d8817e4Smiod static bfd_boolean
debug_set_class_id(struct debug_handle * info,const char * tag,struct debug_type * type)2938*3d8817e4Smiod debug_set_class_id (struct debug_handle *info, const char *tag,
2939*3d8817e4Smiod 		    struct debug_type *type)
2940*3d8817e4Smiod {
2941*3d8817e4Smiod   struct debug_class_type *c;
2942*3d8817e4Smiod   struct debug_class_id *l;
2943*3d8817e4Smiod 
2944*3d8817e4Smiod   assert (type->kind == DEBUG_KIND_STRUCT
2945*3d8817e4Smiod 	  || type->kind == DEBUG_KIND_UNION
2946*3d8817e4Smiod 	  || type->kind == DEBUG_KIND_CLASS
2947*3d8817e4Smiod 	  || type->kind == DEBUG_KIND_UNION_CLASS);
2948*3d8817e4Smiod 
2949*3d8817e4Smiod   c = type->u.kclass;
2950*3d8817e4Smiod 
2951*3d8817e4Smiod   if (c->id > info->base_id)
2952*3d8817e4Smiod     return TRUE;
2953*3d8817e4Smiod 
2954*3d8817e4Smiod   for (l = info->id_list; l != NULL; l = l->next)
2955*3d8817e4Smiod     {
2956*3d8817e4Smiod       if (l->type->kind != type->kind)
2957*3d8817e4Smiod 	continue;
2958*3d8817e4Smiod 
2959*3d8817e4Smiod       if (tag == NULL)
2960*3d8817e4Smiod 	{
2961*3d8817e4Smiod 	  if (l->tag != NULL)
2962*3d8817e4Smiod 	    continue;
2963*3d8817e4Smiod 	}
2964*3d8817e4Smiod       else
2965*3d8817e4Smiod 	{
2966*3d8817e4Smiod 	  if (l->tag == NULL
2967*3d8817e4Smiod 	      || l->tag[0] != tag[0]
2968*3d8817e4Smiod 	      || strcmp (l->tag, tag) != 0)
2969*3d8817e4Smiod 	    continue;
2970*3d8817e4Smiod 	}
2971*3d8817e4Smiod 
2972*3d8817e4Smiod       if (debug_type_samep (info, l->type, type))
2973*3d8817e4Smiod 	{
2974*3d8817e4Smiod 	  c->id = l->type->u.kclass->id;
2975*3d8817e4Smiod 	  return TRUE;
2976*3d8817e4Smiod 	}
2977*3d8817e4Smiod     }
2978*3d8817e4Smiod 
2979*3d8817e4Smiod   /* There are no identical types.  Use a new ID, and add it to the
2980*3d8817e4Smiod      list.  */
2981*3d8817e4Smiod   ++info->class_id;
2982*3d8817e4Smiod   c->id = info->class_id;
2983*3d8817e4Smiod 
2984*3d8817e4Smiod   l = (struct debug_class_id *) xmalloc (sizeof *l);
2985*3d8817e4Smiod   memset (l, 0, sizeof *l);
2986*3d8817e4Smiod 
2987*3d8817e4Smiod   l->type = type;
2988*3d8817e4Smiod   l->tag = tag;
2989*3d8817e4Smiod 
2990*3d8817e4Smiod   l->next = info->id_list;
2991*3d8817e4Smiod   info->id_list = l;
2992*3d8817e4Smiod 
2993*3d8817e4Smiod   return TRUE;
2994*3d8817e4Smiod }
2995*3d8817e4Smiod 
2996*3d8817e4Smiod /* See if two types are the same.  At this point, we don't care about
2997*3d8817e4Smiod    tags and the like.  */
2998*3d8817e4Smiod 
2999*3d8817e4Smiod static bfd_boolean
debug_type_samep(struct debug_handle * info,struct debug_type * t1,struct debug_type * t2)3000*3d8817e4Smiod debug_type_samep (struct debug_handle *info, struct debug_type *t1,
3001*3d8817e4Smiod 		  struct debug_type *t2)
3002*3d8817e4Smiod {
3003*3d8817e4Smiod   struct debug_type_compare_list *l;
3004*3d8817e4Smiod   struct debug_type_compare_list top;
3005*3d8817e4Smiod   bfd_boolean ret;
3006*3d8817e4Smiod 
3007*3d8817e4Smiod   if (t1 == NULL)
3008*3d8817e4Smiod     return t2 == NULL;
3009*3d8817e4Smiod   if (t2 == NULL)
3010*3d8817e4Smiod     return FALSE;
3011*3d8817e4Smiod 
3012*3d8817e4Smiod   while (t1->kind == DEBUG_KIND_INDIRECT)
3013*3d8817e4Smiod     {
3014*3d8817e4Smiod       t1 = *t1->u.kindirect->slot;
3015*3d8817e4Smiod       if (t1 == NULL)
3016*3d8817e4Smiod 	return FALSE;
3017*3d8817e4Smiod     }
3018*3d8817e4Smiod   while (t2->kind == DEBUG_KIND_INDIRECT)
3019*3d8817e4Smiod     {
3020*3d8817e4Smiod       t2 = *t2->u.kindirect->slot;
3021*3d8817e4Smiod       if (t2 == NULL)
3022*3d8817e4Smiod 	return FALSE;
3023*3d8817e4Smiod     }
3024*3d8817e4Smiod 
3025*3d8817e4Smiod   if (t1 == t2)
3026*3d8817e4Smiod     return TRUE;
3027*3d8817e4Smiod 
3028*3d8817e4Smiod   /* As a special case, permit a typedef to match a tag, since C++
3029*3d8817e4Smiod      debugging output will sometimes add a typedef where C debugging
3030*3d8817e4Smiod      output will not.  */
3031*3d8817e4Smiod   if (t1->kind == DEBUG_KIND_NAMED
3032*3d8817e4Smiod       && t2->kind == DEBUG_KIND_TAGGED)
3033*3d8817e4Smiod     return debug_type_samep (info, t1->u.knamed->type, t2);
3034*3d8817e4Smiod   else if (t1->kind == DEBUG_KIND_TAGGED
3035*3d8817e4Smiod 	   && t2->kind == DEBUG_KIND_NAMED)
3036*3d8817e4Smiod     return debug_type_samep (info, t1, t2->u.knamed->type);
3037*3d8817e4Smiod 
3038*3d8817e4Smiod   if (t1->kind != t2->kind
3039*3d8817e4Smiod       || t1->size != t2->size)
3040*3d8817e4Smiod     return FALSE;
3041*3d8817e4Smiod 
3042*3d8817e4Smiod   /* Get rid of the trivial cases first.  */
3043*3d8817e4Smiod   switch (t1->kind)
3044*3d8817e4Smiod     {
3045*3d8817e4Smiod     default:
3046*3d8817e4Smiod       break;
3047*3d8817e4Smiod     case DEBUG_KIND_VOID:
3048*3d8817e4Smiod     case DEBUG_KIND_FLOAT:
3049*3d8817e4Smiod     case DEBUG_KIND_COMPLEX:
3050*3d8817e4Smiod     case DEBUG_KIND_BOOL:
3051*3d8817e4Smiod       return TRUE;
3052*3d8817e4Smiod     case DEBUG_KIND_INT:
3053*3d8817e4Smiod       return t1->u.kint == t2->u.kint;
3054*3d8817e4Smiod     }
3055*3d8817e4Smiod 
3056*3d8817e4Smiod   /* We have to avoid an infinite recursion.  We do this by keeping a
3057*3d8817e4Smiod      list of types which we are comparing.  We just keep the list on
3058*3d8817e4Smiod      the stack.  If we encounter a pair of types we are currently
3059*3d8817e4Smiod      comparing, we just assume that they are equal.  */
3060*3d8817e4Smiod   for (l = info->compare_list; l != NULL; l = l->next)
3061*3d8817e4Smiod     {
3062*3d8817e4Smiod       if (l->t1 == t1 && l->t2 == t2)
3063*3d8817e4Smiod 	return TRUE;
3064*3d8817e4Smiod     }
3065*3d8817e4Smiod 
3066*3d8817e4Smiod   top.t1 = t1;
3067*3d8817e4Smiod   top.t2 = t2;
3068*3d8817e4Smiod   top.next = info->compare_list;
3069*3d8817e4Smiod   info->compare_list = &top;
3070*3d8817e4Smiod 
3071*3d8817e4Smiod   switch (t1->kind)
3072*3d8817e4Smiod     {
3073*3d8817e4Smiod     default:
3074*3d8817e4Smiod       abort ();
3075*3d8817e4Smiod       ret = FALSE;
3076*3d8817e4Smiod       break;
3077*3d8817e4Smiod 
3078*3d8817e4Smiod     case DEBUG_KIND_STRUCT:
3079*3d8817e4Smiod     case DEBUG_KIND_UNION:
3080*3d8817e4Smiod     case DEBUG_KIND_CLASS:
3081*3d8817e4Smiod     case DEBUG_KIND_UNION_CLASS:
3082*3d8817e4Smiod       if (t1->u.kclass == NULL)
3083*3d8817e4Smiod 	ret = t2->u.kclass == NULL;
3084*3d8817e4Smiod       else if (t2->u.kclass == NULL)
3085*3d8817e4Smiod 	ret = FALSE;
3086*3d8817e4Smiod       else if (t1->u.kclass->id > info->base_id
3087*3d8817e4Smiod 	       && t1->u.kclass->id == t2->u.kclass->id)
3088*3d8817e4Smiod 	ret = TRUE;
3089*3d8817e4Smiod       else
3090*3d8817e4Smiod 	ret = debug_class_type_samep (info, t1, t2);
3091*3d8817e4Smiod       break;
3092*3d8817e4Smiod 
3093*3d8817e4Smiod     case DEBUG_KIND_ENUM:
3094*3d8817e4Smiod       if (t1->u.kenum == NULL)
3095*3d8817e4Smiod 	ret = t2->u.kenum == NULL;
3096*3d8817e4Smiod       else if (t2->u.kenum == NULL)
3097*3d8817e4Smiod 	ret = FALSE;
3098*3d8817e4Smiod       else
3099*3d8817e4Smiod 	{
3100*3d8817e4Smiod 	  const char **pn1, **pn2;
3101*3d8817e4Smiod 	  bfd_signed_vma *pv1, *pv2;
3102*3d8817e4Smiod 
3103*3d8817e4Smiod 	  pn1 = t1->u.kenum->names;
3104*3d8817e4Smiod 	  pn2 = t2->u.kenum->names;
3105*3d8817e4Smiod 	  pv1 = t1->u.kenum->values;
3106*3d8817e4Smiod 	  pv2 = t2->u.kenum->values;
3107*3d8817e4Smiod 	  while (*pn1 != NULL && *pn2 != NULL)
3108*3d8817e4Smiod 	    {
3109*3d8817e4Smiod 	      if (**pn1 != **pn2
3110*3d8817e4Smiod 		  || *pv1 != *pv2
3111*3d8817e4Smiod 		  || strcmp (*pn1, *pn2) != 0)
3112*3d8817e4Smiod 		break;
3113*3d8817e4Smiod 	      ++pn1;
3114*3d8817e4Smiod 	      ++pn2;
3115*3d8817e4Smiod 	      ++pv1;
3116*3d8817e4Smiod 	      ++pv2;
3117*3d8817e4Smiod 	    }
3118*3d8817e4Smiod 	  ret = *pn1 == NULL && *pn2 == NULL;
3119*3d8817e4Smiod 	}
3120*3d8817e4Smiod       break;
3121*3d8817e4Smiod 
3122*3d8817e4Smiod     case DEBUG_KIND_POINTER:
3123*3d8817e4Smiod       ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer);
3124*3d8817e4Smiod       break;
3125*3d8817e4Smiod 
3126*3d8817e4Smiod     case DEBUG_KIND_FUNCTION:
3127*3d8817e4Smiod       if (t1->u.kfunction->varargs != t2->u.kfunction->varargs
3128*3d8817e4Smiod 	  || ! debug_type_samep (info, t1->u.kfunction->return_type,
3129*3d8817e4Smiod 				 t2->u.kfunction->return_type)
3130*3d8817e4Smiod 	  || ((t1->u.kfunction->arg_types == NULL)
3131*3d8817e4Smiod 	      != (t2->u.kfunction->arg_types == NULL)))
3132*3d8817e4Smiod 	ret = FALSE;
3133*3d8817e4Smiod       else if (t1->u.kfunction->arg_types == NULL)
3134*3d8817e4Smiod 	ret = TRUE;
3135*3d8817e4Smiod       else
3136*3d8817e4Smiod 	{
3137*3d8817e4Smiod 	  struct debug_type **a1, **a2;
3138*3d8817e4Smiod 
3139*3d8817e4Smiod 	  a1 = t1->u.kfunction->arg_types;
3140*3d8817e4Smiod 	  a2 = t2->u.kfunction->arg_types;
3141*3d8817e4Smiod 	  while (*a1 != NULL && *a2 != NULL)
3142*3d8817e4Smiod 	    {
3143*3d8817e4Smiod 	      if (! debug_type_samep (info, *a1, *a2))
3144*3d8817e4Smiod 		break;
3145*3d8817e4Smiod 	      ++a1;
3146*3d8817e4Smiod 	      ++a2;
3147*3d8817e4Smiod 	    }
3148*3d8817e4Smiod 	  ret = *a1 == NULL && *a2 == NULL;
3149*3d8817e4Smiod 	}
3150*3d8817e4Smiod       break;
3151*3d8817e4Smiod 
3152*3d8817e4Smiod     case DEBUG_KIND_REFERENCE:
3153*3d8817e4Smiod       ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference);
3154*3d8817e4Smiod       break;
3155*3d8817e4Smiod 
3156*3d8817e4Smiod     case DEBUG_KIND_RANGE:
3157*3d8817e4Smiod       ret = (t1->u.krange->lower == t2->u.krange->lower
3158*3d8817e4Smiod 	     && t1->u.krange->upper == t2->u.krange->upper
3159*3d8817e4Smiod 	     && debug_type_samep (info, t1->u.krange->type,
3160*3d8817e4Smiod 				  t2->u.krange->type));
3161*3d8817e4Smiod 
3162*3d8817e4Smiod     case DEBUG_KIND_ARRAY:
3163*3d8817e4Smiod       ret = (t1->u.karray->lower == t2->u.karray->lower
3164*3d8817e4Smiod 	     && t1->u.karray->upper == t2->u.karray->upper
3165*3d8817e4Smiod 	     && t1->u.karray->stringp == t2->u.karray->stringp
3166*3d8817e4Smiod 	     && debug_type_samep (info, t1->u.karray->element_type,
3167*3d8817e4Smiod 				  t2->u.karray->element_type));
3168*3d8817e4Smiod       break;
3169*3d8817e4Smiod 
3170*3d8817e4Smiod     case DEBUG_KIND_SET:
3171*3d8817e4Smiod       ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp
3172*3d8817e4Smiod 	     && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type));
3173*3d8817e4Smiod       break;
3174*3d8817e4Smiod 
3175*3d8817e4Smiod     case DEBUG_KIND_OFFSET:
3176*3d8817e4Smiod       ret = (debug_type_samep (info, t1->u.koffset->base_type,
3177*3d8817e4Smiod 			       t2->u.koffset->base_type)
3178*3d8817e4Smiod 	     && debug_type_samep (info, t1->u.koffset->target_type,
3179*3d8817e4Smiod 				  t2->u.koffset->target_type));
3180*3d8817e4Smiod       break;
3181*3d8817e4Smiod 
3182*3d8817e4Smiod     case DEBUG_KIND_METHOD:
3183*3d8817e4Smiod       if (t1->u.kmethod->varargs != t2->u.kmethod->varargs
3184*3d8817e4Smiod 	  || ! debug_type_samep (info, t1->u.kmethod->return_type,
3185*3d8817e4Smiod 				 t2->u.kmethod->return_type)
3186*3d8817e4Smiod 	  || ! debug_type_samep (info, t1->u.kmethod->domain_type,
3187*3d8817e4Smiod 				 t2->u.kmethod->domain_type)
3188*3d8817e4Smiod 	  || ((t1->u.kmethod->arg_types == NULL)
3189*3d8817e4Smiod 	      != (t2->u.kmethod->arg_types == NULL)))
3190*3d8817e4Smiod 	ret = FALSE;
3191*3d8817e4Smiod       else if (t1->u.kmethod->arg_types == NULL)
3192*3d8817e4Smiod 	ret = TRUE;
3193*3d8817e4Smiod       else
3194*3d8817e4Smiod 	{
3195*3d8817e4Smiod 	  struct debug_type **a1, **a2;
3196*3d8817e4Smiod 
3197*3d8817e4Smiod 	  a1 = t1->u.kmethod->arg_types;
3198*3d8817e4Smiod 	  a2 = t2->u.kmethod->arg_types;
3199*3d8817e4Smiod 	  while (*a1 != NULL && *a2 != NULL)
3200*3d8817e4Smiod 	    {
3201*3d8817e4Smiod 	      if (! debug_type_samep (info, *a1, *a2))
3202*3d8817e4Smiod 		break;
3203*3d8817e4Smiod 	      ++a1;
3204*3d8817e4Smiod 	      ++a2;
3205*3d8817e4Smiod 	    }
3206*3d8817e4Smiod 	  ret = *a1 == NULL && *a2 == NULL;
3207*3d8817e4Smiod 	}
3208*3d8817e4Smiod       break;
3209*3d8817e4Smiod 
3210*3d8817e4Smiod     case DEBUG_KIND_CONST:
3211*3d8817e4Smiod       ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst);
3212*3d8817e4Smiod       break;
3213*3d8817e4Smiod 
3214*3d8817e4Smiod     case DEBUG_KIND_VOLATILE:
3215*3d8817e4Smiod       ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile);
3216*3d8817e4Smiod       break;
3217*3d8817e4Smiod 
3218*3d8817e4Smiod     case DEBUG_KIND_NAMED:
3219*3d8817e4Smiod     case DEBUG_KIND_TAGGED:
3220*3d8817e4Smiod       ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0
3221*3d8817e4Smiod 	     && debug_type_samep (info, t1->u.knamed->type,
3222*3d8817e4Smiod 				  t2->u.knamed->type));
3223*3d8817e4Smiod       break;
3224*3d8817e4Smiod     }
3225*3d8817e4Smiod 
3226*3d8817e4Smiod   info->compare_list = top.next;
3227*3d8817e4Smiod 
3228*3d8817e4Smiod   return ret;
3229*3d8817e4Smiod }
3230*3d8817e4Smiod 
3231*3d8817e4Smiod /* See if two classes are the same.  This is a subroutine of
3232*3d8817e4Smiod    debug_type_samep.  */
3233*3d8817e4Smiod 
3234*3d8817e4Smiod static bfd_boolean
debug_class_type_samep(struct debug_handle * info,struct debug_type * t1,struct debug_type * t2)3235*3d8817e4Smiod debug_class_type_samep (struct debug_handle *info, struct debug_type *t1,
3236*3d8817e4Smiod 			struct debug_type *t2)
3237*3d8817e4Smiod {
3238*3d8817e4Smiod   struct debug_class_type *c1, *c2;
3239*3d8817e4Smiod 
3240*3d8817e4Smiod   c1 = t1->u.kclass;
3241*3d8817e4Smiod   c2 = t2->u.kclass;
3242*3d8817e4Smiod 
3243*3d8817e4Smiod   if ((c1->fields == NULL) != (c2->fields == NULL)
3244*3d8817e4Smiod       || (c1->baseclasses == NULL) != (c2->baseclasses == NULL)
3245*3d8817e4Smiod       || (c1->methods == NULL) != (c2->methods == NULL)
3246*3d8817e4Smiod       || (c1->vptrbase == NULL) != (c2->vptrbase == NULL))
3247*3d8817e4Smiod     return FALSE;
3248*3d8817e4Smiod 
3249*3d8817e4Smiod   if (c1->fields != NULL)
3250*3d8817e4Smiod     {
3251*3d8817e4Smiod       struct debug_field **pf1, **pf2;
3252*3d8817e4Smiod 
3253*3d8817e4Smiod       for (pf1 = c1->fields, pf2 = c2->fields;
3254*3d8817e4Smiod 	   *pf1 != NULL && *pf2 != NULL;
3255*3d8817e4Smiod 	   pf1++, pf2++)
3256*3d8817e4Smiod 	{
3257*3d8817e4Smiod 	  struct debug_field *f1, *f2;
3258*3d8817e4Smiod 
3259*3d8817e4Smiod 	  f1 = *pf1;
3260*3d8817e4Smiod 	  f2 = *pf2;
3261*3d8817e4Smiod 	  if (f1->name[0] != f2->name[0]
3262*3d8817e4Smiod 	      || f1->visibility != f2->visibility
3263*3d8817e4Smiod 	      || f1->static_member != f2->static_member)
3264*3d8817e4Smiod 	    return FALSE;
3265*3d8817e4Smiod 	  if (f1->static_member)
3266*3d8817e4Smiod 	    {
3267*3d8817e4Smiod 	      if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0)
3268*3d8817e4Smiod 		return FALSE;
3269*3d8817e4Smiod 	    }
3270*3d8817e4Smiod 	  else
3271*3d8817e4Smiod 	    {
3272*3d8817e4Smiod 	      if (f1->u.f.bitpos != f2->u.f.bitpos
3273*3d8817e4Smiod 		  || f1->u.f.bitsize != f2->u.f.bitsize)
3274*3d8817e4Smiod 		return FALSE;
3275*3d8817e4Smiod 	    }
3276*3d8817e4Smiod 	  /* We do the checks which require function calls last.  We
3277*3d8817e4Smiod              don't require that the types of fields have the same
3278*3d8817e4Smiod              names, since that sometimes fails in the presence of
3279*3d8817e4Smiod              typedefs and we really don't care.  */
3280*3d8817e4Smiod 	  if (strcmp (f1->name, f2->name) != 0
3281*3d8817e4Smiod 	      || ! debug_type_samep (info,
3282*3d8817e4Smiod 				     debug_get_real_type ((void *) info,
3283*3d8817e4Smiod 							  f1->type, NULL),
3284*3d8817e4Smiod 				     debug_get_real_type ((void *) info,
3285*3d8817e4Smiod 							  f2->type, NULL)))
3286*3d8817e4Smiod 	    return FALSE;
3287*3d8817e4Smiod 	}
3288*3d8817e4Smiod       if (*pf1 != NULL || *pf2 != NULL)
3289*3d8817e4Smiod 	return FALSE;
3290*3d8817e4Smiod     }
3291*3d8817e4Smiod 
3292*3d8817e4Smiod   if (c1->vptrbase != NULL)
3293*3d8817e4Smiod     {
3294*3d8817e4Smiod       if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase))
3295*3d8817e4Smiod 	return FALSE;
3296*3d8817e4Smiod     }
3297*3d8817e4Smiod 
3298*3d8817e4Smiod   if (c1->baseclasses != NULL)
3299*3d8817e4Smiod     {
3300*3d8817e4Smiod       struct debug_baseclass **pb1, **pb2;
3301*3d8817e4Smiod 
3302*3d8817e4Smiod       for (pb1 = c1->baseclasses, pb2 = c2->baseclasses;
3303*3d8817e4Smiod 	   *pb1 != NULL && *pb2 != NULL;
3304*3d8817e4Smiod 	   ++pb1, ++pb2)
3305*3d8817e4Smiod 	{
3306*3d8817e4Smiod 	  struct debug_baseclass *b1, *b2;
3307*3d8817e4Smiod 
3308*3d8817e4Smiod 	  b1 = *pb1;
3309*3d8817e4Smiod 	  b2 = *pb2;
3310*3d8817e4Smiod 	  if (b1->bitpos != b2->bitpos
3311*3d8817e4Smiod 	      || b1->virtual != b2->virtual
3312*3d8817e4Smiod 	      || b1->visibility != b2->visibility
3313*3d8817e4Smiod 	      || ! debug_type_samep (info, b1->type, b2->type))
3314*3d8817e4Smiod 	    return FALSE;
3315*3d8817e4Smiod 	}
3316*3d8817e4Smiod       if (*pb1 != NULL || *pb2 != NULL)
3317*3d8817e4Smiod 	return FALSE;
3318*3d8817e4Smiod     }
3319*3d8817e4Smiod 
3320*3d8817e4Smiod   if (c1->methods != NULL)
3321*3d8817e4Smiod     {
3322*3d8817e4Smiod       struct debug_method **pm1, **pm2;
3323*3d8817e4Smiod 
3324*3d8817e4Smiod       for (pm1 = c1->methods, pm2 = c2->methods;
3325*3d8817e4Smiod 	   *pm1 != NULL && *pm2 != NULL;
3326*3d8817e4Smiod 	   ++pm1, ++pm2)
3327*3d8817e4Smiod 	{
3328*3d8817e4Smiod 	  struct debug_method *m1, *m2;
3329*3d8817e4Smiod 
3330*3d8817e4Smiod 	  m1 = *pm1;
3331*3d8817e4Smiod 	  m2 = *pm2;
3332*3d8817e4Smiod 	  if (m1->name[0] != m2->name[0]
3333*3d8817e4Smiod 	      || strcmp (m1->name, m2->name) != 0
3334*3d8817e4Smiod 	      || (m1->variants == NULL) != (m2->variants == NULL))
3335*3d8817e4Smiod 	    return FALSE;
3336*3d8817e4Smiod 	  if (m1->variants == NULL)
3337*3d8817e4Smiod 	    {
3338*3d8817e4Smiod 	      struct debug_method_variant **pv1, **pv2;
3339*3d8817e4Smiod 
3340*3d8817e4Smiod 	      for (pv1 = m1->variants, pv2 = m2->variants;
3341*3d8817e4Smiod 		   *pv1 != NULL && *pv2 != NULL;
3342*3d8817e4Smiod 		   ++pv1, ++pv2)
3343*3d8817e4Smiod 		{
3344*3d8817e4Smiod 		  struct debug_method_variant *v1, *v2;
3345*3d8817e4Smiod 
3346*3d8817e4Smiod 		  v1 = *pv1;
3347*3d8817e4Smiod 		  v2 = *pv2;
3348*3d8817e4Smiod 		  if (v1->physname[0] != v2->physname[0]
3349*3d8817e4Smiod 		      || v1->visibility != v2->visibility
3350*3d8817e4Smiod 		      || v1->constp != v2->constp
3351*3d8817e4Smiod 		      || v1->volatilep != v2->volatilep
3352*3d8817e4Smiod 		      || v1->voffset != v2->voffset
3353*3d8817e4Smiod 		      || (v1->context == NULL) != (v2->context == NULL)
3354*3d8817e4Smiod 		      || strcmp (v1->physname, v2->physname) != 0
3355*3d8817e4Smiod 		      || ! debug_type_samep (info, v1->type, v2->type))
3356*3d8817e4Smiod 		    return FALSE;
3357*3d8817e4Smiod 		  if (v1->context != NULL)
3358*3d8817e4Smiod 		    {
3359*3d8817e4Smiod 		      if (! debug_type_samep (info, v1->context,
3360*3d8817e4Smiod 					      v2->context))
3361*3d8817e4Smiod 			return FALSE;
3362*3d8817e4Smiod 		    }
3363*3d8817e4Smiod 		}
3364*3d8817e4Smiod 	      if (*pv1 != NULL || *pv2 != NULL)
3365*3d8817e4Smiod 		return FALSE;
3366*3d8817e4Smiod 	    }
3367*3d8817e4Smiod 	}
3368*3d8817e4Smiod       if (*pm1 != NULL || *pm2 != NULL)
3369*3d8817e4Smiod 	return FALSE;
3370*3d8817e4Smiod     }
3371*3d8817e4Smiod 
3372*3d8817e4Smiod   return TRUE;
3373*3d8817e4Smiod }
3374