xref: /dflybsd-src/contrib/gcc-4.7/gcc/sdbout.c (revision 0a8dc9fc45f4d0b236341a473fac4a486375f60c)
1e4b17023SJohn Marino /* Output sdb-format symbol table information from GNU compiler.
2e4b17023SJohn Marino    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3e4b17023SJohn Marino    2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
4e4b17023SJohn Marino    Free Software Foundation, Inc.
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino /*  mike@tredysvr.Tredydev.Unisys.COM says:
23e4b17023SJohn Marino I modified the struct.c example and have a nm of a .o resulting from the
24e4b17023SJohn Marino AT&T C compiler.  From the example below I would conclude the following:
25e4b17023SJohn Marino 
26e4b17023SJohn Marino 1. All .defs from structures are emitted as scanned.  The example below
27e4b17023SJohn Marino    clearly shows the symbol table entries for BoxRec2 are after the first
28e4b17023SJohn Marino    function.
29e4b17023SJohn Marino 
30e4b17023SJohn Marino 2. All functions and their locals (including statics) are emitted as scanned.
31e4b17023SJohn Marino 
32e4b17023SJohn Marino 3. All nested unnamed union and structure .defs must be emitted before
33e4b17023SJohn Marino    the structure in which they are nested.  The AT&T assembler is a
34e4b17023SJohn Marino    one pass beast as far as symbolics are concerned.
35e4b17023SJohn Marino 
36e4b17023SJohn Marino 4. All structure .defs are emitted before the typedefs that refer to them.
37e4b17023SJohn Marino 
38e4b17023SJohn Marino 5. All top level static and external variable definitions are moved to the
39e4b17023SJohn Marino    end of file with all top level statics occurring first before externs.
40e4b17023SJohn Marino 
41e4b17023SJohn Marino 6. All undefined references are at the end of the file.
42e4b17023SJohn Marino */
43e4b17023SJohn Marino 
44e4b17023SJohn Marino #include "config.h"
45e4b17023SJohn Marino #include "system.h"
46e4b17023SJohn Marino #include "coretypes.h"
47e4b17023SJohn Marino #include "tm.h"
48e4b17023SJohn Marino #include "debug.h"
49e4b17023SJohn Marino #include "tree.h"
50e4b17023SJohn Marino #include "ggc.h"
51e4b17023SJohn Marino #include "vec.h"
52e4b17023SJohn Marino 
53e4b17023SJohn Marino static GTY(()) tree anonymous_types;
54e4b17023SJohn Marino 
55e4b17023SJohn Marino /* Counter to generate unique "names" for nameless struct members.  */
56e4b17023SJohn Marino 
57e4b17023SJohn Marino static GTY(()) int unnamed_struct_number;
58e4b17023SJohn Marino 
59e4b17023SJohn Marino /* Declarations whose debug info was deferred till end of compilation.  */
60e4b17023SJohn Marino 
61e4b17023SJohn Marino static GTY(()) VEC(tree,gc) *deferred_global_decls;
62e4b17023SJohn Marino 
63e4b17023SJohn Marino /* The C front end may call sdbout_symbol before sdbout_init runs.
64e4b17023SJohn Marino    We save all such decls in this list and output them when we get
65e4b17023SJohn Marino    to sdbout_init.  */
66e4b17023SJohn Marino 
67e4b17023SJohn Marino static GTY(()) tree preinit_symbols;
68e4b17023SJohn Marino static GTY(()) bool sdbout_initialized;
69e4b17023SJohn Marino 
70e4b17023SJohn Marino #ifdef SDB_DEBUGGING_INFO
71e4b17023SJohn Marino 
72e4b17023SJohn Marino #include "rtl.h"
73e4b17023SJohn Marino #include "regs.h"
74e4b17023SJohn Marino #include "flags.h"
75e4b17023SJohn Marino #include "insn-config.h"
76e4b17023SJohn Marino #include "reload.h"
77e4b17023SJohn Marino #include "output.h"
78e4b17023SJohn Marino #include "diagnostic-core.h"
79e4b17023SJohn Marino #include "tm_p.h"
80e4b17023SJohn Marino #include "gsyms.h"
81e4b17023SJohn Marino #include "langhooks.h"
82e4b17023SJohn Marino #include "target.h"
83e4b17023SJohn Marino 
84e4b17023SJohn Marino /* 1 if PARM is passed to this function in memory.  */
85e4b17023SJohn Marino 
86e4b17023SJohn Marino #define PARM_PASSED_IN_MEMORY(PARM) \
87e4b17023SJohn Marino  (MEM_P (DECL_INCOMING_RTL (PARM)))
88e4b17023SJohn Marino 
89e4b17023SJohn Marino /* A C expression for the integer offset value of an automatic variable
90e4b17023SJohn Marino    (C_AUTO) having address X (an RTX).  */
91e4b17023SJohn Marino #ifndef DEBUGGER_AUTO_OFFSET
92e4b17023SJohn Marino #define DEBUGGER_AUTO_OFFSET(X) \
93e4b17023SJohn Marino   (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0)
94e4b17023SJohn Marino #endif
95e4b17023SJohn Marino 
96e4b17023SJohn Marino /* A C expression for the integer offset value of an argument (C_ARG)
97e4b17023SJohn Marino    having address X (an RTX).  The nominal offset is OFFSET.  */
98e4b17023SJohn Marino #ifndef DEBUGGER_ARG_OFFSET
99e4b17023SJohn Marino #define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET)
100e4b17023SJohn Marino #endif
101e4b17023SJohn Marino 
102e4b17023SJohn Marino /* Line number of beginning of current function, minus one.
103e4b17023SJohn Marino    Negative means not in a function or not using sdb.  */
104e4b17023SJohn Marino 
105e4b17023SJohn Marino int sdb_begin_function_line = -1;
106e4b17023SJohn Marino 
107e4b17023SJohn Marino 
108e4b17023SJohn Marino extern FILE *asm_out_file;
109e4b17023SJohn Marino 
110e4b17023SJohn Marino extern tree current_function_decl;
111e4b17023SJohn Marino 
112e4b17023SJohn Marino #include "sdbout.h"
113e4b17023SJohn Marino 
114e4b17023SJohn Marino static void sdbout_init			(const char *);
115e4b17023SJohn Marino static void sdbout_finish		(const char *);
116e4b17023SJohn Marino static void sdbout_start_source_file	(unsigned int, const char *);
117e4b17023SJohn Marino static void sdbout_end_source_file	(unsigned int);
118e4b17023SJohn Marino static void sdbout_begin_block		(unsigned int, unsigned int);
119e4b17023SJohn Marino static void sdbout_end_block		(unsigned int, unsigned int);
120e4b17023SJohn Marino static void sdbout_source_line		(unsigned int, const char *, int, bool);
121e4b17023SJohn Marino static void sdbout_end_epilogue		(unsigned int, const char *);
122e4b17023SJohn Marino static void sdbout_global_decl		(tree);
123e4b17023SJohn Marino #ifndef MIPS_DEBUGGING_INFO
124e4b17023SJohn Marino static void sdbout_begin_prologue	(unsigned int, const char *);
125e4b17023SJohn Marino #endif
126e4b17023SJohn Marino static void sdbout_end_prologue		(unsigned int, const char *);
127e4b17023SJohn Marino static void sdbout_begin_function	(tree);
128e4b17023SJohn Marino static void sdbout_end_function		(unsigned int);
129e4b17023SJohn Marino static void sdbout_toplevel_data	(tree);
130e4b17023SJohn Marino static void sdbout_label		(rtx);
131e4b17023SJohn Marino static char *gen_fake_label		(void);
132e4b17023SJohn Marino static int plain_type			(tree);
133e4b17023SJohn Marino static int template_name_p		(tree);
134e4b17023SJohn Marino static void sdbout_record_type_name	(tree);
135e4b17023SJohn Marino static int plain_type_1			(tree, int);
136e4b17023SJohn Marino static void sdbout_block		(tree);
137e4b17023SJohn Marino static void sdbout_syms			(tree);
138e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
139e4b17023SJohn Marino static void sdbout_queue_anonymous_type	(tree);
140e4b17023SJohn Marino static void sdbout_dequeue_anonymous_types (void);
141e4b17023SJohn Marino #endif
142e4b17023SJohn Marino static void sdbout_type			(tree);
143e4b17023SJohn Marino static void sdbout_field_types		(tree);
144e4b17023SJohn Marino static void sdbout_one_type		(tree);
145e4b17023SJohn Marino static void sdbout_parms		(tree);
146e4b17023SJohn Marino static void sdbout_reg_parms		(tree);
147e4b17023SJohn Marino static void sdbout_global_decl		(tree);
148e4b17023SJohn Marino 
149e4b17023SJohn Marino /* Random macros describing parts of SDB data.  */
150e4b17023SJohn Marino 
151e4b17023SJohn Marino /* Default value of delimiter is ";".  */
152e4b17023SJohn Marino #ifndef SDB_DELIM
153e4b17023SJohn Marino #define SDB_DELIM	";"
154e4b17023SJohn Marino #endif
155e4b17023SJohn Marino 
156e4b17023SJohn Marino /* Maximum number of dimensions the assembler will allow.  */
157e4b17023SJohn Marino #ifndef SDB_MAX_DIM
158e4b17023SJohn Marino #define SDB_MAX_DIM 4
159e4b17023SJohn Marino #endif
160e4b17023SJohn Marino 
161e4b17023SJohn Marino #ifndef PUT_SDB_SCL
162e4b17023SJohn Marino #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d%s", (a), SDB_DELIM)
163e4b17023SJohn Marino #endif
164e4b17023SJohn Marino 
165e4b17023SJohn Marino #ifndef PUT_SDB_INT_VAL
166e4b17023SJohn Marino #define PUT_SDB_INT_VAL(a) \
167e4b17023SJohn Marino  do {									\
168e4b17023SJohn Marino    fprintf (asm_out_file, "\t.val\t" HOST_WIDE_INT_PRINT_DEC "%s",	\
169e4b17023SJohn Marino 	    (HOST_WIDE_INT) (a), SDB_DELIM);				\
170e4b17023SJohn Marino  } while (0)
171e4b17023SJohn Marino 
172e4b17023SJohn Marino #endif
173e4b17023SJohn Marino 
174e4b17023SJohn Marino #ifndef PUT_SDB_VAL
175e4b17023SJohn Marino #define PUT_SDB_VAL(a)				\
176e4b17023SJohn Marino ( fputs ("\t.val\t", asm_out_file),		\
177e4b17023SJohn Marino   output_addr_const (asm_out_file, (a)),	\
178e4b17023SJohn Marino   fprintf (asm_out_file, SDB_DELIM))
179e4b17023SJohn Marino #endif
180e4b17023SJohn Marino 
181e4b17023SJohn Marino #ifndef PUT_SDB_DEF
182e4b17023SJohn Marino #define PUT_SDB_DEF(a)				\
183e4b17023SJohn Marino do { fprintf (asm_out_file, "\t.def\t");	\
184e4b17023SJohn Marino      assemble_name (asm_out_file, a);	\
185e4b17023SJohn Marino      fprintf (asm_out_file, SDB_DELIM); } while (0)
186e4b17023SJohn Marino #endif
187e4b17023SJohn Marino 
188e4b17023SJohn Marino #ifndef PUT_SDB_PLAIN_DEF
189e4b17023SJohn Marino #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s%s",a, SDB_DELIM)
190e4b17023SJohn Marino #endif
191e4b17023SJohn Marino 
192e4b17023SJohn Marino #ifndef PUT_SDB_ENDEF
193e4b17023SJohn Marino #define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file)
194e4b17023SJohn Marino #endif
195e4b17023SJohn Marino 
196e4b17023SJohn Marino #ifndef PUT_SDB_TYPE
197e4b17023SJohn Marino #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o%s", a, SDB_DELIM)
198e4b17023SJohn Marino #endif
199e4b17023SJohn Marino 
200e4b17023SJohn Marino #ifndef PUT_SDB_SIZE
201e4b17023SJohn Marino #define PUT_SDB_SIZE(a) \
202e4b17023SJohn Marino  do {									\
203e4b17023SJohn Marino    fprintf (asm_out_file, "\t.size\t" HOST_WIDE_INT_PRINT_DEC "%s",	\
204e4b17023SJohn Marino 	    (HOST_WIDE_INT) (a), SDB_DELIM);				\
205e4b17023SJohn Marino  } while(0)
206e4b17023SJohn Marino #endif
207e4b17023SJohn Marino 
208e4b17023SJohn Marino #ifndef PUT_SDB_START_DIM
209e4b17023SJohn Marino #define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t")
210e4b17023SJohn Marino #endif
211e4b17023SJohn Marino 
212e4b17023SJohn Marino #ifndef PUT_SDB_NEXT_DIM
213e4b17023SJohn Marino #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
214e4b17023SJohn Marino #endif
215e4b17023SJohn Marino 
216e4b17023SJohn Marino #ifndef PUT_SDB_LAST_DIM
217e4b17023SJohn Marino #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM)
218e4b17023SJohn Marino #endif
219e4b17023SJohn Marino 
220e4b17023SJohn Marino #ifndef PUT_SDB_TAG
221e4b17023SJohn Marino #define PUT_SDB_TAG(a)				\
222e4b17023SJohn Marino do { fprintf (asm_out_file, "\t.tag\t");	\
223e4b17023SJohn Marino      assemble_name (asm_out_file, a);	\
224e4b17023SJohn Marino      fprintf (asm_out_file, SDB_DELIM); } while (0)
225e4b17023SJohn Marino #endif
226e4b17023SJohn Marino 
227e4b17023SJohn Marino #ifndef PUT_SDB_BLOCK_START
228e4b17023SJohn Marino #define PUT_SDB_BLOCK_START(LINE)		\
229e4b17023SJohn Marino   fprintf (asm_out_file,			\
230e4b17023SJohn Marino 	   "\t.def\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
231e4b17023SJohn Marino 	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
232e4b17023SJohn Marino #endif
233e4b17023SJohn Marino 
234e4b17023SJohn Marino #ifndef PUT_SDB_BLOCK_END
235e4b17023SJohn Marino #define PUT_SDB_BLOCK_END(LINE)			\
236e4b17023SJohn Marino   fprintf (asm_out_file,			\
237e4b17023SJohn Marino 	   "\t.def\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n",  \
238e4b17023SJohn Marino 	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
239e4b17023SJohn Marino #endif
240e4b17023SJohn Marino 
241e4b17023SJohn Marino #ifndef PUT_SDB_FUNCTION_START
242e4b17023SJohn Marino #define PUT_SDB_FUNCTION_START(LINE)		\
243e4b17023SJohn Marino   fprintf (asm_out_file,			\
244e4b17023SJohn Marino 	   "\t.def\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
245e4b17023SJohn Marino 	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
246e4b17023SJohn Marino #endif
247e4b17023SJohn Marino 
248e4b17023SJohn Marino #ifndef PUT_SDB_FUNCTION_END
249e4b17023SJohn Marino #define PUT_SDB_FUNCTION_END(LINE)		\
250e4b17023SJohn Marino   fprintf (asm_out_file,			\
251e4b17023SJohn Marino 	   "\t.def\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
252e4b17023SJohn Marino 	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
253e4b17023SJohn Marino #endif
254e4b17023SJohn Marino 
255e4b17023SJohn Marino /* Return the sdb tag identifier string for TYPE
256e4b17023SJohn Marino    if TYPE has already been defined; otherwise return a null pointer.  */
257e4b17023SJohn Marino 
258e4b17023SJohn Marino #define KNOWN_TYPE_TAG(type)  TYPE_SYMTAB_POINTER (type)
259e4b17023SJohn Marino 
260e4b17023SJohn Marino /* Set the sdb tag identifier string for TYPE to NAME.  */
261e4b17023SJohn Marino 
262e4b17023SJohn Marino #define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
263e4b17023SJohn Marino   TYPE_SYMTAB_POINTER (TYPE) = (const char *)(NAME)
264e4b17023SJohn Marino 
265e4b17023SJohn Marino /* Return the name (a string) of the struct, union or enum tag
266e4b17023SJohn Marino    described by the TREE_LIST node LINK.  This is 0 for an anonymous one.  */
267e4b17023SJohn Marino 
268e4b17023SJohn Marino #define TAG_NAME(link) \
269e4b17023SJohn Marino   (((link) && TREE_PURPOSE ((link)) \
270e4b17023SJohn Marino     && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \
271e4b17023SJohn Marino    ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0)
272e4b17023SJohn Marino 
273e4b17023SJohn Marino /* Ensure we don't output a negative line number.  */
274e4b17023SJohn Marino #define MAKE_LINE_SAFE(line)  \
275e4b17023SJohn Marino   if ((int) line <= sdb_begin_function_line) \
276e4b17023SJohn Marino     line = sdb_begin_function_line + 1
277e4b17023SJohn Marino 
278e4b17023SJohn Marino /* Perform linker optimization of merging header file definitions together
279e4b17023SJohn Marino    for targets with MIPS_DEBUGGING_INFO defined.  This won't work without a
280e4b17023SJohn Marino    post 960826 version of GAS.  Nothing breaks with earlier versions of GAS,
281e4b17023SJohn Marino    the optimization just won't be done.  The native assembler already has the
282e4b17023SJohn Marino    necessary support.  */
283e4b17023SJohn Marino 
284e4b17023SJohn Marino #ifdef MIPS_DEBUGGING_INFO
285e4b17023SJohn Marino 
286e4b17023SJohn Marino /* ECOFF linkers have an optimization that does the same kind of thing as
287e4b17023SJohn Marino    N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the
288e4b17023SJohn Marino    executable.  To achieve this, GCC must output a .file for each file
289e4b17023SJohn Marino    name change.  */
290e4b17023SJohn Marino 
291e4b17023SJohn Marino /* This is a stack of input files.  */
292e4b17023SJohn Marino 
293e4b17023SJohn Marino struct sdb_file
294e4b17023SJohn Marino {
295e4b17023SJohn Marino   struct sdb_file *next;
296e4b17023SJohn Marino   const char *name;
297e4b17023SJohn Marino };
298e4b17023SJohn Marino 
299e4b17023SJohn Marino /* This is the top of the stack.  */
300e4b17023SJohn Marino 
301e4b17023SJohn Marino static struct sdb_file *current_file;
302e4b17023SJohn Marino 
303e4b17023SJohn Marino #endif /* MIPS_DEBUGGING_INFO */
304e4b17023SJohn Marino 
305e4b17023SJohn Marino /* The debug hooks structure.  */
306e4b17023SJohn Marino const struct gcc_debug_hooks sdb_debug_hooks =
307e4b17023SJohn Marino {
308e4b17023SJohn Marino   sdbout_init,			         /* init */
309e4b17023SJohn Marino   sdbout_finish,		         /* finish */
310e4b17023SJohn Marino   debug_nothing_void,			 /* assembly_start */
311e4b17023SJohn Marino   debug_nothing_int_charstar,	         /* define */
312e4b17023SJohn Marino   debug_nothing_int_charstar,	         /* undef */
313e4b17023SJohn Marino   sdbout_start_source_file,	         /* start_source_file */
314e4b17023SJohn Marino   sdbout_end_source_file,	         /* end_source_file */
315e4b17023SJohn Marino   sdbout_begin_block,		         /* begin_block */
316e4b17023SJohn Marino   sdbout_end_block,		         /* end_block */
317e4b17023SJohn Marino   debug_true_const_tree,	         /* ignore_block */
318e4b17023SJohn Marino   sdbout_source_line,		         /* source_line */
319e4b17023SJohn Marino #ifdef MIPS_DEBUGGING_INFO
320e4b17023SJohn Marino   /* Defer on MIPS systems so that parameter descriptions follow
321e4b17023SJohn Marino      function entry.  */
322e4b17023SJohn Marino   debug_nothing_int_charstar,	         /* begin_prologue */
323e4b17023SJohn Marino   sdbout_end_prologue,		         /* end_prologue */
324e4b17023SJohn Marino #else
325e4b17023SJohn Marino   sdbout_begin_prologue,	         /* begin_prologue */
326e4b17023SJohn Marino   debug_nothing_int_charstar,	         /* end_prologue */
327e4b17023SJohn Marino #endif
328e4b17023SJohn Marino   debug_nothing_int_charstar,	         /* begin_epilogue */
329e4b17023SJohn Marino   sdbout_end_epilogue,		         /* end_epilogue */
330e4b17023SJohn Marino   sdbout_begin_function,	         /* begin_function */
331e4b17023SJohn Marino   sdbout_end_function,		         /* end_function */
332e4b17023SJohn Marino   debug_nothing_tree,		         /* function_decl */
333e4b17023SJohn Marino   sdbout_global_decl,		         /* global_decl */
334e4b17023SJohn Marino   sdbout_symbol,			 /* type_decl */
335e4b17023SJohn Marino   debug_nothing_tree_tree_tree_bool,	 /* imported_module_or_decl */
336e4b17023SJohn Marino   debug_nothing_tree,		         /* deferred_inline_function */
337e4b17023SJohn Marino   debug_nothing_tree,		         /* outlining_inline_function */
338e4b17023SJohn Marino   sdbout_label,			         /* label */
339e4b17023SJohn Marino   debug_nothing_int,		         /* handle_pch */
340e4b17023SJohn Marino   debug_nothing_rtx,		         /* var_location */
341e4b17023SJohn Marino   debug_nothing_void,                    /* switch_text_section */
342e4b17023SJohn Marino   debug_nothing_tree_tree,		 /* set_name */
343e4b17023SJohn Marino   0,                                     /* start_end_main_source_file */
344e4b17023SJohn Marino   TYPE_SYMTAB_IS_POINTER                 /* tree_type_symtab_field */
345e4b17023SJohn Marino };
346e4b17023SJohn Marino 
347e4b17023SJohn Marino /* Return a unique string to name an anonymous type.  */
348e4b17023SJohn Marino 
349e4b17023SJohn Marino static char *
gen_fake_label(void)350e4b17023SJohn Marino gen_fake_label (void)
351e4b17023SJohn Marino {
352e4b17023SJohn Marino   char label[10];
353e4b17023SJohn Marino   char *labelstr;
354e4b17023SJohn Marino   sprintf (label, ".%dfake", unnamed_struct_number);
355e4b17023SJohn Marino   unnamed_struct_number++;
356e4b17023SJohn Marino   labelstr = xstrdup (label);
357e4b17023SJohn Marino   return labelstr;
358e4b17023SJohn Marino }
359e4b17023SJohn Marino 
360e4b17023SJohn Marino /* Return the number which describes TYPE for SDB.
361e4b17023SJohn Marino    For pointers, etc., this function is recursive.
362e4b17023SJohn Marino    Each record, union or enumeral type must already have had a
363e4b17023SJohn Marino    tag number output.  */
364e4b17023SJohn Marino 
365e4b17023SJohn Marino /* The number is given by d6d5d4d3d2d1bbbb
366e4b17023SJohn Marino    where bbbb is 4 bit basic type, and di indicate  one of notype,ptr,fn,array.
367e4b17023SJohn Marino    Thus, char *foo () has bbbb=T_CHAR
368e4b17023SJohn Marino 			  d1=D_FCN
369e4b17023SJohn Marino 			  d2=D_PTR
370e4b17023SJohn Marino  N_BTMASK=     017       1111     basic type field.
371e4b17023SJohn Marino  N_TSHIFT=       2                derived type shift
372e4b17023SJohn Marino  N_BTSHFT=       4                Basic type shift */
373e4b17023SJohn Marino 
374e4b17023SJohn Marino /* Produce the number that describes a pointer, function or array type.
375e4b17023SJohn Marino    PREV is the number describing the target, value or element type.
376e4b17023SJohn Marino    DT_type describes how to transform that type.  */
377e4b17023SJohn Marino #define PUSH_DERIVED_LEVEL(DT_type,PREV)		\
378e4b17023SJohn Marino   ((((PREV) & ~(int) N_BTMASK) << (int) N_TSHIFT)		\
379e4b17023SJohn Marino    | ((int) DT_type << (int) N_BTSHFT)			\
380e4b17023SJohn Marino    | ((PREV) & (int) N_BTMASK))
381e4b17023SJohn Marino 
382e4b17023SJohn Marino /* Number of elements used in sdb_dims.  */
383e4b17023SJohn Marino static int sdb_n_dims = 0;
384e4b17023SJohn Marino 
385e4b17023SJohn Marino /* Table of array dimensions of current type.  */
386e4b17023SJohn Marino static int sdb_dims[SDB_MAX_DIM];
387e4b17023SJohn Marino 
388e4b17023SJohn Marino /* Size of outermost array currently being processed.  */
389e4b17023SJohn Marino static int sdb_type_size = -1;
390e4b17023SJohn Marino 
391e4b17023SJohn Marino static int
plain_type(tree type)392e4b17023SJohn Marino plain_type (tree type)
393e4b17023SJohn Marino {
394e4b17023SJohn Marino   int val = plain_type_1 (type, 0);
395e4b17023SJohn Marino 
396e4b17023SJohn Marino   /* If we have already saved up some array dimensions, print them now.  */
397e4b17023SJohn Marino   if (sdb_n_dims > 0)
398e4b17023SJohn Marino     {
399e4b17023SJohn Marino       int i;
400e4b17023SJohn Marino       PUT_SDB_START_DIM;
401e4b17023SJohn Marino       for (i = sdb_n_dims - 1; i > 0; i--)
402e4b17023SJohn Marino 	PUT_SDB_NEXT_DIM (sdb_dims[i]);
403e4b17023SJohn Marino       PUT_SDB_LAST_DIM (sdb_dims[0]);
404e4b17023SJohn Marino       sdb_n_dims = 0;
405e4b17023SJohn Marino 
406e4b17023SJohn Marino       sdb_type_size = int_size_in_bytes (type);
407e4b17023SJohn Marino       /* Don't kill sdb if type is not laid out or has variable size.  */
408e4b17023SJohn Marino       if (sdb_type_size < 0)
409e4b17023SJohn Marino 	sdb_type_size = 0;
410e4b17023SJohn Marino     }
411e4b17023SJohn Marino   /* If we have computed the size of an array containing this type,
412e4b17023SJohn Marino      print it now.  */
413e4b17023SJohn Marino   if (sdb_type_size >= 0)
414e4b17023SJohn Marino     {
415e4b17023SJohn Marino       PUT_SDB_SIZE (sdb_type_size);
416e4b17023SJohn Marino       sdb_type_size = -1;
417e4b17023SJohn Marino     }
418e4b17023SJohn Marino   return val;
419e4b17023SJohn Marino }
420e4b17023SJohn Marino 
421e4b17023SJohn Marino static int
template_name_p(tree name)422e4b17023SJohn Marino template_name_p (tree name)
423e4b17023SJohn Marino {
424e4b17023SJohn Marino   const char *ptr = IDENTIFIER_POINTER (name);
425e4b17023SJohn Marino   while (*ptr && *ptr != '<')
426e4b17023SJohn Marino     ptr++;
427e4b17023SJohn Marino 
428e4b17023SJohn Marino   return *ptr != '\0';
429e4b17023SJohn Marino }
430e4b17023SJohn Marino 
431e4b17023SJohn Marino static void
sdbout_record_type_name(tree type)432e4b17023SJohn Marino sdbout_record_type_name (tree type)
433e4b17023SJohn Marino {
434e4b17023SJohn Marino   const char *name = 0;
435e4b17023SJohn Marino   int no_name;
436e4b17023SJohn Marino 
437e4b17023SJohn Marino   if (KNOWN_TYPE_TAG (type))
438e4b17023SJohn Marino     return;
439e4b17023SJohn Marino 
440e4b17023SJohn Marino   if (TYPE_NAME (type) != 0)
441e4b17023SJohn Marino     {
442e4b17023SJohn Marino       tree t = 0;
443e4b17023SJohn Marino 
444e4b17023SJohn Marino       /* Find the IDENTIFIER_NODE for the type name.  */
445e4b17023SJohn Marino       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
446e4b17023SJohn Marino 	t = TYPE_NAME (type);
447e4b17023SJohn Marino       else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
448e4b17023SJohn Marino 	{
449e4b17023SJohn Marino 	  t = DECL_NAME (TYPE_NAME (type));
450e4b17023SJohn Marino 	  /* The DECL_NAME for templates includes "<>", which breaks
451e4b17023SJohn Marino 	     most assemblers.  Use its assembler name instead, which
452e4b17023SJohn Marino 	     has been mangled into being safe.  */
453e4b17023SJohn Marino 	  if (t && template_name_p (t))
454e4b17023SJohn Marino 	    t = DECL_ASSEMBLER_NAME (TYPE_NAME (type));
455e4b17023SJohn Marino 	}
456e4b17023SJohn Marino 
457e4b17023SJohn Marino       /* Now get the name as a string, or invent one.  */
458e4b17023SJohn Marino       if (t != NULL_TREE)
459e4b17023SJohn Marino 	name = IDENTIFIER_POINTER (t);
460e4b17023SJohn Marino     }
461e4b17023SJohn Marino 
462e4b17023SJohn Marino   no_name = (name == 0 || *name == 0);
463e4b17023SJohn Marino   if (no_name)
464e4b17023SJohn Marino     name = gen_fake_label ();
465e4b17023SJohn Marino 
466e4b17023SJohn Marino   SET_KNOWN_TYPE_TAG (type, name);
467e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
468e4b17023SJohn Marino   if (no_name)
469e4b17023SJohn Marino     sdbout_queue_anonymous_type (type);
470e4b17023SJohn Marino #endif
471e4b17023SJohn Marino }
472e4b17023SJohn Marino 
473e4b17023SJohn Marino /* Return the .type value for type TYPE.
474e4b17023SJohn Marino 
475e4b17023SJohn Marino    LEVEL indicates how many levels deep we have recursed into the type.
476e4b17023SJohn Marino    The SDB debug format can only represent 6 derived levels of types.
477e4b17023SJohn Marino    After that, we must output inaccurate debug info.  We deliberately
478e4b17023SJohn Marino    stop before the 7th level, so that ADA recursive types will not give an
479e4b17023SJohn Marino    infinite loop.  */
480e4b17023SJohn Marino 
481e4b17023SJohn Marino static int
plain_type_1(tree type,int level)482e4b17023SJohn Marino plain_type_1 (tree type, int level)
483e4b17023SJohn Marino {
484e4b17023SJohn Marino   if (type == 0)
485e4b17023SJohn Marino     type = void_type_node;
486e4b17023SJohn Marino   else if (type == error_mark_node)
487e4b17023SJohn Marino     type = integer_type_node;
488e4b17023SJohn Marino   else
489e4b17023SJohn Marino     type = TYPE_MAIN_VARIANT (type);
490e4b17023SJohn Marino 
491e4b17023SJohn Marino   switch (TREE_CODE (type))
492e4b17023SJohn Marino     {
493e4b17023SJohn Marino     case VOID_TYPE:
494e4b17023SJohn Marino     case NULLPTR_TYPE:
495e4b17023SJohn Marino       return T_VOID;
496e4b17023SJohn Marino     case BOOLEAN_TYPE:
497e4b17023SJohn Marino     case INTEGER_TYPE:
498e4b17023SJohn Marino       {
499e4b17023SJohn Marino 	int size = int_size_in_bytes (type) * BITS_PER_UNIT;
500e4b17023SJohn Marino 
501e4b17023SJohn Marino 	/* Carefully distinguish all the standard types of C,
502e4b17023SJohn Marino 	   without messing up if the language is not C.
503e4b17023SJohn Marino 	   Note that we check only for the names that contain spaces;
504e4b17023SJohn Marino 	   other names might occur by coincidence in other languages.  */
505e4b17023SJohn Marino 	if (TYPE_NAME (type) != 0
506e4b17023SJohn Marino 	    && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
507e4b17023SJohn Marino 	    && DECL_NAME (TYPE_NAME (type)) != 0
508e4b17023SJohn Marino 	    && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
509e4b17023SJohn Marino 	  {
510e4b17023SJohn Marino 	    const char *const name
511e4b17023SJohn Marino 	      = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
512e4b17023SJohn Marino 
513e4b17023SJohn Marino 	    if (!strcmp (name, "char"))
514e4b17023SJohn Marino 	      return T_CHAR;
515e4b17023SJohn Marino 	    if (!strcmp (name, "unsigned char"))
516e4b17023SJohn Marino 	      return T_UCHAR;
517e4b17023SJohn Marino 	    if (!strcmp (name, "signed char"))
518e4b17023SJohn Marino 	      return T_CHAR;
519e4b17023SJohn Marino 	    if (!strcmp (name, "int"))
520e4b17023SJohn Marino 	      return T_INT;
521e4b17023SJohn Marino 	    if (!strcmp (name, "unsigned int"))
522e4b17023SJohn Marino 	      return T_UINT;
523e4b17023SJohn Marino 	    if (!strcmp (name, "short int"))
524e4b17023SJohn Marino 	      return T_SHORT;
525e4b17023SJohn Marino 	    if (!strcmp (name, "short unsigned int"))
526e4b17023SJohn Marino 	      return T_USHORT;
527e4b17023SJohn Marino 	    if (!strcmp (name, "long int"))
528e4b17023SJohn Marino 	      return T_LONG;
529e4b17023SJohn Marino 	    if (!strcmp (name, "long unsigned int"))
530e4b17023SJohn Marino 	      return T_ULONG;
531e4b17023SJohn Marino 	  }
532e4b17023SJohn Marino 
533e4b17023SJohn Marino 	if (size == INT_TYPE_SIZE)
534e4b17023SJohn Marino 	  return (TYPE_UNSIGNED (type) ? T_UINT : T_INT);
535e4b17023SJohn Marino 	if (size == CHAR_TYPE_SIZE)
536e4b17023SJohn Marino 	  return (TYPE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
537e4b17023SJohn Marino 	if (size == SHORT_TYPE_SIZE)
538e4b17023SJohn Marino 	  return (TYPE_UNSIGNED (type) ? T_USHORT : T_SHORT);
539e4b17023SJohn Marino 	if (size == LONG_TYPE_SIZE)
540e4b17023SJohn Marino 	  return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
541e4b17023SJohn Marino 	if (size == LONG_LONG_TYPE_SIZE)	/* better than nothing */
542e4b17023SJohn Marino 	  return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
543e4b17023SJohn Marino 	return 0;
544e4b17023SJohn Marino       }
545e4b17023SJohn Marino 
546e4b17023SJohn Marino     case REAL_TYPE:
547e4b17023SJohn Marino       {
548e4b17023SJohn Marino 	int precision = TYPE_PRECISION (type);
549e4b17023SJohn Marino 	if (precision == FLOAT_TYPE_SIZE)
550e4b17023SJohn Marino 	  return T_FLOAT;
551e4b17023SJohn Marino 	if (precision == DOUBLE_TYPE_SIZE)
552e4b17023SJohn Marino 	  return T_DOUBLE;
553e4b17023SJohn Marino #ifdef EXTENDED_SDB_BASIC_TYPES
554e4b17023SJohn Marino 	if (precision == LONG_DOUBLE_TYPE_SIZE)
555e4b17023SJohn Marino 	  return T_LNGDBL;
556e4b17023SJohn Marino #else
557e4b17023SJohn Marino 	if (precision == LONG_DOUBLE_TYPE_SIZE)
558e4b17023SJohn Marino 	  return T_DOUBLE;	/* better than nothing */
559e4b17023SJohn Marino #endif
560e4b17023SJohn Marino 	return 0;
561e4b17023SJohn Marino       }
562e4b17023SJohn Marino 
563e4b17023SJohn Marino     case ARRAY_TYPE:
564e4b17023SJohn Marino       {
565e4b17023SJohn Marino 	int m;
566e4b17023SJohn Marino 	if (level >= 6)
567e4b17023SJohn Marino 	  return T_VOID;
568e4b17023SJohn Marino 	else
569e4b17023SJohn Marino 	  m = plain_type_1 (TREE_TYPE (type), level+1);
570e4b17023SJohn Marino 	if (sdb_n_dims < SDB_MAX_DIM)
571e4b17023SJohn Marino 	  sdb_dims[sdb_n_dims++]
572e4b17023SJohn Marino 	    = (TYPE_DOMAIN (type)
573e4b17023SJohn Marino 	       && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != 0
574e4b17023SJohn Marino 	       && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
575e4b17023SJohn Marino 	       && host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
576e4b17023SJohn Marino 	       && host_integerp (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0)
577e4b17023SJohn Marino 	       ? (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
578e4b17023SJohn Marino 		  - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1)
579e4b17023SJohn Marino 	       : 0);
580e4b17023SJohn Marino 
581e4b17023SJohn Marino 	return PUSH_DERIVED_LEVEL (DT_ARY, m);
582e4b17023SJohn Marino       }
583e4b17023SJohn Marino 
584e4b17023SJohn Marino     case RECORD_TYPE:
585e4b17023SJohn Marino     case UNION_TYPE:
586e4b17023SJohn Marino     case QUAL_UNION_TYPE:
587e4b17023SJohn Marino     case ENUMERAL_TYPE:
588e4b17023SJohn Marino       {
589e4b17023SJohn Marino 	const char *tag;
590e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
591e4b17023SJohn Marino 	sdbout_record_type_name (type);
592e4b17023SJohn Marino #endif
593e4b17023SJohn Marino #ifndef SDB_ALLOW_UNKNOWN_REFERENCES
594e4b17023SJohn Marino 	if ((TREE_ASM_WRITTEN (type) && KNOWN_TYPE_TAG (type) != 0)
595e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
596e4b17023SJohn Marino 	    || TYPE_MODE (type) != VOIDmode
597e4b17023SJohn Marino #endif
598e4b17023SJohn Marino 	    )
599e4b17023SJohn Marino #endif
600e4b17023SJohn Marino 	  {
601e4b17023SJohn Marino 	    /* Output the referenced structure tag name
602e4b17023SJohn Marino 	       only if the .def has already been finished.
603e4b17023SJohn Marino 	       At least on 386, the Unix assembler
604e4b17023SJohn Marino 	       cannot handle forward references to tags.  */
605e4b17023SJohn Marino 	    /* But the 88100, it requires them, sigh...  */
606e4b17023SJohn Marino 	    /* And the MIPS requires unknown refs as well...  */
607e4b17023SJohn Marino 	    tag = KNOWN_TYPE_TAG (type);
608e4b17023SJohn Marino 	    PUT_SDB_TAG (tag);
609e4b17023SJohn Marino 	    /* These 3 lines used to follow the close brace.
610e4b17023SJohn Marino 	       However, a size of 0 without a tag implies a tag of 0,
611e4b17023SJohn Marino 	       so if we don't know a tag, we can't mention the size.  */
612e4b17023SJohn Marino 	    sdb_type_size = int_size_in_bytes (type);
613e4b17023SJohn Marino 	    if (sdb_type_size < 0)
614e4b17023SJohn Marino 	      sdb_type_size = 0;
615e4b17023SJohn Marino 	  }
616e4b17023SJohn Marino 	return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
617e4b17023SJohn Marino 		: (TREE_CODE (type) == UNION_TYPE) ? T_UNION
618e4b17023SJohn Marino 		: (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION
619e4b17023SJohn Marino 		: T_ENUM);
620e4b17023SJohn Marino       }
621e4b17023SJohn Marino     case POINTER_TYPE:
622e4b17023SJohn Marino     case REFERENCE_TYPE:
623e4b17023SJohn Marino       {
624e4b17023SJohn Marino 	int m;
625e4b17023SJohn Marino 	if (level >= 6)
626e4b17023SJohn Marino 	  return T_VOID;
627e4b17023SJohn Marino 	else
628e4b17023SJohn Marino 	  m = plain_type_1 (TREE_TYPE (type), level+1);
629e4b17023SJohn Marino 	return PUSH_DERIVED_LEVEL (DT_PTR, m);
630e4b17023SJohn Marino       }
631e4b17023SJohn Marino     case FUNCTION_TYPE:
632e4b17023SJohn Marino     case METHOD_TYPE:
633e4b17023SJohn Marino       {
634e4b17023SJohn Marino 	int m;
635e4b17023SJohn Marino 	if (level >= 6)
636e4b17023SJohn Marino 	  return T_VOID;
637e4b17023SJohn Marino 	else
638e4b17023SJohn Marino 	  m = plain_type_1 (TREE_TYPE (type), level+1);
639e4b17023SJohn Marino 	return PUSH_DERIVED_LEVEL (DT_FCN, m);
640e4b17023SJohn Marino       }
641e4b17023SJohn Marino     default:
642e4b17023SJohn Marino       return 0;
643e4b17023SJohn Marino     }
644e4b17023SJohn Marino }
645e4b17023SJohn Marino 
646e4b17023SJohn Marino /* Output the symbols defined in block number DO_BLOCK.
647e4b17023SJohn Marino 
648e4b17023SJohn Marino    This function works by walking the tree structure of blocks,
649e4b17023SJohn Marino    counting blocks until it finds the desired block.  */
650e4b17023SJohn Marino 
651e4b17023SJohn Marino static int do_block = 0;
652e4b17023SJohn Marino 
653e4b17023SJohn Marino static void
sdbout_block(tree block)654e4b17023SJohn Marino sdbout_block (tree block)
655e4b17023SJohn Marino {
656e4b17023SJohn Marino   while (block)
657e4b17023SJohn Marino     {
658e4b17023SJohn Marino       /* Ignore blocks never expanded or otherwise marked as real.  */
659e4b17023SJohn Marino       if (TREE_USED (block))
660e4b17023SJohn Marino 	{
661e4b17023SJohn Marino 	  /* When we reach the specified block, output its symbols.  */
662e4b17023SJohn Marino 	  if (BLOCK_NUMBER (block) == do_block)
663e4b17023SJohn Marino 	    sdbout_syms (BLOCK_VARS (block));
664e4b17023SJohn Marino 
665e4b17023SJohn Marino 	  /* If we are past the specified block, stop the scan.  */
666e4b17023SJohn Marino 	  if (BLOCK_NUMBER (block) > do_block)
667e4b17023SJohn Marino 	    return;
668e4b17023SJohn Marino 
669e4b17023SJohn Marino 	  /* Scan the blocks within this block.  */
670e4b17023SJohn Marino 	  sdbout_block (BLOCK_SUBBLOCKS (block));
671e4b17023SJohn Marino 	}
672e4b17023SJohn Marino 
673e4b17023SJohn Marino       block = BLOCK_CHAIN (block);
674e4b17023SJohn Marino     }
675e4b17023SJohn Marino }
676e4b17023SJohn Marino 
677e4b17023SJohn Marino /* Call sdbout_symbol on each decl in the chain SYMS.  */
678e4b17023SJohn Marino 
679e4b17023SJohn Marino static void
sdbout_syms(tree syms)680e4b17023SJohn Marino sdbout_syms (tree syms)
681e4b17023SJohn Marino {
682e4b17023SJohn Marino   while (syms)
683e4b17023SJohn Marino     {
684e4b17023SJohn Marino       if (TREE_CODE (syms) != LABEL_DECL)
685e4b17023SJohn Marino 	sdbout_symbol (syms, 1);
686e4b17023SJohn Marino       syms = TREE_CHAIN (syms);
687e4b17023SJohn Marino     }
688e4b17023SJohn Marino }
689e4b17023SJohn Marino 
690e4b17023SJohn Marino /* Output SDB information for a symbol described by DECL.
691e4b17023SJohn Marino    LOCAL is nonzero if the symbol is not file-scope.  */
692e4b17023SJohn Marino 
693e4b17023SJohn Marino void
sdbout_symbol(tree decl,int local)694e4b17023SJohn Marino sdbout_symbol (tree decl, int local)
695e4b17023SJohn Marino {
696e4b17023SJohn Marino   tree type = TREE_TYPE (decl);
697e4b17023SJohn Marino   tree context = NULL_TREE;
698e4b17023SJohn Marino   rtx value;
699e4b17023SJohn Marino   int regno = -1;
700e4b17023SJohn Marino   const char *name;
701e4b17023SJohn Marino 
702e4b17023SJohn Marino   /* If we are called before sdbout_init is run, just save the symbol
703e4b17023SJohn Marino      for later.  */
704e4b17023SJohn Marino   if (!sdbout_initialized)
705e4b17023SJohn Marino     {
706e4b17023SJohn Marino       preinit_symbols = tree_cons (0, decl, preinit_symbols);
707e4b17023SJohn Marino       return;
708e4b17023SJohn Marino     }
709e4b17023SJohn Marino 
710e4b17023SJohn Marino   sdbout_one_type (type);
711e4b17023SJohn Marino 
712e4b17023SJohn Marino   switch (TREE_CODE (decl))
713e4b17023SJohn Marino     {
714e4b17023SJohn Marino     case CONST_DECL:
715e4b17023SJohn Marino       /* Enum values are defined by defining the enum type.  */
716e4b17023SJohn Marino       return;
717e4b17023SJohn Marino 
718e4b17023SJohn Marino     case FUNCTION_DECL:
719e4b17023SJohn Marino       /* Don't mention a nested function under its parent.  */
720e4b17023SJohn Marino       context = decl_function_context (decl);
721e4b17023SJohn Marino       if (context == current_function_decl)
722e4b17023SJohn Marino 	return;
723e4b17023SJohn Marino       /* Check DECL_INITIAL to distinguish declarations from definitions.
724e4b17023SJohn Marino 	 Don't output debug info here for declarations; they will have
725e4b17023SJohn Marino 	 a DECL_INITIAL value of 0.  */
726e4b17023SJohn Marino       if (! DECL_INITIAL (decl))
727e4b17023SJohn Marino 	return;
728e4b17023SJohn Marino       if (!MEM_P (DECL_RTL (decl))
729e4b17023SJohn Marino 	  || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
730e4b17023SJohn Marino 	return;
731e4b17023SJohn Marino       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
732e4b17023SJohn Marino       PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
733e4b17023SJohn Marino       PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT);
734e4b17023SJohn Marino       break;
735e4b17023SJohn Marino 
736e4b17023SJohn Marino     case TYPE_DECL:
737e4b17023SJohn Marino       /* Done with tagged types.  */
738e4b17023SJohn Marino       if (DECL_NAME (decl) == 0)
739e4b17023SJohn Marino 	return;
740e4b17023SJohn Marino       if (DECL_IGNORED_P (decl))
741e4b17023SJohn Marino 	return;
742e4b17023SJohn Marino       /* Don't output intrinsic types.  GAS chokes on SDB .def
743e4b17023SJohn Marino 	 statements that contain identifiers with embedded spaces
744e4b17023SJohn Marino 	 (eg "unsigned long").  */
745e4b17023SJohn Marino       if (DECL_IS_BUILTIN (decl))
746e4b17023SJohn Marino 	return;
747e4b17023SJohn Marino 
748e4b17023SJohn Marino       /* Output typedef name.  */
749e4b17023SJohn Marino       if (template_name_p (DECL_NAME (decl)))
750e4b17023SJohn Marino 	PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
751e4b17023SJohn Marino       else
752e4b17023SJohn Marino 	PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
753e4b17023SJohn Marino       PUT_SDB_SCL (C_TPDEF);
754e4b17023SJohn Marino       break;
755e4b17023SJohn Marino 
756e4b17023SJohn Marino     case PARM_DECL:
757e4b17023SJohn Marino       /* Parm decls go in their own separate chains
758e4b17023SJohn Marino 	 and are output by sdbout_reg_parms and sdbout_parms.  */
759e4b17023SJohn Marino       gcc_unreachable ();
760e4b17023SJohn Marino 
761e4b17023SJohn Marino     case VAR_DECL:
762e4b17023SJohn Marino       /* Don't mention a variable that is external.
763e4b17023SJohn Marino 	 Let the file that defines it describe it.  */
764e4b17023SJohn Marino       if (DECL_EXTERNAL (decl))
765e4b17023SJohn Marino 	return;
766e4b17023SJohn Marino 
767e4b17023SJohn Marino       /* Ignore __FUNCTION__, etc.  */
768e4b17023SJohn Marino       if (DECL_IGNORED_P (decl))
769e4b17023SJohn Marino 	return;
770e4b17023SJohn Marino 
771e4b17023SJohn Marino       /* If there was an error in the declaration, don't dump core
772e4b17023SJohn Marino 	 if there is no RTL associated with the variable doesn't
773e4b17023SJohn Marino 	 exist.  */
774e4b17023SJohn Marino       if (!DECL_RTL_SET_P (decl))
775e4b17023SJohn Marino 	return;
776e4b17023SJohn Marino 
777e4b17023SJohn Marino       SET_DECL_RTL (decl,
778e4b17023SJohn Marino 		    eliminate_regs (DECL_RTL (decl), VOIDmode, NULL_RTX));
779e4b17023SJohn Marino #ifdef LEAF_REG_REMAP
780e4b17023SJohn Marino       if (current_function_uses_only_leaf_regs)
781e4b17023SJohn Marino 	leaf_renumber_regs_insn (DECL_RTL (decl));
782e4b17023SJohn Marino #endif
783e4b17023SJohn Marino       value = DECL_RTL (decl);
784e4b17023SJohn Marino 
785e4b17023SJohn Marino       /* Don't mention a variable at all
786e4b17023SJohn Marino 	 if it was completely optimized into nothingness.
787e4b17023SJohn Marino 
788e4b17023SJohn Marino 	 If DECL was from an inline function, then its rtl
789e4b17023SJohn Marino 	 is not identically the rtl that was used in this
790e4b17023SJohn Marino 	 particular compilation.  */
791e4b17023SJohn Marino       if (REG_P (value))
792e4b17023SJohn Marino 	{
793e4b17023SJohn Marino 	  regno = REGNO (value);
794e4b17023SJohn Marino 	  if (regno >= FIRST_PSEUDO_REGISTER)
795e4b17023SJohn Marino 	    return;
796e4b17023SJohn Marino 	}
797e4b17023SJohn Marino       else if (GET_CODE (value) == SUBREG)
798e4b17023SJohn Marino 	{
799e4b17023SJohn Marino 	  while (GET_CODE (value) == SUBREG)
800e4b17023SJohn Marino 	    value = SUBREG_REG (value);
801e4b17023SJohn Marino 	  if (REG_P (value))
802e4b17023SJohn Marino 	    {
803e4b17023SJohn Marino 	      if (REGNO (value) >= FIRST_PSEUDO_REGISTER)
804e4b17023SJohn Marino 		return;
805e4b17023SJohn Marino 	    }
806e4b17023SJohn Marino 	  regno = REGNO (alter_subreg (&value));
807e4b17023SJohn Marino 	  SET_DECL_RTL (decl, value);
808e4b17023SJohn Marino 	}
809e4b17023SJohn Marino       /* Don't output anything if an auto variable
810e4b17023SJohn Marino 	 gets RTL that is static.
811e4b17023SJohn Marino 	 GAS version 2.2 can't handle such output.  */
812e4b17023SJohn Marino       else if (MEM_P (value) && CONSTANT_P (XEXP (value, 0))
813e4b17023SJohn Marino 	       && ! TREE_STATIC (decl))
814e4b17023SJohn Marino 	return;
815e4b17023SJohn Marino 
816e4b17023SJohn Marino       /* Emit any structure, union, or enum type that has not been output.
817e4b17023SJohn Marino 	 This occurs for tag-less structs (et al) used to declare variables
818e4b17023SJohn Marino 	 within functions.  */
819e4b17023SJohn Marino       if (TREE_CODE (type) == ENUMERAL_TYPE
820e4b17023SJohn Marino 	  || TREE_CODE (type) == RECORD_TYPE
821e4b17023SJohn Marino 	  || TREE_CODE (type) == UNION_TYPE
822e4b17023SJohn Marino 	  || TREE_CODE (type) == QUAL_UNION_TYPE)
823e4b17023SJohn Marino 	{
824e4b17023SJohn Marino 	  if (COMPLETE_TYPE_P (type)		/* not a forward reference */
825e4b17023SJohn Marino 	      && KNOWN_TYPE_TAG (type) == 0)	/* not yet declared */
826e4b17023SJohn Marino 	    sdbout_one_type (type);
827e4b17023SJohn Marino 	}
828e4b17023SJohn Marino 
829e4b17023SJohn Marino       /* Defer SDB information for top-level initialized variables! */
830e4b17023SJohn Marino       if (! local
831e4b17023SJohn Marino 	  && MEM_P (value)
832e4b17023SJohn Marino 	  && DECL_INITIAL (decl))
833e4b17023SJohn Marino 	return;
834e4b17023SJohn Marino 
835e4b17023SJohn Marino       /* C++ in 2.3 makes nameless symbols.  That will be fixed later.
836e4b17023SJohn Marino 	 For now, avoid crashing.  */
837e4b17023SJohn Marino       if (DECL_NAME (decl) == NULL_TREE)
838e4b17023SJohn Marino 	return;
839e4b17023SJohn Marino 
840e4b17023SJohn Marino       /* Record the name for, starting a symtab entry.  */
841e4b17023SJohn Marino       if (local)
842e4b17023SJohn Marino 	name = IDENTIFIER_POINTER (DECL_NAME (decl));
843e4b17023SJohn Marino       else
844e4b17023SJohn Marino 	name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
845e4b17023SJohn Marino 
846e4b17023SJohn Marino       if (MEM_P (value)
847e4b17023SJohn Marino 	  && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
848e4b17023SJohn Marino 	{
849e4b17023SJohn Marino 	  PUT_SDB_DEF (name);
850e4b17023SJohn Marino 	  if (TREE_PUBLIC (decl))
851e4b17023SJohn Marino 	    {
852e4b17023SJohn Marino 	      PUT_SDB_VAL (XEXP (value, 0));
853e4b17023SJohn Marino 	      PUT_SDB_SCL (C_EXT);
854e4b17023SJohn Marino 	    }
855e4b17023SJohn Marino 	  else
856e4b17023SJohn Marino 	    {
857e4b17023SJohn Marino 	      PUT_SDB_VAL (XEXP (value, 0));
858e4b17023SJohn Marino 	      PUT_SDB_SCL (C_STAT);
859e4b17023SJohn Marino 	    }
860e4b17023SJohn Marino 	}
861e4b17023SJohn Marino       else if (regno >= 0)
862e4b17023SJohn Marino 	{
863e4b17023SJohn Marino 	  PUT_SDB_DEF (name);
864e4b17023SJohn Marino 	  PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno));
865e4b17023SJohn Marino 	  PUT_SDB_SCL (C_REG);
866e4b17023SJohn Marino 	}
867e4b17023SJohn Marino       else if (MEM_P (value)
868e4b17023SJohn Marino 	       && (MEM_P (XEXP (value, 0))
869e4b17023SJohn Marino 		   || (REG_P (XEXP (value, 0))
870e4b17023SJohn Marino 		       && REGNO (XEXP (value, 0)) != HARD_FRAME_POINTER_REGNUM
871e4b17023SJohn Marino 		       && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM)))
872e4b17023SJohn Marino 	/* If the value is indirect by memory or by a register
873e4b17023SJohn Marino 	   that isn't the frame pointer
874e4b17023SJohn Marino 	   then it means the object is variable-sized and address through
875e4b17023SJohn Marino 	   that register or stack slot.  COFF has no way to represent this
876e4b17023SJohn Marino 	   so all we can do is output the variable as a pointer.  */
877e4b17023SJohn Marino 	{
878e4b17023SJohn Marino 	  PUT_SDB_DEF (name);
879e4b17023SJohn Marino 	  if (REG_P (XEXP (value, 0)))
880e4b17023SJohn Marino 	    {
881e4b17023SJohn Marino 	      PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0))));
882e4b17023SJohn Marino 	      PUT_SDB_SCL (C_REG);
883e4b17023SJohn Marino 	    }
884e4b17023SJohn Marino 	  else
885e4b17023SJohn Marino 	    {
886e4b17023SJohn Marino 	      /* DECL_RTL looks like (MEM (MEM (PLUS (REG...)
887e4b17023SJohn Marino 		 (CONST_INT...)))).
888e4b17023SJohn Marino 		 We want the value of that CONST_INT.  */
889e4b17023SJohn Marino 	      /* Encore compiler hates a newline in a macro arg, it seems.  */
890e4b17023SJohn Marino 	      PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET
891e4b17023SJohn Marino 			       (XEXP (XEXP (value, 0), 0)));
892e4b17023SJohn Marino 	      PUT_SDB_SCL (C_AUTO);
893e4b17023SJohn Marino 	    }
894e4b17023SJohn Marino 
895e4b17023SJohn Marino 	  /* Effectively do build_pointer_type, but don't cache this type,
896e4b17023SJohn Marino 	     since it might be temporary whereas the type it points to
897e4b17023SJohn Marino 	     might have been saved for inlining.  */
898e4b17023SJohn Marino 	  /* Don't use REFERENCE_TYPE because dbx can't handle that.  */
899e4b17023SJohn Marino 	  type = make_node (POINTER_TYPE);
900e4b17023SJohn Marino 	  TREE_TYPE (type) = TREE_TYPE (decl);
901e4b17023SJohn Marino 	}
902e4b17023SJohn Marino       else if (MEM_P (value)
903e4b17023SJohn Marino 	       && ((GET_CODE (XEXP (value, 0)) == PLUS
904e4b17023SJohn Marino 		    && REG_P (XEXP (XEXP (value, 0), 0))
905e4b17023SJohn Marino 		    && CONST_INT_P (XEXP (XEXP (value, 0), 1)))
906e4b17023SJohn Marino 		   /* This is for variables which are at offset zero from
907e4b17023SJohn Marino 		      the frame pointer.  This happens on the Alpha.
908e4b17023SJohn Marino 		      Non-frame pointer registers are excluded above.  */
909e4b17023SJohn Marino 		   || (REG_P (XEXP (value, 0)))))
910e4b17023SJohn Marino 	{
911e4b17023SJohn Marino 	  /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
912e4b17023SJohn Marino 	     or (MEM (REG...)).  We want the value of that CONST_INT
913e4b17023SJohn Marino 	     or zero.  */
914e4b17023SJohn Marino 	  PUT_SDB_DEF (name);
915e4b17023SJohn Marino 	  PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0)));
916e4b17023SJohn Marino 	  PUT_SDB_SCL (C_AUTO);
917e4b17023SJohn Marino 	}
918e4b17023SJohn Marino       else
919e4b17023SJohn Marino 	{
920e4b17023SJohn Marino 	  /* It is something we don't know how to represent for SDB.  */
921e4b17023SJohn Marino 	  return;
922e4b17023SJohn Marino 	}
923e4b17023SJohn Marino       break;
924e4b17023SJohn Marino 
925e4b17023SJohn Marino     default:
926e4b17023SJohn Marino       break;
927e4b17023SJohn Marino     }
928e4b17023SJohn Marino   PUT_SDB_TYPE (plain_type (type));
929e4b17023SJohn Marino   PUT_SDB_ENDEF;
930e4b17023SJohn Marino }
931e4b17023SJohn Marino 
932e4b17023SJohn Marino /* Output SDB information for a top-level initialized variable
933e4b17023SJohn Marino    that has been delayed.  */
934e4b17023SJohn Marino 
935e4b17023SJohn Marino static void
sdbout_toplevel_data(tree decl)936e4b17023SJohn Marino sdbout_toplevel_data (tree decl)
937e4b17023SJohn Marino {
938e4b17023SJohn Marino   tree type = TREE_TYPE (decl);
939e4b17023SJohn Marino 
940e4b17023SJohn Marino   if (DECL_IGNORED_P (decl))
941e4b17023SJohn Marino     return;
942e4b17023SJohn Marino 
943e4b17023SJohn Marino   gcc_assert (TREE_CODE (decl) == VAR_DECL);
944e4b17023SJohn Marino   gcc_assert (MEM_P (DECL_RTL (decl)));
945e4b17023SJohn Marino   gcc_assert (DECL_INITIAL (decl));
946e4b17023SJohn Marino 
947e4b17023SJohn Marino   PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
948e4b17023SJohn Marino   PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
949e4b17023SJohn Marino   if (TREE_PUBLIC (decl))
950e4b17023SJohn Marino     {
951e4b17023SJohn Marino       PUT_SDB_SCL (C_EXT);
952e4b17023SJohn Marino     }
953e4b17023SJohn Marino   else
954e4b17023SJohn Marino     {
955e4b17023SJohn Marino       PUT_SDB_SCL (C_STAT);
956e4b17023SJohn Marino     }
957e4b17023SJohn Marino   PUT_SDB_TYPE (plain_type (type));
958e4b17023SJohn Marino   PUT_SDB_ENDEF;
959e4b17023SJohn Marino }
960e4b17023SJohn Marino 
961e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
962e4b17023SJohn Marino 
963e4b17023SJohn Marino /* Machinery to record and output anonymous types.  */
964e4b17023SJohn Marino 
965e4b17023SJohn Marino static void
sdbout_queue_anonymous_type(tree type)966e4b17023SJohn Marino sdbout_queue_anonymous_type (tree type)
967e4b17023SJohn Marino {
968e4b17023SJohn Marino   anonymous_types = tree_cons (NULL_TREE, type, anonymous_types);
969e4b17023SJohn Marino }
970e4b17023SJohn Marino 
971e4b17023SJohn Marino static void
sdbout_dequeue_anonymous_types(void)972e4b17023SJohn Marino sdbout_dequeue_anonymous_types (void)
973e4b17023SJohn Marino {
974e4b17023SJohn Marino   tree types, link;
975e4b17023SJohn Marino 
976e4b17023SJohn Marino   while (anonymous_types)
977e4b17023SJohn Marino     {
978e4b17023SJohn Marino       types = nreverse (anonymous_types);
979e4b17023SJohn Marino       anonymous_types = NULL_TREE;
980e4b17023SJohn Marino 
981e4b17023SJohn Marino       for (link = types; link; link = TREE_CHAIN (link))
982e4b17023SJohn Marino 	{
983e4b17023SJohn Marino 	  tree type = TREE_VALUE (link);
984e4b17023SJohn Marino 
985e4b17023SJohn Marino 	  if (type && ! TREE_ASM_WRITTEN (type))
986e4b17023SJohn Marino 	    sdbout_one_type (type);
987e4b17023SJohn Marino 	}
988e4b17023SJohn Marino     }
989e4b17023SJohn Marino }
990e4b17023SJohn Marino 
991e4b17023SJohn Marino #endif
992e4b17023SJohn Marino 
993e4b17023SJohn Marino /* Given a chain of ..._TYPE nodes, all of which have names,
994e4b17023SJohn Marino    output definitions of those names, as typedefs.  */
995e4b17023SJohn Marino 
996e4b17023SJohn Marino void
sdbout_types(tree types)997e4b17023SJohn Marino sdbout_types (tree types)
998e4b17023SJohn Marino {
999e4b17023SJohn Marino   tree link;
1000e4b17023SJohn Marino 
1001e4b17023SJohn Marino   for (link = types; link; link = TREE_CHAIN (link))
1002e4b17023SJohn Marino     sdbout_one_type (link);
1003e4b17023SJohn Marino 
1004e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
1005e4b17023SJohn Marino   sdbout_dequeue_anonymous_types ();
1006e4b17023SJohn Marino #endif
1007e4b17023SJohn Marino }
1008e4b17023SJohn Marino 
1009e4b17023SJohn Marino static void
sdbout_type(tree type)1010e4b17023SJohn Marino sdbout_type (tree type)
1011e4b17023SJohn Marino {
1012e4b17023SJohn Marino   if (type == error_mark_node)
1013e4b17023SJohn Marino     type = integer_type_node;
1014e4b17023SJohn Marino   PUT_SDB_TYPE (plain_type (type));
1015e4b17023SJohn Marino }
1016e4b17023SJohn Marino 
1017e4b17023SJohn Marino /* Output types of the fields of type TYPE, if they are structs.
1018e4b17023SJohn Marino 
1019e4b17023SJohn Marino    Formerly did not chase through pointer types, since that could be circular.
1020e4b17023SJohn Marino    They must come before TYPE, since forward refs are not allowed.
1021e4b17023SJohn Marino    Now james@bigtex.cactus.org says to try them.  */
1022e4b17023SJohn Marino 
1023e4b17023SJohn Marino static void
sdbout_field_types(tree type)1024e4b17023SJohn Marino sdbout_field_types (tree type)
1025e4b17023SJohn Marino {
1026e4b17023SJohn Marino   tree tail;
1027e4b17023SJohn Marino 
1028e4b17023SJohn Marino   for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
1029e4b17023SJohn Marino     /* This condition should match the one for emitting the actual
1030e4b17023SJohn Marino        members below.  */
1031e4b17023SJohn Marino     if (TREE_CODE (tail) == FIELD_DECL
1032e4b17023SJohn Marino 	&& DECL_NAME (tail)
1033e4b17023SJohn Marino 	&& DECL_SIZE (tail)
1034e4b17023SJohn Marino 	&& host_integerp (DECL_SIZE (tail), 1)
1035e4b17023SJohn Marino 	&& host_integerp (bit_position (tail), 0))
1036e4b17023SJohn Marino       {
1037e4b17023SJohn Marino 	if (POINTER_TYPE_P (TREE_TYPE (tail)))
1038e4b17023SJohn Marino 	  sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
1039e4b17023SJohn Marino 	else
1040e4b17023SJohn Marino 	  sdbout_one_type (TREE_TYPE (tail));
1041e4b17023SJohn Marino       }
1042e4b17023SJohn Marino }
1043e4b17023SJohn Marino 
1044e4b17023SJohn Marino /* Use this to put out the top level defined record and union types
1045e4b17023SJohn Marino    for later reference.  If this is a struct with a name, then put that
1046e4b17023SJohn Marino    name out.  Other unnamed structs will have .xxfake labels generated so
1047e4b17023SJohn Marino    that they may be referred to later.
1048e4b17023SJohn Marino    The label will be stored in the KNOWN_TYPE_TAG slot of a type.
1049e4b17023SJohn Marino    It may NOT be called recursively.  */
1050e4b17023SJohn Marino 
1051e4b17023SJohn Marino static void
sdbout_one_type(tree type)1052e4b17023SJohn Marino sdbout_one_type (tree type)
1053e4b17023SJohn Marino {
1054e4b17023SJohn Marino   if (current_function_decl != NULL_TREE
1055e4b17023SJohn Marino       && DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
1056e4b17023SJohn Marino     ; /* Don't change section amid function.  */
1057e4b17023SJohn Marino   else
1058e4b17023SJohn Marino     switch_to_section (text_section);
1059e4b17023SJohn Marino 
1060e4b17023SJohn Marino   switch (TREE_CODE (type))
1061e4b17023SJohn Marino     {
1062e4b17023SJohn Marino     case RECORD_TYPE:
1063e4b17023SJohn Marino     case UNION_TYPE:
1064e4b17023SJohn Marino     case QUAL_UNION_TYPE:
1065e4b17023SJohn Marino     case ENUMERAL_TYPE:
1066e4b17023SJohn Marino       type = TYPE_MAIN_VARIANT (type);
1067e4b17023SJohn Marino       /* Don't output a type twice.  */
1068e4b17023SJohn Marino       if (TREE_ASM_WRITTEN (type))
1069e4b17023SJohn Marino 	/* James said test TREE_ASM_BEING_WRITTEN here.  */
1070e4b17023SJohn Marino 	return;
1071e4b17023SJohn Marino 
1072e4b17023SJohn Marino       /* Output nothing if type is not yet defined.  */
1073e4b17023SJohn Marino       if (!COMPLETE_TYPE_P (type))
1074e4b17023SJohn Marino 	return;
1075e4b17023SJohn Marino 
1076e4b17023SJohn Marino       TREE_ASM_WRITTEN (type) = 1;
1077e4b17023SJohn Marino 
1078e4b17023SJohn Marino       /* This is reputed to cause trouble with the following case,
1079e4b17023SJohn Marino 	 but perhaps checking TYPE_SIZE above will fix it.  */
1080e4b17023SJohn Marino 
1081e4b17023SJohn Marino       /* Here is a testcase:
1082e4b17023SJohn Marino 
1083e4b17023SJohn Marino 	struct foo {
1084e4b17023SJohn Marino 	  struct badstr *bbb;
1085e4b17023SJohn Marino 	} forwardref;
1086e4b17023SJohn Marino 
1087e4b17023SJohn Marino 	typedef struct intermediate {
1088e4b17023SJohn Marino 	  int aaaa;
1089e4b17023SJohn Marino 	} intermediate_ref;
1090e4b17023SJohn Marino 
1091e4b17023SJohn Marino 	typedef struct badstr {
1092e4b17023SJohn Marino 	  int ccccc;
1093e4b17023SJohn Marino 	} badtype;   */
1094e4b17023SJohn Marino 
1095e4b17023SJohn Marino       /* This change, which ought to make better output,
1096e4b17023SJohn Marino 	 used to make the COFF assembler unhappy.
1097e4b17023SJohn Marino 	 Changes involving KNOWN_TYPE_TAG may fix the problem.  */
1098e4b17023SJohn Marino       /* Before really doing anything, output types we want to refer to.  */
1099e4b17023SJohn Marino       /* Note that in version 1 the following two lines
1100e4b17023SJohn Marino 	 are not used if forward references are in use.  */
1101e4b17023SJohn Marino       if (TREE_CODE (type) != ENUMERAL_TYPE)
1102e4b17023SJohn Marino 	sdbout_field_types (type);
1103e4b17023SJohn Marino 
1104e4b17023SJohn Marino       /* Output a structure type.  */
1105e4b17023SJohn Marino       {
1106e4b17023SJohn Marino 	int size = int_size_in_bytes (type);
1107e4b17023SJohn Marino 	int member_scl = 0;
1108e4b17023SJohn Marino 	tree tem;
1109e4b17023SJohn Marino 
1110e4b17023SJohn Marino 	/* Record the type tag, but not in its permanent place just yet.  */
1111e4b17023SJohn Marino 	sdbout_record_type_name (type);
1112e4b17023SJohn Marino 
1113e4b17023SJohn Marino 	PUT_SDB_DEF (KNOWN_TYPE_TAG (type));
1114e4b17023SJohn Marino 
1115e4b17023SJohn Marino 	switch (TREE_CODE (type))
1116e4b17023SJohn Marino 	  {
1117e4b17023SJohn Marino 	  case UNION_TYPE:
1118e4b17023SJohn Marino 	  case QUAL_UNION_TYPE:
1119e4b17023SJohn Marino 	    PUT_SDB_SCL (C_UNTAG);
1120e4b17023SJohn Marino 	    PUT_SDB_TYPE (T_UNION);
1121e4b17023SJohn Marino 	    member_scl = C_MOU;
1122e4b17023SJohn Marino 	    break;
1123e4b17023SJohn Marino 
1124e4b17023SJohn Marino 	  case RECORD_TYPE:
1125e4b17023SJohn Marino 	    PUT_SDB_SCL (C_STRTAG);
1126e4b17023SJohn Marino 	    PUT_SDB_TYPE (T_STRUCT);
1127e4b17023SJohn Marino 	    member_scl = C_MOS;
1128e4b17023SJohn Marino 	    break;
1129e4b17023SJohn Marino 
1130e4b17023SJohn Marino 	  case ENUMERAL_TYPE:
1131e4b17023SJohn Marino 	    PUT_SDB_SCL (C_ENTAG);
1132e4b17023SJohn Marino 	    PUT_SDB_TYPE (T_ENUM);
1133e4b17023SJohn Marino 	    member_scl = C_MOE;
1134e4b17023SJohn Marino 	    break;
1135e4b17023SJohn Marino 
1136e4b17023SJohn Marino 	  default:
1137e4b17023SJohn Marino 	    break;
1138e4b17023SJohn Marino 	  }
1139e4b17023SJohn Marino 
1140e4b17023SJohn Marino 	PUT_SDB_SIZE (size);
1141e4b17023SJohn Marino 	PUT_SDB_ENDEF;
1142e4b17023SJohn Marino 
1143e4b17023SJohn Marino 	/* Print out the base class information with fields
1144e4b17023SJohn Marino 	   named after the types they hold.  */
1145e4b17023SJohn Marino 	/* This is only relevant to aggregate types.  TYPE_BINFO is used
1146e4b17023SJohn Marino 	   for other purposes in an ENUMERAL_TYPE, so we must exclude that
1147e4b17023SJohn Marino 	   case.  */
1148e4b17023SJohn Marino 	if (TREE_CODE (type) != ENUMERAL_TYPE && TYPE_BINFO (type))
1149e4b17023SJohn Marino 	  {
1150e4b17023SJohn Marino 	    int i;
1151e4b17023SJohn Marino 	    tree binfo, child;
1152e4b17023SJohn Marino 
1153e4b17023SJohn Marino 	    for (binfo = TYPE_BINFO (type), i = 0;
1154e4b17023SJohn Marino 		 BINFO_BASE_ITERATE (binfo, i, child); i++)
1155e4b17023SJohn Marino 	      {
1156e4b17023SJohn Marino 		tree child_type = BINFO_TYPE (child);
1157e4b17023SJohn Marino 		tree child_type_name;
1158e4b17023SJohn Marino 
1159e4b17023SJohn Marino 		if (TYPE_NAME (child_type) == 0)
1160e4b17023SJohn Marino 		  continue;
1161e4b17023SJohn Marino 		if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
1162e4b17023SJohn Marino 		  child_type_name = TYPE_NAME (child_type);
1163e4b17023SJohn Marino 		else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL)
1164e4b17023SJohn Marino 		  {
1165e4b17023SJohn Marino 		    child_type_name = DECL_NAME (TYPE_NAME (child_type));
1166e4b17023SJohn Marino 		    if (child_type_name && template_name_p (child_type_name))
1167e4b17023SJohn Marino 		      child_type_name
1168e4b17023SJohn Marino 			= DECL_ASSEMBLER_NAME (TYPE_NAME (child_type));
1169e4b17023SJohn Marino 		  }
1170e4b17023SJohn Marino 		else
1171e4b17023SJohn Marino 		  continue;
1172e4b17023SJohn Marino 
1173e4b17023SJohn Marino 		PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
1174e4b17023SJohn Marino 		PUT_SDB_INT_VAL (tree_low_cst (BINFO_OFFSET (child), 0));
1175e4b17023SJohn Marino 		PUT_SDB_SCL (member_scl);
1176e4b17023SJohn Marino 		sdbout_type (BINFO_TYPE (child));
1177e4b17023SJohn Marino 		PUT_SDB_ENDEF;
1178e4b17023SJohn Marino 	      }
1179e4b17023SJohn Marino 	  }
1180e4b17023SJohn Marino 
1181e4b17023SJohn Marino 	/* Output the individual fields.  */
1182e4b17023SJohn Marino 
1183e4b17023SJohn Marino 	if (TREE_CODE (type) == ENUMERAL_TYPE)
1184e4b17023SJohn Marino 	  {
1185e4b17023SJohn Marino 	    for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
1186e4b17023SJohn Marino 	      {
1187e4b17023SJohn Marino 	        tree value = TREE_VALUE (tem);
1188e4b17023SJohn Marino 
1189e4b17023SJohn Marino 	        if (TREE_CODE (value) == CONST_DECL)
1190e4b17023SJohn Marino 	          value = DECL_INITIAL (value);
1191e4b17023SJohn Marino 
1192e4b17023SJohn Marino 	        if (host_integerp (value, 0))
1193e4b17023SJohn Marino 		  {
1194e4b17023SJohn Marino 		    PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
1195e4b17023SJohn Marino 		    PUT_SDB_INT_VAL (tree_low_cst (value, 0));
1196e4b17023SJohn Marino 		    PUT_SDB_SCL (C_MOE);
1197e4b17023SJohn Marino 		    PUT_SDB_TYPE (T_MOE);
1198e4b17023SJohn Marino 		    PUT_SDB_ENDEF;
1199e4b17023SJohn Marino 		  }
1200e4b17023SJohn Marino 	      }
1201e4b17023SJohn Marino 	  }
1202e4b17023SJohn Marino 	else			/* record or union type */
1203e4b17023SJohn Marino 	  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
1204e4b17023SJohn Marino 	    /* Output the name, type, position (in bits), size (in bits)
1205e4b17023SJohn Marino 	       of each field.  */
1206e4b17023SJohn Marino 
1207e4b17023SJohn Marino 	    /* Omit here the nameless fields that are used to skip bits.
1208e4b17023SJohn Marino 	       Also omit fields with variable size or position.
1209e4b17023SJohn Marino 	       Also omit non FIELD_DECL nodes that GNU C++ may put here.  */
1210e4b17023SJohn Marino 	    if (TREE_CODE (tem) == FIELD_DECL
1211e4b17023SJohn Marino 		&& DECL_NAME (tem)
1212e4b17023SJohn Marino 		&& DECL_SIZE (tem)
1213e4b17023SJohn Marino 		&& host_integerp (DECL_SIZE (tem), 1)
1214e4b17023SJohn Marino 		&& host_integerp (bit_position (tem), 0))
1215e4b17023SJohn Marino 	      {
1216e4b17023SJohn Marino 		const char *name;
1217e4b17023SJohn Marino 
1218e4b17023SJohn Marino 		name = IDENTIFIER_POINTER (DECL_NAME (tem));
1219e4b17023SJohn Marino 		PUT_SDB_DEF (name);
1220e4b17023SJohn Marino 		if (DECL_BIT_FIELD_TYPE (tem))
1221e4b17023SJohn Marino 		  {
1222e4b17023SJohn Marino 		    PUT_SDB_INT_VAL (int_bit_position (tem));
1223e4b17023SJohn Marino 		    PUT_SDB_SCL (C_FIELD);
1224e4b17023SJohn Marino 		    sdbout_type (DECL_BIT_FIELD_TYPE (tem));
1225e4b17023SJohn Marino 		    PUT_SDB_SIZE (tree_low_cst (DECL_SIZE (tem), 1));
1226e4b17023SJohn Marino 		  }
1227e4b17023SJohn Marino 		else
1228e4b17023SJohn Marino 		  {
1229e4b17023SJohn Marino 		    PUT_SDB_INT_VAL (int_bit_position (tem) / BITS_PER_UNIT);
1230e4b17023SJohn Marino 		    PUT_SDB_SCL (member_scl);
1231e4b17023SJohn Marino 		    sdbout_type (TREE_TYPE (tem));
1232e4b17023SJohn Marino 		  }
1233e4b17023SJohn Marino 		PUT_SDB_ENDEF;
1234e4b17023SJohn Marino 	      }
1235e4b17023SJohn Marino 	/* Output end of a structure,union, or enumeral definition.  */
1236e4b17023SJohn Marino 
1237e4b17023SJohn Marino 	PUT_SDB_PLAIN_DEF ("eos");
1238e4b17023SJohn Marino 	PUT_SDB_INT_VAL (size);
1239e4b17023SJohn Marino 	PUT_SDB_SCL (C_EOS);
1240e4b17023SJohn Marino 	PUT_SDB_TAG (KNOWN_TYPE_TAG (type));
1241e4b17023SJohn Marino 	PUT_SDB_SIZE (size);
1242e4b17023SJohn Marino 	PUT_SDB_ENDEF;
1243e4b17023SJohn Marino 	break;
1244e4b17023SJohn Marino       }
1245e4b17023SJohn Marino 
1246e4b17023SJohn Marino     default:
1247e4b17023SJohn Marino       break;
1248e4b17023SJohn Marino     }
1249e4b17023SJohn Marino }
1250e4b17023SJohn Marino 
1251e4b17023SJohn Marino /* The following two functions output definitions of function parameters.
1252e4b17023SJohn Marino    Each parameter gets a definition locating it in the parameter list.
1253e4b17023SJohn Marino    Each parameter that is a register variable gets a second definition
1254e4b17023SJohn Marino    locating it in the register.
1255e4b17023SJohn Marino 
1256e4b17023SJohn Marino    Printing or argument lists in gdb uses the definitions that
1257e4b17023SJohn Marino    locate in the parameter list.  But reference to the variable in
1258e4b17023SJohn Marino    expressions uses preferentially the definition as a register.  */
1259e4b17023SJohn Marino 
1260e4b17023SJohn Marino /* Output definitions, referring to storage in the parmlist,
1261e4b17023SJohn Marino    of all the parms in PARMS, which is a chain of PARM_DECL nodes.  */
1262e4b17023SJohn Marino 
1263e4b17023SJohn Marino static void
sdbout_parms(tree parms)1264e4b17023SJohn Marino sdbout_parms (tree parms)
1265e4b17023SJohn Marino {
1266e4b17023SJohn Marino   for (; parms; parms = TREE_CHAIN (parms))
1267*95d28233SJohn Marino     if (DECL_NAME (parms)
1268*95d28233SJohn Marino 	&& TREE_TYPE (parms) != error_mark_node
1269*95d28233SJohn Marino 	&& DECL_RTL_SET_P (parms)
1270*95d28233SJohn Marino 	&& DECL_INCOMING_RTL (parms))
1271e4b17023SJohn Marino       {
1272e4b17023SJohn Marino 	int current_sym_value = 0;
1273e4b17023SJohn Marino 	const char *name = IDENTIFIER_POINTER (DECL_NAME (parms));
1274e4b17023SJohn Marino 
1275e4b17023SJohn Marino 	if (name == 0 || *name == 0)
1276e4b17023SJohn Marino 	  name = gen_fake_label ();
1277e4b17023SJohn Marino 
1278e4b17023SJohn Marino 	/* Perform any necessary register eliminations on the parameter's rtl,
1279e4b17023SJohn Marino 	   so that the debugging output will be accurate.  */
1280e4b17023SJohn Marino 	DECL_INCOMING_RTL (parms)
1281e4b17023SJohn Marino 	  = eliminate_regs (DECL_INCOMING_RTL (parms), VOIDmode, NULL_RTX);
1282e4b17023SJohn Marino 	SET_DECL_RTL (parms,
1283e4b17023SJohn Marino 		      eliminate_regs (DECL_RTL (parms), VOIDmode, NULL_RTX));
1284e4b17023SJohn Marino 
1285e4b17023SJohn Marino 	if (PARM_PASSED_IN_MEMORY (parms))
1286e4b17023SJohn Marino 	  {
1287e4b17023SJohn Marino 	    rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
1288e4b17023SJohn Marino 	    tree type;
1289e4b17023SJohn Marino 
1290e4b17023SJohn Marino 	    /* ??? Here we assume that the parm address is indexed
1291e4b17023SJohn Marino 	       off the frame pointer or arg pointer.
1292e4b17023SJohn Marino 	       If that is not true, we produce meaningless results,
1293e4b17023SJohn Marino 	       but do not crash.  */
1294e4b17023SJohn Marino 	    if (GET_CODE (addr) == PLUS
1295e4b17023SJohn Marino 		&& CONST_INT_P (XEXP (addr, 1)))
1296e4b17023SJohn Marino 	      current_sym_value = INTVAL (XEXP (addr, 1));
1297e4b17023SJohn Marino 	    else
1298e4b17023SJohn Marino 	      current_sym_value = 0;
1299e4b17023SJohn Marino 
1300e4b17023SJohn Marino 	    if (REG_P (DECL_RTL (parms))
1301e4b17023SJohn Marino 		&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
1302e4b17023SJohn Marino 	      type = DECL_ARG_TYPE (parms);
1303e4b17023SJohn Marino 	    else
1304e4b17023SJohn Marino 	      {
1305e4b17023SJohn Marino 		int original_sym_value = current_sym_value;
1306e4b17023SJohn Marino 
1307e4b17023SJohn Marino 		/* This is the case where the parm is passed as an int or
1308e4b17023SJohn Marino 		   double and it is converted to a char, short or float
1309e4b17023SJohn Marino 		   and stored back in the parmlist.  In this case, describe
1310e4b17023SJohn Marino 		   the parm with the variable's declared type, and adjust
1311e4b17023SJohn Marino 		   the address if the least significant bytes (which we are
1312e4b17023SJohn Marino 		   using) are not the first ones.  */
1313e4b17023SJohn Marino 		if (BYTES_BIG_ENDIAN
1314e4b17023SJohn Marino 		    && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
1315e4b17023SJohn Marino 		  current_sym_value +=
1316e4b17023SJohn Marino 		    (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
1317e4b17023SJohn Marino 		     - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
1318e4b17023SJohn Marino 
1319e4b17023SJohn Marino 		if (MEM_P (DECL_RTL (parms))
1320e4b17023SJohn Marino 		    && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
1321e4b17023SJohn Marino 		    && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
1322e4b17023SJohn Marino 			== CONST_INT)
1323e4b17023SJohn Marino 		    && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1))
1324e4b17023SJohn Marino 			== current_sym_value))
1325e4b17023SJohn Marino 		  type = TREE_TYPE (parms);
1326e4b17023SJohn Marino 		else
1327e4b17023SJohn Marino 		  {
1328e4b17023SJohn Marino 		    current_sym_value = original_sym_value;
1329e4b17023SJohn Marino 		    type = DECL_ARG_TYPE (parms);
1330e4b17023SJohn Marino 		  }
1331e4b17023SJohn Marino 	      }
1332e4b17023SJohn Marino 
1333e4b17023SJohn Marino 	    PUT_SDB_DEF (name);
1334e4b17023SJohn Marino 	    PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, addr));
1335e4b17023SJohn Marino 	    PUT_SDB_SCL (C_ARG);
1336e4b17023SJohn Marino 	    PUT_SDB_TYPE (plain_type (type));
1337e4b17023SJohn Marino 	    PUT_SDB_ENDEF;
1338e4b17023SJohn Marino 	  }
1339e4b17023SJohn Marino 	else if (REG_P (DECL_RTL (parms)))
1340e4b17023SJohn Marino 	  {
1341e4b17023SJohn Marino 	    rtx best_rtl;
1342e4b17023SJohn Marino 	    /* Parm passed in registers and lives in registers or nowhere.  */
1343e4b17023SJohn Marino 
1344e4b17023SJohn Marino 	    /* If parm lives in a register, use that register;
1345e4b17023SJohn Marino 	       pretend the parm was passed there.  It would be more consistent
1346e4b17023SJohn Marino 	       to describe the register where the parm was passed,
1347e4b17023SJohn Marino 	       but in practice that register usually holds something else.  */
1348e4b17023SJohn Marino 	    if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
1349e4b17023SJohn Marino 	      best_rtl = DECL_RTL (parms);
1350e4b17023SJohn Marino 	    /* If the parm lives nowhere,
1351e4b17023SJohn Marino 	       use the register where it was passed.  */
1352e4b17023SJohn Marino 	    else
1353e4b17023SJohn Marino 	      best_rtl = DECL_INCOMING_RTL (parms);
1354e4b17023SJohn Marino 
1355e4b17023SJohn Marino 	    PUT_SDB_DEF (name);
1356e4b17023SJohn Marino 	    PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl)));
1357e4b17023SJohn Marino 	    PUT_SDB_SCL (C_REGPARM);
1358e4b17023SJohn Marino 	    PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
1359e4b17023SJohn Marino 	    PUT_SDB_ENDEF;
1360e4b17023SJohn Marino 	  }
1361e4b17023SJohn Marino 	else if (MEM_P (DECL_RTL (parms))
1362e4b17023SJohn Marino 		 && XEXP (DECL_RTL (parms), 0) != const0_rtx)
1363e4b17023SJohn Marino 	  {
1364e4b17023SJohn Marino 	    /* Parm was passed in registers but lives on the stack.  */
1365e4b17023SJohn Marino 
1366e4b17023SJohn Marino 	    /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))),
1367e4b17023SJohn Marino 	       in which case we want the value of that CONST_INT,
1368e4b17023SJohn Marino 	       or (MEM (REG ...)) or (MEM (MEM ...)),
1369e4b17023SJohn Marino 	       in which case we use a value of zero.  */
1370e4b17023SJohn Marino 	    if (REG_P (XEXP (DECL_RTL (parms), 0))
1371e4b17023SJohn Marino 		|| MEM_P (XEXP (DECL_RTL (parms), 0)))
1372e4b17023SJohn Marino 	      current_sym_value = 0;
1373e4b17023SJohn Marino 	    else
1374e4b17023SJohn Marino 	      current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
1375e4b17023SJohn Marino 
1376e4b17023SJohn Marino 	    /* Again, this assumes the offset is based on the arg pointer.  */
1377e4b17023SJohn Marino 	    PUT_SDB_DEF (name);
1378e4b17023SJohn Marino 	    PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value,
1379e4b17023SJohn Marino 						  XEXP (DECL_RTL (parms), 0)));
1380e4b17023SJohn Marino 	    PUT_SDB_SCL (C_ARG);
1381e4b17023SJohn Marino 	    PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
1382e4b17023SJohn Marino 	    PUT_SDB_ENDEF;
1383e4b17023SJohn Marino 	  }
1384e4b17023SJohn Marino       }
1385e4b17023SJohn Marino }
1386e4b17023SJohn Marino 
1387e4b17023SJohn Marino /* Output definitions for the places where parms live during the function,
1388e4b17023SJohn Marino    when different from where they were passed, when the parms were passed
1389e4b17023SJohn Marino    in memory.
1390e4b17023SJohn Marino 
1391e4b17023SJohn Marino    It is not useful to do this for parms passed in registers
1392e4b17023SJohn Marino    that live during the function in different registers, because it is
1393e4b17023SJohn Marino    impossible to look in the passed register for the passed value,
1394e4b17023SJohn Marino    so we use the within-the-function register to begin with.
1395e4b17023SJohn Marino 
1396e4b17023SJohn Marino    PARMS is a chain of PARM_DECL nodes.  */
1397e4b17023SJohn Marino 
1398e4b17023SJohn Marino static void
sdbout_reg_parms(tree parms)1399e4b17023SJohn Marino sdbout_reg_parms (tree parms)
1400e4b17023SJohn Marino {
1401e4b17023SJohn Marino   for (; parms; parms = TREE_CHAIN (parms))
1402*95d28233SJohn Marino     if (DECL_NAME (parms)
1403*95d28233SJohn Marino         && TREE_TYPE (parms) != error_mark_node
1404*95d28233SJohn Marino         && DECL_RTL_SET_P (parms)
1405*95d28233SJohn Marino         && DECL_INCOMING_RTL (parms))
1406e4b17023SJohn Marino       {
1407e4b17023SJohn Marino 	const char *name = IDENTIFIER_POINTER (DECL_NAME (parms));
1408e4b17023SJohn Marino 
1409e4b17023SJohn Marino 	/* Report parms that live in registers during the function
1410e4b17023SJohn Marino 	   but were passed in memory.  */
1411e4b17023SJohn Marino 	if (REG_P (DECL_RTL (parms))
1412e4b17023SJohn Marino 	    && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
1413e4b17023SJohn Marino 	    && PARM_PASSED_IN_MEMORY (parms))
1414e4b17023SJohn Marino 	  {
1415e4b17023SJohn Marino 	    if (name == 0 || *name == 0)
1416e4b17023SJohn Marino 	      name = gen_fake_label ();
1417e4b17023SJohn Marino 	    PUT_SDB_DEF (name);
1418e4b17023SJohn Marino 	    PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))));
1419e4b17023SJohn Marino 	    PUT_SDB_SCL (C_REG);
1420e4b17023SJohn Marino 	    PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
1421e4b17023SJohn Marino 	    PUT_SDB_ENDEF;
1422e4b17023SJohn Marino 	  }
1423e4b17023SJohn Marino 	/* Report parms that live in memory but not where they were passed.  */
1424e4b17023SJohn Marino 	else if (MEM_P (DECL_RTL (parms))
1425e4b17023SJohn Marino 		 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
1426e4b17023SJohn Marino 		 && CONST_INT_P (XEXP (XEXP (DECL_RTL (parms), 0), 1))
1427e4b17023SJohn Marino 		 && PARM_PASSED_IN_MEMORY (parms)
1428e4b17023SJohn Marino 		 && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms)))
1429e4b17023SJohn Marino 	  {
1430e4b17023SJohn Marino #if 0 /* ??? It is not clear yet what should replace this.  */
1431e4b17023SJohn Marino 	    int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
1432e4b17023SJohn Marino 	    /* A parm declared char is really passed as an int,
1433e4b17023SJohn Marino 	       so it occupies the least significant bytes.
1434e4b17023SJohn Marino 	       On a big-endian machine those are not the low-numbered ones.  */
1435e4b17023SJohn Marino 	    if (BYTES_BIG_ENDIAN
1436e4b17023SJohn Marino 		&& offset != -1
1437e4b17023SJohn Marino 		&& TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
1438e4b17023SJohn Marino 	      offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
1439e4b17023SJohn Marino 			 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
1440e4b17023SJohn Marino 	    if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
1441e4b17023SJohn Marino #endif
1442e4b17023SJohn Marino 	      {
1443e4b17023SJohn Marino 		if (name == 0 || *name == 0)
1444e4b17023SJohn Marino 		  name = gen_fake_label ();
1445e4b17023SJohn Marino 		PUT_SDB_DEF (name);
1446e4b17023SJohn Marino 		PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET
1447e4b17023SJohn Marino 				 (XEXP (DECL_RTL (parms), 0)));
1448e4b17023SJohn Marino 		PUT_SDB_SCL (C_AUTO);
1449e4b17023SJohn Marino 		PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
1450e4b17023SJohn Marino 		PUT_SDB_ENDEF;
1451e4b17023SJohn Marino 	      }
1452e4b17023SJohn Marino 	  }
1453e4b17023SJohn Marino       }
1454e4b17023SJohn Marino }
1455e4b17023SJohn Marino 
1456e4b17023SJohn Marino /* Output debug information for a global DECL.  Called from toplev.c
1457e4b17023SJohn Marino    after compilation proper has finished.  */
1458e4b17023SJohn Marino 
1459e4b17023SJohn Marino static void
sdbout_global_decl(tree decl)1460e4b17023SJohn Marino sdbout_global_decl (tree decl)
1461e4b17023SJohn Marino {
1462e4b17023SJohn Marino   if (TREE_CODE (decl) == VAR_DECL
1463e4b17023SJohn Marino       && !DECL_EXTERNAL (decl)
1464e4b17023SJohn Marino       && DECL_RTL_SET_P (decl))
1465e4b17023SJohn Marino     {
1466e4b17023SJohn Marino       /* The COFF linker can move initialized global vars to the end.
1467e4b17023SJohn Marino 	 And that can screw up the symbol ordering.  Defer those for
1468e4b17023SJohn Marino 	 sdbout_finish ().  */
1469e4b17023SJohn Marino       if (!DECL_INITIAL (decl) || !TREE_PUBLIC (decl))
1470e4b17023SJohn Marino 	sdbout_symbol (decl, 0);
1471e4b17023SJohn Marino       else
1472e4b17023SJohn Marino 	VEC_safe_push (tree, gc, deferred_global_decls, decl);
1473e4b17023SJohn Marino 
1474e4b17023SJohn Marino       /* Output COFF information for non-global file-scope initialized
1475e4b17023SJohn Marino 	 variables.  */
1476e4b17023SJohn Marino       if (DECL_INITIAL (decl) && MEM_P (DECL_RTL (decl)))
1477e4b17023SJohn Marino 	sdbout_toplevel_data (decl);
1478e4b17023SJohn Marino     }
1479e4b17023SJohn Marino }
1480e4b17023SJohn Marino 
1481e4b17023SJohn Marino /* Output initialized global vars at the end, in the order of
1482e4b17023SJohn Marino    definition.  See comment in sdbout_global_decl.  */
1483e4b17023SJohn Marino 
1484e4b17023SJohn Marino static void
sdbout_finish(const char * main_filename ATTRIBUTE_UNUSED)1485e4b17023SJohn Marino sdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
1486e4b17023SJohn Marino {
1487e4b17023SJohn Marino   size_t i;
1488e4b17023SJohn Marino   tree decl;
1489e4b17023SJohn Marino 
1490e4b17023SJohn Marino   FOR_EACH_VEC_ELT (tree, deferred_global_decls, i, decl)
1491e4b17023SJohn Marino     sdbout_symbol (decl, 0);
1492e4b17023SJohn Marino }
1493e4b17023SJohn Marino 
1494e4b17023SJohn Marino /* Describe the beginning of an internal block within a function.
1495e4b17023SJohn Marino    Also output descriptions of variables defined in this block.
1496e4b17023SJohn Marino 
1497e4b17023SJohn Marino    N is the number of the block, by order of beginning, counting from 1,
1498e4b17023SJohn Marino    and not counting the outermost (function top-level) block.
1499e4b17023SJohn Marino    The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
1500e4b17023SJohn Marino    if the count starts at 0 for the outermost one.  */
1501e4b17023SJohn Marino 
1502e4b17023SJohn Marino static void
sdbout_begin_block(unsigned int line,unsigned int n)1503e4b17023SJohn Marino sdbout_begin_block (unsigned int line, unsigned int n)
1504e4b17023SJohn Marino {
1505e4b17023SJohn Marino   tree decl = current_function_decl;
1506e4b17023SJohn Marino   MAKE_LINE_SAFE (line);
1507e4b17023SJohn Marino 
1508e4b17023SJohn Marino   /* The SCO compiler does not emit a separate block for the function level
1509e4b17023SJohn Marino      scope, so we avoid it here also.  However, mips ECOFF compilers do emit
1510e4b17023SJohn Marino      a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined.  */
1511e4b17023SJohn Marino #ifndef MIPS_DEBUGGING_INFO
1512e4b17023SJohn Marino   if (n != 1)
1513e4b17023SJohn Marino #endif
1514e4b17023SJohn Marino     PUT_SDB_BLOCK_START (line - sdb_begin_function_line);
1515e4b17023SJohn Marino 
1516e4b17023SJohn Marino   if (n == 1)
1517e4b17023SJohn Marino     {
1518e4b17023SJohn Marino       /* Include the outermost BLOCK's variables in block 1.  */
1519e4b17023SJohn Marino       do_block = BLOCK_NUMBER (DECL_INITIAL (decl));
1520e4b17023SJohn Marino       sdbout_block (DECL_INITIAL (decl));
1521e4b17023SJohn Marino     }
1522e4b17023SJohn Marino   /* If -g1, suppress all the internal symbols of functions
1523e4b17023SJohn Marino      except for arguments.  */
1524e4b17023SJohn Marino   if (debug_info_level != DINFO_LEVEL_TERSE)
1525e4b17023SJohn Marino     {
1526e4b17023SJohn Marino       do_block = n;
1527e4b17023SJohn Marino       sdbout_block (DECL_INITIAL (decl));
1528e4b17023SJohn Marino     }
1529e4b17023SJohn Marino 
1530e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
1531e4b17023SJohn Marino   sdbout_dequeue_anonymous_types ();
1532e4b17023SJohn Marino #endif
1533e4b17023SJohn Marino }
1534e4b17023SJohn Marino 
1535e4b17023SJohn Marino /* Describe the end line-number of an internal block within a function.  */
1536e4b17023SJohn Marino 
1537e4b17023SJohn Marino static void
sdbout_end_block(unsigned int line,unsigned int n ATTRIBUTE_UNUSED)1538e4b17023SJohn Marino sdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED)
1539e4b17023SJohn Marino {
1540e4b17023SJohn Marino   MAKE_LINE_SAFE (line);
1541e4b17023SJohn Marino 
1542e4b17023SJohn Marino   /* The SCO compiler does not emit a separate block for the function level
1543e4b17023SJohn Marino      scope, so we avoid it here also.  However, mips ECOFF compilers do emit
1544e4b17023SJohn Marino      a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined.  */
1545e4b17023SJohn Marino #ifndef MIPS_DEBUGGING_INFO
1546e4b17023SJohn Marino   if (n != 1)
1547e4b17023SJohn Marino #endif
1548e4b17023SJohn Marino   PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
1549e4b17023SJohn Marino }
1550e4b17023SJohn Marino 
1551e4b17023SJohn Marino /* Output a line number symbol entry for source file FILENAME and line
1552e4b17023SJohn Marino    number LINE.  */
1553e4b17023SJohn Marino 
1554e4b17023SJohn Marino static void
sdbout_source_line(unsigned int line,const char * filename ATTRIBUTE_UNUSED,int discriminator ATTRIBUTE_UNUSED,bool is_stmt ATTRIBUTE_UNUSED)1555e4b17023SJohn Marino sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED,
1556e4b17023SJohn Marino                     int discriminator ATTRIBUTE_UNUSED,
1557e4b17023SJohn Marino                     bool is_stmt ATTRIBUTE_UNUSED)
1558e4b17023SJohn Marino {
1559e4b17023SJohn Marino   /* COFF relative line numbers must be positive.  */
1560e4b17023SJohn Marino   if ((int) line > sdb_begin_function_line)
1561e4b17023SJohn Marino     {
1562e4b17023SJohn Marino #ifdef SDB_OUTPUT_SOURCE_LINE
1563e4b17023SJohn Marino       SDB_OUTPUT_SOURCE_LINE (asm_out_file, line);
1564e4b17023SJohn Marino #else
1565e4b17023SJohn Marino       fprintf (asm_out_file, "\t.ln\t%d\n",
1566e4b17023SJohn Marino 	       ((sdb_begin_function_line > -1)
1567e4b17023SJohn Marino 		? line - sdb_begin_function_line : 1));
1568e4b17023SJohn Marino #endif
1569e4b17023SJohn Marino     }
1570e4b17023SJohn Marino }
1571e4b17023SJohn Marino 
1572e4b17023SJohn Marino /* Output sdb info for the current function name.
1573e4b17023SJohn Marino    Called from assemble_start_function.  */
1574e4b17023SJohn Marino 
1575e4b17023SJohn Marino static void
sdbout_begin_function(tree decl ATTRIBUTE_UNUSED)1576e4b17023SJohn Marino sdbout_begin_function (tree decl ATTRIBUTE_UNUSED)
1577e4b17023SJohn Marino {
1578e4b17023SJohn Marino   sdbout_symbol (current_function_decl, 0);
1579e4b17023SJohn Marino }
1580e4b17023SJohn Marino 
1581e4b17023SJohn Marino /* Called at beginning of function body (before or after prologue,
1582e4b17023SJohn Marino    depending on MIPS_DEBUGGING_INFO).  Record the function's starting
1583e4b17023SJohn Marino    line number, so we can output relative line numbers for the other
1584e4b17023SJohn Marino    lines.  Describe beginning of outermost block.  Also describe the
1585e4b17023SJohn Marino    parameter list.  */
1586e4b17023SJohn Marino 
1587e4b17023SJohn Marino #ifndef MIPS_DEBUGGING_INFO
1588e4b17023SJohn Marino static void
sdbout_begin_prologue(unsigned int line,const char * file ATTRIBUTE_UNUSED)1589e4b17023SJohn Marino sdbout_begin_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
1590e4b17023SJohn Marino {
1591e4b17023SJohn Marino   sdbout_end_prologue (line, file);
1592e4b17023SJohn Marino }
1593e4b17023SJohn Marino #endif
1594e4b17023SJohn Marino 
1595e4b17023SJohn Marino static void
sdbout_end_prologue(unsigned int line,const char * file ATTRIBUTE_UNUSED)1596e4b17023SJohn Marino sdbout_end_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
1597e4b17023SJohn Marino {
1598e4b17023SJohn Marino   sdb_begin_function_line = line - 1;
1599e4b17023SJohn Marino   PUT_SDB_FUNCTION_START (line);
1600e4b17023SJohn Marino   sdbout_parms (DECL_ARGUMENTS (current_function_decl));
1601e4b17023SJohn Marino   sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl));
1602e4b17023SJohn Marino }
1603e4b17023SJohn Marino 
1604e4b17023SJohn Marino /* Called at end of function (before epilogue).
1605e4b17023SJohn Marino    Describe end of outermost block.  */
1606e4b17023SJohn Marino 
1607e4b17023SJohn Marino static void
sdbout_end_function(unsigned int line)1608e4b17023SJohn Marino sdbout_end_function (unsigned int line)
1609e4b17023SJohn Marino {
1610e4b17023SJohn Marino #ifdef SDB_ALLOW_FORWARD_REFERENCES
1611e4b17023SJohn Marino   sdbout_dequeue_anonymous_types ();
1612e4b17023SJohn Marino #endif
1613e4b17023SJohn Marino 
1614e4b17023SJohn Marino   MAKE_LINE_SAFE (line);
1615e4b17023SJohn Marino   PUT_SDB_FUNCTION_END (line - sdb_begin_function_line);
1616e4b17023SJohn Marino 
1617e4b17023SJohn Marino   /* Indicate we are between functions, for line-number output.  */
1618e4b17023SJohn Marino   sdb_begin_function_line = -1;
1619e4b17023SJohn Marino }
1620e4b17023SJohn Marino 
1621e4b17023SJohn Marino /* Output sdb info for the absolute end of a function.
1622e4b17023SJohn Marino    Called after the epilogue is output.  */
1623e4b17023SJohn Marino 
1624e4b17023SJohn Marino static void
sdbout_end_epilogue(unsigned int line ATTRIBUTE_UNUSED,const char * file ATTRIBUTE_UNUSED)1625e4b17023SJohn Marino sdbout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
1626e4b17023SJohn Marino 		     const char *file ATTRIBUTE_UNUSED)
1627e4b17023SJohn Marino {
1628e4b17023SJohn Marino   const char *const name ATTRIBUTE_UNUSED
1629e4b17023SJohn Marino     = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
1630e4b17023SJohn Marino 
1631e4b17023SJohn Marino #ifdef PUT_SDB_EPILOGUE_END
1632e4b17023SJohn Marino   PUT_SDB_EPILOGUE_END (name);
1633e4b17023SJohn Marino #else
1634e4b17023SJohn Marino   fprintf (asm_out_file, "\t.def\t");
1635e4b17023SJohn Marino   assemble_name (asm_out_file, name);
1636e4b17023SJohn Marino   fprintf (asm_out_file, "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n",
1637e4b17023SJohn Marino 	   SDB_DELIM, SDB_DELIM, SDB_DELIM);
1638e4b17023SJohn Marino #endif
1639e4b17023SJohn Marino }
1640e4b17023SJohn Marino 
1641e4b17023SJohn Marino /* Output sdb info for the given label.  Called only if LABEL_NAME (insn)
1642e4b17023SJohn Marino    is present.  */
1643e4b17023SJohn Marino 
1644e4b17023SJohn Marino static void
sdbout_label(rtx insn)1645e4b17023SJohn Marino sdbout_label (rtx insn)
1646e4b17023SJohn Marino {
1647e4b17023SJohn Marino   PUT_SDB_DEF (LABEL_NAME (insn));
1648e4b17023SJohn Marino   PUT_SDB_VAL (insn);
1649e4b17023SJohn Marino   PUT_SDB_SCL (C_LABEL);
1650e4b17023SJohn Marino   PUT_SDB_TYPE (T_NULL);
1651e4b17023SJohn Marino   PUT_SDB_ENDEF;
1652e4b17023SJohn Marino }
1653e4b17023SJohn Marino 
1654e4b17023SJohn Marino /* Change to reading from a new source file.  */
1655e4b17023SJohn Marino 
1656e4b17023SJohn Marino static void
sdbout_start_source_file(unsigned int line ATTRIBUTE_UNUSED,const char * filename ATTRIBUTE_UNUSED)1657e4b17023SJohn Marino sdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
1658e4b17023SJohn Marino 			  const char *filename ATTRIBUTE_UNUSED)
1659e4b17023SJohn Marino {
1660e4b17023SJohn Marino #ifdef MIPS_DEBUGGING_INFO
1661e4b17023SJohn Marino   struct sdb_file *n = XNEW (struct sdb_file);
1662e4b17023SJohn Marino 
1663e4b17023SJohn Marino   n->next = current_file;
1664e4b17023SJohn Marino   n->name = filename;
1665e4b17023SJohn Marino   current_file = n;
1666e4b17023SJohn Marino   output_file_directive (asm_out_file, filename);
1667e4b17023SJohn Marino #endif
1668e4b17023SJohn Marino }
1669e4b17023SJohn Marino 
1670e4b17023SJohn Marino /* Revert to reading a previous source file.  */
1671e4b17023SJohn Marino 
1672e4b17023SJohn Marino static void
sdbout_end_source_file(unsigned int line ATTRIBUTE_UNUSED)1673e4b17023SJohn Marino sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
1674e4b17023SJohn Marino {
1675e4b17023SJohn Marino #ifdef MIPS_DEBUGGING_INFO
1676e4b17023SJohn Marino   struct sdb_file *next;
1677e4b17023SJohn Marino 
1678e4b17023SJohn Marino   next = current_file->next;
1679e4b17023SJohn Marino   free (current_file);
1680e4b17023SJohn Marino   current_file = next;
1681e4b17023SJohn Marino   output_file_directive (asm_out_file, current_file->name);
1682e4b17023SJohn Marino #endif
1683e4b17023SJohn Marino }
1684e4b17023SJohn Marino 
1685e4b17023SJohn Marino /* Set up for SDB output at the start of compilation.  */
1686e4b17023SJohn Marino 
1687e4b17023SJohn Marino static void
sdbout_init(const char * input_file_name ATTRIBUTE_UNUSED)1688e4b17023SJohn Marino sdbout_init (const char *input_file_name ATTRIBUTE_UNUSED)
1689e4b17023SJohn Marino {
1690e4b17023SJohn Marino   tree t;
1691e4b17023SJohn Marino 
1692e4b17023SJohn Marino #ifdef MIPS_DEBUGGING_INFO
1693e4b17023SJohn Marino   current_file = XNEW (struct sdb_file);
1694e4b17023SJohn Marino   current_file->next = NULL;
1695e4b17023SJohn Marino   current_file->name = input_file_name;
1696e4b17023SJohn Marino #endif
1697e4b17023SJohn Marino 
1698e4b17023SJohn Marino   deferred_global_decls = VEC_alloc (tree, gc, 12);
1699e4b17023SJohn Marino 
1700e4b17023SJohn Marino   /* Emit debug information which was queued by sdbout_symbol before
1701e4b17023SJohn Marino      we got here.  */
1702e4b17023SJohn Marino   sdbout_initialized = true;
1703e4b17023SJohn Marino 
1704e4b17023SJohn Marino   for (t = nreverse (preinit_symbols); t; t = TREE_CHAIN (t))
1705e4b17023SJohn Marino     sdbout_symbol (TREE_VALUE (t), 0);
1706e4b17023SJohn Marino   preinit_symbols = 0;
1707e4b17023SJohn Marino }
1708e4b17023SJohn Marino 
1709e4b17023SJohn Marino #endif /* SDB_DEBUGGING_INFO */
1710e4b17023SJohn Marino 
1711e4b17023SJohn Marino #include "gt-sdbout.h"
1712