118334Speter/* Output sdb-format symbol table information from GNU compiler.
290075Sobrien   Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3169689Skan   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
418334Speter
590075SobrienThis file is part of GCC.
618334Speter
790075SobrienGCC is free software; you can redistribute it and/or modify it under
890075Sobrienthe terms of the GNU General Public License as published by the Free
990075SobrienSoftware Foundation; either version 2, or (at your option) any later
1090075Sobrienversion.
1118334Speter
1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1490075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1590075Sobrienfor more details.
1618334Speter
1718334SpeterYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
19169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20169689Skan02110-1301, USA.  */
2118334Speter
2218334Speter/*  mike@tredysvr.Tredydev.Unisys.COM says:
2318334SpeterI modified the struct.c example and have a nm of a .o resulting from the
2418334SpeterAT&T C compiler.  From the example below I would conclude the following:
2518334Speter
2618334Speter1. All .defs from structures are emitted as scanned.  The example below
2718334Speter   clearly shows the symbol table entries for BoxRec2 are after the first
2818334Speter   function.
2918334Speter
3018334Speter2. All functions and their locals (including statics) are emitted as scanned.
3118334Speter
3218334Speter3. All nested unnamed union and structure .defs must be emitted before
3318334Speter   the structure in which they are nested.  The AT&T assembler is a
3418334Speter   one pass beast as far as symbolics are concerned.
3518334Speter
3618334Speter4. All structure .defs are emitted before the typedefs that refer to them.
3718334Speter
3818334Speter5. All top level static and external variable definitions are moved to the
3918334Speter   end of file with all top level statics occurring first before externs.
4018334Speter
4118334Speter6. All undefined references are at the end of the file.
4218334Speter*/
4318334Speter
4418334Speter#include "config.h"
45117395Skan#include "system.h"
46132718Skan#include "coretypes.h"
47132718Skan#include "tm.h"
48117395Skan#include "debug.h"
49117395Skan#include "tree.h"
50117395Skan#include "ggc.h"
51169689Skan#include "varray.h"
5218334Speter
53117395Skanstatic GTY(()) tree anonymous_types;
54117395Skan
55132718Skan/* Counter to generate unique "names" for nameless struct members.  */
56132718Skan
57132718Skanstatic GTY(()) int unnamed_struct_number;
58132718Skan
59169689Skan/* Declarations whose debug info was deferred till end of compilation.  */
60169689Skan
61169689Skanstatic GTY(()) varray_type deferred_global_decls;
62169689Skan
63169689Skan/* The C front end may call sdbout_symbol before sdbout_init runs.
64169689Skan   We save all such decls in this list and output them when we get
65169689Skan   to sdbout_init.  */
66169689Skan
67169689Skanstatic GTY(()) tree preinit_symbols;
68169689Skanstatic GTY(()) bool sdbout_initialized;
69169689Skan
7018334Speter#ifdef SDB_DEBUGGING_INFO
7118334Speter
7218334Speter#include "rtl.h"
7318334Speter#include "regs.h"
7418334Speter#include "flags.h"
7518334Speter#include "insn-config.h"
7618334Speter#include "reload.h"
7750397Sobrien#include "output.h"
7850397Sobrien#include "toplev.h"
7990075Sobrien#include "tm_p.h"
8018334Speter#include "gsyms.h"
81117395Skan#include "langhooks.h"
82132718Skan#include "target.h"
8318334Speter
8418334Speter/* 1 if PARM is passed to this function in memory.  */
8518334Speter
8618334Speter#define PARM_PASSED_IN_MEMORY(PARM) \
87169689Skan (MEM_P (DECL_INCOMING_RTL (PARM)))
8818334Speter
8918334Speter/* A C expression for the integer offset value of an automatic variable
9018334Speter   (C_AUTO) having address X (an RTX).  */
9118334Speter#ifndef DEBUGGER_AUTO_OFFSET
9218334Speter#define DEBUGGER_AUTO_OFFSET(X) \
9318334Speter  (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0)
9418334Speter#endif
9518334Speter
9618334Speter/* A C expression for the integer offset value of an argument (C_ARG)
9718334Speter   having address X (an RTX).  The nominal offset is OFFSET.  */
9818334Speter#ifndef DEBUGGER_ARG_OFFSET
9918334Speter#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET)
10018334Speter#endif
10118334Speter
10218334Speter/* Line number of beginning of current function, minus one.
10318334Speter   Negative means not in a function or not using sdb.  */
10418334Speter
10518334Speterint sdb_begin_function_line = -1;
10618334Speter
10718334Speter
10818334Speterextern FILE *asm_out_file;
10918334Speter
11018334Speterextern tree current_function_decl;
11118334Speter
11250397Sobrien#include "sdbout.h"
11318334Speter
114132718Skanstatic void sdbout_init			(const char *);
115132718Skanstatic void sdbout_finish		(const char *);
116132718Skanstatic void sdbout_start_source_file	(unsigned int, const char *);
117132718Skanstatic void sdbout_end_source_file	(unsigned int);
118132718Skanstatic void sdbout_begin_block		(unsigned int, unsigned int);
119132718Skanstatic void sdbout_end_block		(unsigned int, unsigned int);
120132718Skanstatic void sdbout_source_line		(unsigned int, const char *);
121132718Skanstatic void sdbout_end_epilogue		(unsigned int, const char *);
122132718Skanstatic void sdbout_global_decl		(tree);
12390075Sobrien#ifndef MIPS_DEBUGGING_INFO
124132718Skanstatic void sdbout_begin_prologue	(unsigned int, const char *);
12518334Speter#endif
126132718Skanstatic void sdbout_end_prologue		(unsigned int, const char *);
127132718Skanstatic void sdbout_begin_function	(tree);
128132718Skanstatic void sdbout_end_function		(unsigned int);
129132718Skanstatic void sdbout_toplevel_data	(tree);
130132718Skanstatic void sdbout_label		(rtx);
131132718Skanstatic char *gen_fake_label		(void);
132132718Skanstatic int plain_type			(tree);
133132718Skanstatic int template_name_p		(tree);
134132718Skanstatic void sdbout_record_type_name	(tree);
135132718Skanstatic int plain_type_1			(tree, int);
136132718Skanstatic void sdbout_block		(tree);
137132718Skanstatic void sdbout_syms			(tree);
13890075Sobrien#ifdef SDB_ALLOW_FORWARD_REFERENCES
139132718Skanstatic void sdbout_queue_anonymous_type	(tree);
140132718Skanstatic void sdbout_dequeue_anonymous_types (void);
14118334Speter#endif
142132718Skanstatic void sdbout_type			(tree);
143132718Skanstatic void sdbout_field_types		(tree);
144132718Skanstatic void sdbout_one_type		(tree);
145132718Skanstatic void sdbout_parms		(tree);
146132718Skanstatic void sdbout_reg_parms		(tree);
147132718Skanstatic void sdbout_global_decl		(tree);
148132718Skan
14918334Speter/* Random macros describing parts of SDB data.  */
15018334Speter
15118334Speter/* Default value of delimiter is ";".  */
15218334Speter#ifndef SDB_DELIM
15318334Speter#define SDB_DELIM	";"
15418334Speter#endif
15518334Speter
15618334Speter/* Maximum number of dimensions the assembler will allow.  */
15718334Speter#ifndef SDB_MAX_DIM
15818334Speter#define SDB_MAX_DIM 4
15918334Speter#endif
16018334Speter
16118334Speter#ifndef PUT_SDB_SCL
16218334Speter#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d%s", (a), SDB_DELIM)
16318334Speter#endif
16418334Speter
16518334Speter#ifndef PUT_SDB_INT_VAL
16650397Sobrien#define PUT_SDB_INT_VAL(a) \
16750397Sobrien do {									\
168132718Skan   fprintf (asm_out_file, "\t.val\t" HOST_WIDE_INT_PRINT_DEC "%s",	\
169132718Skan	    (HOST_WIDE_INT) (a), SDB_DELIM);				\
17050397Sobrien } while (0)
17150397Sobrien
17218334Speter#endif
17318334Speter
17418334Speter#ifndef PUT_SDB_VAL
17518334Speter#define PUT_SDB_VAL(a)				\
17618334Speter( fputs ("\t.val\t", asm_out_file),		\
17718334Speter  output_addr_const (asm_out_file, (a)),	\
17818334Speter  fprintf (asm_out_file, SDB_DELIM))
17918334Speter#endif
18018334Speter
18118334Speter#ifndef PUT_SDB_DEF
18218334Speter#define PUT_SDB_DEF(a)				\
18318334Speterdo { fprintf (asm_out_file, "\t.def\t");	\
184132718Skan     assemble_name (asm_out_file, a);	\
18518334Speter     fprintf (asm_out_file, SDB_DELIM); } while (0)
18618334Speter#endif
18718334Speter
18818334Speter#ifndef PUT_SDB_PLAIN_DEF
18918334Speter#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s%s",a, SDB_DELIM)
19018334Speter#endif
19118334Speter
19218334Speter#ifndef PUT_SDB_ENDEF
19318334Speter#define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file)
19418334Speter#endif
19518334Speter
19618334Speter#ifndef PUT_SDB_TYPE
19718334Speter#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o%s", a, SDB_DELIM)
19818334Speter#endif
19918334Speter
20018334Speter#ifndef PUT_SDB_SIZE
20150397Sobrien#define PUT_SDB_SIZE(a) \
20250397Sobrien do {									\
203132718Skan   fprintf (asm_out_file, "\t.size\t" HOST_WIDE_INT_PRINT_DEC "%s",	\
204132718Skan	    (HOST_WIDE_INT) (a), SDB_DELIM);				\
20550397Sobrien } while(0)
20618334Speter#endif
20718334Speter
20818334Speter#ifndef PUT_SDB_START_DIM
20918334Speter#define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t")
21018334Speter#endif
21118334Speter
21218334Speter#ifndef PUT_SDB_NEXT_DIM
21318334Speter#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
21418334Speter#endif
21518334Speter
21618334Speter#ifndef PUT_SDB_LAST_DIM
21718334Speter#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM)
21818334Speter#endif
21918334Speter
22018334Speter#ifndef PUT_SDB_TAG
22118334Speter#define PUT_SDB_TAG(a)				\
22218334Speterdo { fprintf (asm_out_file, "\t.tag\t");	\
22390075Sobrien     assemble_name (asm_out_file, a);	\
22418334Speter     fprintf (asm_out_file, SDB_DELIM); } while (0)
22518334Speter#endif
22618334Speter
22718334Speter#ifndef PUT_SDB_BLOCK_START
22818334Speter#define PUT_SDB_BLOCK_START(LINE)		\
22918334Speter  fprintf (asm_out_file,			\
23018334Speter	   "\t.def\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
23118334Speter	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
23218334Speter#endif
23318334Speter
23418334Speter#ifndef PUT_SDB_BLOCK_END
23518334Speter#define PUT_SDB_BLOCK_END(LINE)			\
23618334Speter  fprintf (asm_out_file,			\
23718334Speter	   "\t.def\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n",  \
23818334Speter	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
23918334Speter#endif
24018334Speter
24118334Speter#ifndef PUT_SDB_FUNCTION_START
24218334Speter#define PUT_SDB_FUNCTION_START(LINE)		\
24318334Speter  fprintf (asm_out_file,			\
24418334Speter	   "\t.def\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
24518334Speter	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
24618334Speter#endif
24718334Speter
24818334Speter#ifndef PUT_SDB_FUNCTION_END
24918334Speter#define PUT_SDB_FUNCTION_END(LINE)		\
25018334Speter  fprintf (asm_out_file,			\
25118334Speter	   "\t.def\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
25218334Speter	   SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
25318334Speter#endif
25418334Speter
25518334Speter/* Return the sdb tag identifier string for TYPE
25690075Sobrien   if TYPE has already been defined; otherwise return a null pointer.  */
25718334Speter
25818334Speter#define KNOWN_TYPE_TAG(type)  TYPE_SYMTAB_POINTER (type)
25918334Speter
26018334Speter/* Set the sdb tag identifier string for TYPE to NAME.  */
26118334Speter
26218334Speter#define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
263132718Skan  TYPE_SYMTAB_POINTER (TYPE) = (char *)(NAME)
26418334Speter
26518334Speter/* Return the name (a string) of the struct, union or enum tag
26618334Speter   described by the TREE_LIST node LINK.  This is 0 for an anonymous one.  */
26718334Speter
26818334Speter#define TAG_NAME(link) \
26918334Speter  (((link) && TREE_PURPOSE ((link)) \
27018334Speter    && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \
27118334Speter   ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0)
27218334Speter
27318334Speter/* Ensure we don't output a negative line number.  */
27418334Speter#define MAKE_LINE_SAFE(line)  \
27590075Sobrien  if ((int) line <= sdb_begin_function_line) \
27690075Sobrien    line = sdb_begin_function_line + 1
27750397Sobrien
27850397Sobrien/* Perform linker optimization of merging header file definitions together
27950397Sobrien   for targets with MIPS_DEBUGGING_INFO defined.  This won't work without a
28050397Sobrien   post 960826 version of GAS.  Nothing breaks with earlier versions of GAS,
28150397Sobrien   the optimization just won't be done.  The native assembler already has the
28250397Sobrien   necessary support.  */
28350397Sobrien
28450397Sobrien#ifdef MIPS_DEBUGGING_INFO
28550397Sobrien
28650397Sobrien/* ECOFF linkers have an optimization that does the same kind of thing as
28750397Sobrien   N_BINCL/E_INCL in stabs: eliminate duplicate debug information in the
28850397Sobrien   executable.  To achieve this, GCC must output a .file for each file
28950397Sobrien   name change.  */
29050397Sobrien
29150397Sobrien/* This is a stack of input files.  */
29250397Sobrien
29350397Sobrienstruct sdb_file
29450397Sobrien{
29550397Sobrien  struct sdb_file *next;
29690075Sobrien  const char *name;
29750397Sobrien};
29850397Sobrien
29950397Sobrien/* This is the top of the stack.  */
30050397Sobrien
30150397Sobrienstatic struct sdb_file *current_file;
30250397Sobrien
30350397Sobrien#endif /* MIPS_DEBUGGING_INFO */
304132718Skan
30590075Sobrien/* The debug hooks structure.  */
306117395Skanconst struct gcc_debug_hooks sdb_debug_hooks =
30718334Speter{
308169689Skan  sdbout_init,			         /* init */
309169689Skan  sdbout_finish,		         /* finish */
310169689Skan  debug_nothing_int_charstar,	         /* define */
311169689Skan  debug_nothing_int_charstar,	         /* undef */
312169689Skan  sdbout_start_source_file,	         /* start_source_file */
313169689Skan  sdbout_end_source_file,	         /* end_source_file */
314169689Skan  sdbout_begin_block,		         /* begin_block */
315169689Skan  sdbout_end_block,		         /* end_block */
316169689Skan  debug_true_tree,		         /* ignore_block */
317169689Skan  sdbout_source_line,		         /* source_line */
31850397Sobrien#ifdef MIPS_DEBUGGING_INFO
31990075Sobrien  /* Defer on MIPS systems so that parameter descriptions follow
32090075Sobrien     function entry.  */
321169689Skan  debug_nothing_int_charstar,	         /* begin_prologue */
322169689Skan  sdbout_end_prologue,		         /* end_prologue */
32390075Sobrien#else
324169689Skan  sdbout_begin_prologue,	         /* begin_prologue */
325169689Skan  debug_nothing_int_charstar,	         /* end_prologue */
32650397Sobrien#endif
327169689Skan  sdbout_end_epilogue,		         /* end_epilogue */
328169689Skan  sdbout_begin_function,	         /* begin_function */
329169689Skan  sdbout_end_function,		         /* end_function */
330169689Skan  debug_nothing_tree,		         /* function_decl */
331169689Skan  sdbout_global_decl,		         /* global_decl */
332169689Skan  sdbout_symbol,			 /* type_decl */
333169689Skan  debug_nothing_tree_tree,               /* imported_module_or_decl */
334169689Skan  debug_nothing_tree,		         /* deferred_inline_function */
335169689Skan  debug_nothing_tree,		         /* outlining_inline_function */
336169689Skan  sdbout_label,			         /* label */
337169689Skan  debug_nothing_int,		         /* handle_pch */
338169689Skan  debug_nothing_rtx,		         /* var_location */
339169689Skan  debug_nothing_void,                    /* switch_text_section */
340169689Skan  0                                      /* start_end_main_source_file */
34190075Sobrien};
34218334Speter
34318334Speter/* Return a unique string to name an anonymous type.  */
34418334Speter
34518334Speterstatic char *
346132718Skangen_fake_label (void)
34718334Speter{
34818334Speter  char label[10];
34918334Speter  char *labelstr;
350169689Skan  sprintf (label, ".%dfake", unnamed_struct_number);
35118334Speter  unnamed_struct_number++;
352117395Skan  labelstr = xstrdup (label);
35318334Speter  return labelstr;
35418334Speter}
355132718Skan
35618334Speter/* Return the number which describes TYPE for SDB.
35718334Speter   For pointers, etc., this function is recursive.
35818334Speter   Each record, union or enumeral type must already have had a
35918334Speter   tag number output.  */
36018334Speter
36118334Speter/* The number is given by d6d5d4d3d2d1bbbb
36218334Speter   where bbbb is 4 bit basic type, and di indicate  one of notype,ptr,fn,array.
36318334Speter   Thus, char *foo () has bbbb=T_CHAR
36418334Speter			  d1=D_FCN
36518334Speter			  d2=D_PTR
36618334Speter N_BTMASK=     017       1111     basic type field.
36718334Speter N_TSHIFT=       2                derived type shift
36818334Speter N_BTSHFT=       4                Basic type shift */
36918334Speter
37018334Speter/* Produce the number that describes a pointer, function or array type.
37118334Speter   PREV is the number describing the target, value or element type.
37218334Speter   DT_type describes how to transform that type.  */
37318334Speter#define PUSH_DERIVED_LEVEL(DT_type,PREV)		\
37490075Sobrien  ((((PREV) & ~(int) N_BTMASK) << (int) N_TSHIFT)		\
37590075Sobrien   | ((int) DT_type << (int) N_BTSHFT)			\
37690075Sobrien   | ((PREV) & (int) N_BTMASK))
37718334Speter
37818334Speter/* Number of elements used in sdb_dims.  */
37918334Speterstatic int sdb_n_dims = 0;
38018334Speter
38118334Speter/* Table of array dimensions of current type.  */
38218334Speterstatic int sdb_dims[SDB_MAX_DIM];
38318334Speter
38418334Speter/* Size of outermost array currently being processed.  */
38518334Speterstatic int sdb_type_size = -1;
38618334Speter
38718334Speterstatic int
388132718Skanplain_type (tree type)
38918334Speter{
39018334Speter  int val = plain_type_1 (type, 0);
39118334Speter
39218334Speter  /* If we have already saved up some array dimensions, print them now.  */
39318334Speter  if (sdb_n_dims > 0)
39418334Speter    {
39518334Speter      int i;
39618334Speter      PUT_SDB_START_DIM;
39718334Speter      for (i = sdb_n_dims - 1; i > 0; i--)
39818334Speter	PUT_SDB_NEXT_DIM (sdb_dims[i]);
39918334Speter      PUT_SDB_LAST_DIM (sdb_dims[0]);
40018334Speter      sdb_n_dims = 0;
40118334Speter
40218334Speter      sdb_type_size = int_size_in_bytes (type);
40318334Speter      /* Don't kill sdb if type is not laid out or has variable size.  */
40418334Speter      if (sdb_type_size < 0)
40518334Speter	sdb_type_size = 0;
40618334Speter    }
40718334Speter  /* If we have computed the size of an array containing this type,
40818334Speter     print it now.  */
40918334Speter  if (sdb_type_size >= 0)
41018334Speter    {
41118334Speter      PUT_SDB_SIZE (sdb_type_size);
41218334Speter      sdb_type_size = -1;
41318334Speter    }
41418334Speter  return val;
41518334Speter}
41618334Speter
41718334Speterstatic int
418132718Skantemplate_name_p (tree name)
41918334Speter{
42090075Sobrien  const char *ptr = IDENTIFIER_POINTER (name);
42118334Speter  while (*ptr && *ptr != '<')
42218334Speter    ptr++;
42318334Speter
42418334Speter  return *ptr != '\0';
42518334Speter}
42618334Speter
42718334Speterstatic void
428132718Skansdbout_record_type_name (tree type)
42918334Speter{
43090075Sobrien  const char *name = 0;
43118334Speter  int no_name;
43218334Speter
43318334Speter  if (KNOWN_TYPE_TAG (type))
43418334Speter    return;
43518334Speter
43618334Speter  if (TYPE_NAME (type) != 0)
43718334Speter    {
43818334Speter      tree t = 0;
43990075Sobrien
44018334Speter      /* Find the IDENTIFIER_NODE for the type name.  */
44118334Speter      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
44218334Speter	t = TYPE_NAME (type);
44318334Speter      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
44418334Speter	{
44518334Speter	  t = DECL_NAME (TYPE_NAME (type));
44618334Speter	  /* The DECL_NAME for templates includes "<>", which breaks
44718334Speter	     most assemblers.  Use its assembler name instead, which
44818334Speter	     has been mangled into being safe.  */
44918334Speter	  if (t && template_name_p (t))
45018334Speter	    t = DECL_ASSEMBLER_NAME (TYPE_NAME (type));
45118334Speter	}
45218334Speter
45318334Speter      /* Now get the name as a string, or invent one.  */
45418334Speter      if (t != NULL_TREE)
45518334Speter	name = IDENTIFIER_POINTER (t);
45618334Speter    }
45718334Speter
45818334Speter  no_name = (name == 0 || *name == 0);
45918334Speter  if (no_name)
46018334Speter    name = gen_fake_label ();
46118334Speter
46218334Speter  SET_KNOWN_TYPE_TAG (type, name);
46318334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES
46418334Speter  if (no_name)
46518334Speter    sdbout_queue_anonymous_type (type);
46618334Speter#endif
46718334Speter}
46818334Speter
46918334Speter/* Return the .type value for type TYPE.
47018334Speter
47118334Speter   LEVEL indicates how many levels deep we have recursed into the type.
47218334Speter   The SDB debug format can only represent 6 derived levels of types.
47318334Speter   After that, we must output inaccurate debug info.  We deliberately
47418334Speter   stop before the 7th level, so that ADA recursive types will not give an
47518334Speter   infinite loop.  */
47618334Speter
47718334Speterstatic int
478132718Skanplain_type_1 (tree type, int level)
47918334Speter{
48018334Speter  if (type == 0)
48118334Speter    type = void_type_node;
48218334Speter  else if (type == error_mark_node)
48318334Speter    type = integer_type_node;
48418334Speter  else
48518334Speter    type = TYPE_MAIN_VARIANT (type);
48618334Speter
48718334Speter  switch (TREE_CODE (type))
48818334Speter    {
48918334Speter    case VOID_TYPE:
49018334Speter      return T_VOID;
49152284Sobrien    case BOOLEAN_TYPE:
49218334Speter    case INTEGER_TYPE:
49318334Speter      {
49418334Speter	int size = int_size_in_bytes (type) * BITS_PER_UNIT;
49518334Speter
49618334Speter	/* Carefully distinguish all the standard types of C,
49718334Speter	   without messing up if the language is not C.
49818334Speter	   Note that we check only for the names that contain spaces;
49918334Speter	   other names might occur by coincidence in other languages.  */
50018334Speter	if (TYPE_NAME (type) != 0
50118334Speter	    && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
50218334Speter	    && DECL_NAME (TYPE_NAME (type)) != 0
50318334Speter	    && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
50418334Speter	  {
50590075Sobrien	    const char *const name
50690075Sobrien	      = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
50718334Speter
50850397Sobrien	    if (!strcmp (name, "char"))
50950397Sobrien	      return T_CHAR;
51018334Speter	    if (!strcmp (name, "unsigned char"))
51118334Speter	      return T_UCHAR;
51218334Speter	    if (!strcmp (name, "signed char"))
51318334Speter	      return T_CHAR;
51450397Sobrien	    if (!strcmp (name, "int"))
51550397Sobrien	      return T_INT;
51618334Speter	    if (!strcmp (name, "unsigned int"))
51718334Speter	      return T_UINT;
51818334Speter	    if (!strcmp (name, "short int"))
51918334Speter	      return T_SHORT;
52018334Speter	    if (!strcmp (name, "short unsigned int"))
52118334Speter	      return T_USHORT;
52218334Speter	    if (!strcmp (name, "long int"))
52318334Speter	      return T_LONG;
52418334Speter	    if (!strcmp (name, "long unsigned int"))
52518334Speter	      return T_ULONG;
52618334Speter	  }
52718334Speter
52850397Sobrien	if (size == INT_TYPE_SIZE)
529169689Skan	  return (TYPE_UNSIGNED (type) ? T_UINT : T_INT);
53018334Speter	if (size == CHAR_TYPE_SIZE)
531169689Skan	  return (TYPE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
53218334Speter	if (size == SHORT_TYPE_SIZE)
533169689Skan	  return (TYPE_UNSIGNED (type) ? T_USHORT : T_SHORT);
53418334Speter	if (size == LONG_TYPE_SIZE)
535169689Skan	  return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
53618334Speter	if (size == LONG_LONG_TYPE_SIZE)	/* better than nothing */
537169689Skan	  return (TYPE_UNSIGNED (type) ? T_ULONG : T_LONG);
53818334Speter	return 0;
53918334Speter      }
54018334Speter
54118334Speter    case REAL_TYPE:
54218334Speter      {
54350397Sobrien	int precision = TYPE_PRECISION (type);
54450397Sobrien	if (precision == FLOAT_TYPE_SIZE)
54518334Speter	  return T_FLOAT;
54650397Sobrien	if (precision == DOUBLE_TYPE_SIZE)
54718334Speter	  return T_DOUBLE;
54850397Sobrien#ifdef EXTENDED_SDB_BASIC_TYPES
54950397Sobrien	if (precision == LONG_DOUBLE_TYPE_SIZE)
55050397Sobrien	  return T_LNGDBL;
55150397Sobrien#else
55250397Sobrien	if (precision == LONG_DOUBLE_TYPE_SIZE)
55350397Sobrien	  return T_DOUBLE;	/* better than nothing */
55450397Sobrien#endif
55518334Speter	return 0;
55618334Speter      }
55718334Speter
55818334Speter    case ARRAY_TYPE:
55918334Speter      {
56018334Speter	int m;
56118334Speter	if (level >= 6)
56218334Speter	  return T_VOID;
56318334Speter	else
56418334Speter	  m = plain_type_1 (TREE_TYPE (type), level+1);
56518334Speter	if (sdb_n_dims < SDB_MAX_DIM)
56618334Speter	  sdb_dims[sdb_n_dims++]
56718334Speter	    = (TYPE_DOMAIN (type)
56890075Sobrien	       && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != 0
56990075Sobrien	       && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
57090075Sobrien	       && host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
57190075Sobrien	       && host_integerp (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0)
57290075Sobrien	       ? (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
57390075Sobrien		  - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1)
57418334Speter	       : 0);
57590075Sobrien
57618334Speter	return PUSH_DERIVED_LEVEL (DT_ARY, m);
57718334Speter      }
57818334Speter
57918334Speter    case RECORD_TYPE:
58018334Speter    case UNION_TYPE:
58118334Speter    case QUAL_UNION_TYPE:
58218334Speter    case ENUMERAL_TYPE:
58318334Speter      {
58418334Speter	char *tag;
58518334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES
58618334Speter	sdbout_record_type_name (type);
58718334Speter#endif
58818334Speter#ifndef SDB_ALLOW_UNKNOWN_REFERENCES
58918334Speter	if ((TREE_ASM_WRITTEN (type) && KNOWN_TYPE_TAG (type) != 0)
59018334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES
59118334Speter	    || TYPE_MODE (type) != VOIDmode
59218334Speter#endif
59318334Speter	    )
59418334Speter#endif
59518334Speter	  {
59618334Speter	    /* Output the referenced structure tag name
59718334Speter	       only if the .def has already been finished.
59818334Speter	       At least on 386, the Unix assembler
59918334Speter	       cannot handle forward references to tags.  */
60050397Sobrien	    /* But the 88100, it requires them, sigh...  */
60150397Sobrien	    /* And the MIPS requires unknown refs as well...  */
60218334Speter	    tag = KNOWN_TYPE_TAG (type);
60318334Speter	    PUT_SDB_TAG (tag);
60418334Speter	    /* These 3 lines used to follow the close brace.
60518334Speter	       However, a size of 0 without a tag implies a tag of 0,
60618334Speter	       so if we don't know a tag, we can't mention the size.  */
60718334Speter	    sdb_type_size = int_size_in_bytes (type);
60818334Speter	    if (sdb_type_size < 0)
60918334Speter	      sdb_type_size = 0;
61018334Speter	  }
61118334Speter	return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
61218334Speter		: (TREE_CODE (type) == UNION_TYPE) ? T_UNION
61318334Speter		: (TREE_CODE (type) == QUAL_UNION_TYPE) ? T_UNION
61418334Speter		: T_ENUM);
61518334Speter      }
61618334Speter    case POINTER_TYPE:
61718334Speter    case REFERENCE_TYPE:
61818334Speter      {
61918334Speter	int m;
62018334Speter	if (level >= 6)
62118334Speter	  return T_VOID;
62218334Speter	else
62318334Speter	  m = plain_type_1 (TREE_TYPE (type), level+1);
62418334Speter	return PUSH_DERIVED_LEVEL (DT_PTR, m);
62518334Speter      }
62618334Speter    case FUNCTION_TYPE:
62718334Speter    case METHOD_TYPE:
62818334Speter      {
62918334Speter	int m;
63018334Speter	if (level >= 6)
63118334Speter	  return T_VOID;
63218334Speter	else
63318334Speter	  m = plain_type_1 (TREE_TYPE (type), level+1);
63418334Speter	return PUSH_DERIVED_LEVEL (DT_FCN, m);
63518334Speter      }
63618334Speter    default:
63718334Speter      return 0;
63818334Speter    }
63918334Speter}
640132718Skan
64118334Speter/* Output the symbols defined in block number DO_BLOCK.
64218334Speter
64318334Speter   This function works by walking the tree structure of blocks,
64418334Speter   counting blocks until it finds the desired block.  */
64518334Speter
64618334Speterstatic int do_block = 0;
64718334Speter
64818334Speterstatic void
649132718Skansdbout_block (tree block)
65018334Speter{
65118334Speter  while (block)
65218334Speter    {
65318334Speter      /* Ignore blocks never expanded or otherwise marked as real.  */
65418334Speter      if (TREE_USED (block))
65518334Speter	{
65618334Speter	  /* When we reach the specified block, output its symbols.  */
65790075Sobrien	  if (BLOCK_NUMBER (block) == do_block)
65890075Sobrien	    sdbout_syms (BLOCK_VARS (block));
65918334Speter
66018334Speter	  /* If we are past the specified block, stop the scan.  */
66190075Sobrien	  if (BLOCK_NUMBER (block) > do_block)
66218334Speter	    return;
66318334Speter
66418334Speter	  /* Scan the blocks within this block.  */
66518334Speter	  sdbout_block (BLOCK_SUBBLOCKS (block));
66618334Speter	}
66718334Speter
66818334Speter      block = BLOCK_CHAIN (block);
66918334Speter    }
67018334Speter}
671132718Skan
67218334Speter/* Call sdbout_symbol on each decl in the chain SYMS.  */
67318334Speter
67418334Speterstatic void
675132718Skansdbout_syms (tree syms)
67618334Speter{
67718334Speter  while (syms)
67818334Speter    {
67918334Speter      if (TREE_CODE (syms) != LABEL_DECL)
68018334Speter	sdbout_symbol (syms, 1);
68118334Speter      syms = TREE_CHAIN (syms);
68218334Speter    }
68318334Speter}
68418334Speter
68518334Speter/* Output SDB information for a symbol described by DECL.
68618334Speter   LOCAL is nonzero if the symbol is not file-scope.  */
68718334Speter
68818334Spetervoid
689132718Skansdbout_symbol (tree decl, int local)
69018334Speter{
69118334Speter  tree type = TREE_TYPE (decl);
69218334Speter  tree context = NULL_TREE;
69318334Speter  rtx value;
69418334Speter  int regno = -1;
69590075Sobrien  const char *name;
69618334Speter
697169689Skan  /* If we are called before sdbout_init is run, just save the symbol
698169689Skan     for later.  */
699169689Skan  if (!sdbout_initialized)
700169689Skan    {
701169689Skan      preinit_symbols = tree_cons (0, decl, preinit_symbols);
702169689Skan      return;
703169689Skan    }
704169689Skan
70518334Speter  sdbout_one_type (type);
70618334Speter
70718334Speter  switch (TREE_CODE (decl))
70818334Speter    {
70918334Speter    case CONST_DECL:
71018334Speter      /* Enum values are defined by defining the enum type.  */
71118334Speter      return;
71218334Speter
71318334Speter    case FUNCTION_DECL:
71418334Speter      /* Don't mention a nested function under its parent.  */
71518334Speter      context = decl_function_context (decl);
71618334Speter      if (context == current_function_decl)
71718334Speter	return;
71850397Sobrien      /* Check DECL_INITIAL to distinguish declarations from definitions.
71950397Sobrien	 Don't output debug info here for declarations; they will have
72050397Sobrien	 a DECL_INITIAL value of 0.  */
72150397Sobrien      if (! DECL_INITIAL (decl))
72218334Speter	return;
723169689Skan      if (!MEM_P (DECL_RTL (decl))
72418334Speter	  || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
72518334Speter	return;
72618334Speter      PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
72718334Speter      PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
72818334Speter      PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT);
72918334Speter      break;
73018334Speter
73118334Speter    case TYPE_DECL:
73218334Speter      /* Done with tagged types.  */
73318334Speter      if (DECL_NAME (decl) == 0)
73418334Speter	return;
73518334Speter      if (DECL_IGNORED_P (decl))
73618334Speter	return;
737169689Skan      /* Don't output intrinsic types.  GAS chokes on SDB .def
738169689Skan	 statements that contain identifiers with embedded spaces
739169689Skan	 (eg "unsigned long").  */
740169689Skan      if (DECL_IS_BUILTIN (decl))
741169689Skan	return;
74218334Speter
74318334Speter      /* Output typedef name.  */
74418334Speter      if (template_name_p (DECL_NAME (decl)))
74518334Speter	PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
74618334Speter      else
74718334Speter	PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
74818334Speter      PUT_SDB_SCL (C_TPDEF);
74918334Speter      break;
75018334Speter
75118334Speter    case PARM_DECL:
75218334Speter      /* Parm decls go in their own separate chains
75318334Speter	 and are output by sdbout_reg_parms and sdbout_parms.  */
754169689Skan      gcc_unreachable ();
75518334Speter
75618334Speter    case VAR_DECL:
75718334Speter      /* Don't mention a variable that is external.
75818334Speter	 Let the file that defines it describe it.  */
75918334Speter      if (DECL_EXTERNAL (decl))
76018334Speter	return;
76118334Speter
76218334Speter      /* Ignore __FUNCTION__, etc.  */
76318334Speter      if (DECL_IGNORED_P (decl))
76418334Speter	return;
76518334Speter
76618334Speter      /* If there was an error in the declaration, don't dump core
76718334Speter	 if there is no RTL associated with the variable doesn't
76818334Speter	 exist.  */
76990075Sobrien      if (!DECL_RTL_SET_P (decl))
77018334Speter	return;
77118334Speter
772117395Skan      SET_DECL_RTL (decl,
77390075Sobrien		    eliminate_regs (DECL_RTL (decl), 0, NULL_RTX));
77418334Speter#ifdef LEAF_REG_REMAP
77552284Sobrien      if (current_function_uses_only_leaf_regs)
77618334Speter	leaf_renumber_regs_insn (DECL_RTL (decl));
77718334Speter#endif
77818334Speter      value = DECL_RTL (decl);
77918334Speter
78018334Speter      /* Don't mention a variable at all
78118334Speter	 if it was completely optimized into nothingness.
78218334Speter
78318334Speter	 If DECL was from an inline function, then its rtl
78418334Speter	 is not identically the rtl that was used in this
78518334Speter	 particular compilation.  */
786169689Skan      if (REG_P (value))
78718334Speter	{
78890075Sobrien	  regno = REGNO (value);
78918334Speter	  if (regno >= FIRST_PSEUDO_REGISTER)
79018334Speter	    return;
79118334Speter	}
79218334Speter      else if (GET_CODE (value) == SUBREG)
79318334Speter	{
79418334Speter	  while (GET_CODE (value) == SUBREG)
79590075Sobrien	    value = SUBREG_REG (value);
796169689Skan	  if (REG_P (value))
79718334Speter	    {
79890075Sobrien	      if (REGNO (value) >= FIRST_PSEUDO_REGISTER)
79918334Speter		return;
80018334Speter	    }
80190075Sobrien	  regno = REGNO (alter_subreg (&value));
80290075Sobrien	  SET_DECL_RTL (decl, value);
80318334Speter	}
80418334Speter      /* Don't output anything if an auto variable
80518334Speter	 gets RTL that is static.
80618334Speter	 GAS version 2.2 can't handle such output.  */
807169689Skan      else if (MEM_P (value) && CONSTANT_P (XEXP (value, 0))
80818334Speter	       && ! TREE_STATIC (decl))
80918334Speter	return;
81018334Speter
81118334Speter      /* Emit any structure, union, or enum type that has not been output.
81218334Speter	 This occurs for tag-less structs (et al) used to declare variables
81318334Speter	 within functions.  */
81418334Speter      if (TREE_CODE (type) == ENUMERAL_TYPE
81518334Speter	  || TREE_CODE (type) == RECORD_TYPE
81618334Speter	  || TREE_CODE (type) == UNION_TYPE
81718334Speter	  || TREE_CODE (type) == QUAL_UNION_TYPE)
81818334Speter	{
81990075Sobrien	  if (COMPLETE_TYPE_P (type)		/* not a forward reference */
82018334Speter	      && KNOWN_TYPE_TAG (type) == 0)	/* not yet declared */
82118334Speter	    sdbout_one_type (type);
82218334Speter	}
82318334Speter
82418334Speter      /* Defer SDB information for top-level initialized variables! */
82518334Speter      if (! local
826169689Skan	  && MEM_P (value)
82718334Speter	  && DECL_INITIAL (decl))
82818334Speter	return;
82918334Speter
83018334Speter      /* C++ in 2.3 makes nameless symbols.  That will be fixed later.
83118334Speter	 For now, avoid crashing.  */
83218334Speter      if (DECL_NAME (decl) == NULL_TREE)
83318334Speter	return;
83418334Speter
83518334Speter      /* Record the name for, starting a symtab entry.  */
83690075Sobrien      if (local)
83790075Sobrien	name = IDENTIFIER_POINTER (DECL_NAME (decl));
83890075Sobrien      else
83990075Sobrien	name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
84018334Speter
841169689Skan      if (MEM_P (value)
84218334Speter	  && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
84318334Speter	{
84418334Speter	  PUT_SDB_DEF (name);
84518334Speter	  if (TREE_PUBLIC (decl))
84618334Speter	    {
84718334Speter	      PUT_SDB_VAL (XEXP (value, 0));
848117395Skan	      PUT_SDB_SCL (C_EXT);
84918334Speter	    }
85018334Speter	  else
85118334Speter	    {
85218334Speter	      PUT_SDB_VAL (XEXP (value, 0));
853117395Skan	      PUT_SDB_SCL (C_STAT);
85418334Speter	    }
85518334Speter	}
85618334Speter      else if (regno >= 0)
85718334Speter	{
85818334Speter	  PUT_SDB_DEF (name);
85918334Speter	  PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno));
86018334Speter	  PUT_SDB_SCL (C_REG);
86118334Speter	}
862169689Skan      else if (MEM_P (value)
863169689Skan	       && (MEM_P (XEXP (value, 0))
864169689Skan		   || (REG_P (XEXP (value, 0))
86518334Speter		       && REGNO (XEXP (value, 0)) != HARD_FRAME_POINTER_REGNUM
86618334Speter		       && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM)))
86718334Speter	/* If the value is indirect by memory or by a register
86818334Speter	   that isn't the frame pointer
86918334Speter	   then it means the object is variable-sized and address through
87018334Speter	   that register or stack slot.  COFF has no way to represent this
87118334Speter	   so all we can do is output the variable as a pointer.  */
87218334Speter	{
87318334Speter	  PUT_SDB_DEF (name);
874169689Skan	  if (REG_P (XEXP (value, 0)))
87518334Speter	    {
87618334Speter	      PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0))));
87718334Speter	      PUT_SDB_SCL (C_REG);
87818334Speter	    }
87918334Speter	  else
88018334Speter	    {
88118334Speter	      /* DECL_RTL looks like (MEM (MEM (PLUS (REG...)
88218334Speter		 (CONST_INT...)))).
88318334Speter		 We want the value of that CONST_INT.  */
88418334Speter	      /* Encore compiler hates a newline in a macro arg, it seems.  */
88518334Speter	      PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET
88618334Speter			       (XEXP (XEXP (value, 0), 0)));
88718334Speter	      PUT_SDB_SCL (C_AUTO);
88818334Speter	    }
88918334Speter
89052284Sobrien	  /* Effectively do build_pointer_type, but don't cache this type,
89152284Sobrien	     since it might be temporary whereas the type it points to
89252284Sobrien	     might have been saved for inlining.  */
89352284Sobrien	  /* Don't use REFERENCE_TYPE because dbx can't handle that.  */
89452284Sobrien	  type = make_node (POINTER_TYPE);
89552284Sobrien	  TREE_TYPE (type) = TREE_TYPE (decl);
89618334Speter	}
897169689Skan      else if (MEM_P (value)
89818334Speter	       && ((GET_CODE (XEXP (value, 0)) == PLUS
899169689Skan		    && REG_P (XEXP (XEXP (value, 0), 0))
90018334Speter		    && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT)
90118334Speter		   /* This is for variables which are at offset zero from
90218334Speter		      the frame pointer.  This happens on the Alpha.
90318334Speter		      Non-frame pointer registers are excluded above.  */
904169689Skan		   || (REG_P (XEXP (value, 0)))))
90518334Speter	{
90618334Speter	  /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
90718334Speter	     or (MEM (REG...)).  We want the value of that CONST_INT
90818334Speter	     or zero.  */
90918334Speter	  PUT_SDB_DEF (name);
91018334Speter	  PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0)));
91118334Speter	  PUT_SDB_SCL (C_AUTO);
91218334Speter	}
91318334Speter      else
91418334Speter	{
91518334Speter	  /* It is something we don't know how to represent for SDB.  */
91618334Speter	  return;
91718334Speter	}
91818334Speter      break;
91950397Sobrien
92050397Sobrien    default:
92150397Sobrien      break;
92218334Speter    }
92318334Speter  PUT_SDB_TYPE (plain_type (type));
92418334Speter  PUT_SDB_ENDEF;
92518334Speter}
926132718Skan
92718334Speter/* Output SDB information for a top-level initialized variable
92818334Speter   that has been delayed.  */
92918334Speter
93090075Sobrienstatic void
931132718Skansdbout_toplevel_data (tree decl)
93218334Speter{
93318334Speter  tree type = TREE_TYPE (decl);
93418334Speter
93518334Speter  if (DECL_IGNORED_P (decl))
93618334Speter    return;
93718334Speter
938169689Skan  gcc_assert (TREE_CODE (decl) == VAR_DECL);
939169689Skan  gcc_assert (MEM_P (DECL_RTL (decl)));
940169689Skan  gcc_assert (DECL_INITIAL (decl));
94118334Speter
94218334Speter  PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
94318334Speter  PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
94418334Speter  if (TREE_PUBLIC (decl))
94518334Speter    {
94618334Speter      PUT_SDB_SCL (C_EXT);
94718334Speter    }
94818334Speter  else
94918334Speter    {
95018334Speter      PUT_SDB_SCL (C_STAT);
95118334Speter    }
95218334Speter  PUT_SDB_TYPE (plain_type (type));
95318334Speter  PUT_SDB_ENDEF;
95418334Speter}
955132718Skan
95618334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES
95718334Speter
95850397Sobrien/* Machinery to record and output anonymous types.  */
95918334Speter
96018334Speterstatic void
961132718Skansdbout_queue_anonymous_type (tree type)
96218334Speter{
96390075Sobrien  anonymous_types = tree_cons (NULL_TREE, type, anonymous_types);
96418334Speter}
96518334Speter
96618334Speterstatic void
967132718Skansdbout_dequeue_anonymous_types (void)
96818334Speter{
96990075Sobrien  tree types, link;
97018334Speter
97118334Speter  while (anonymous_types)
97218334Speter    {
97318334Speter      types = nreverse (anonymous_types);
97418334Speter      anonymous_types = NULL_TREE;
97518334Speter
97618334Speter      for (link = types; link; link = TREE_CHAIN (link))
97718334Speter	{
97890075Sobrien	  tree type = TREE_VALUE (link);
97918334Speter
98018334Speter	  if (type && ! TREE_ASM_WRITTEN (type))
98118334Speter	    sdbout_one_type (type);
98218334Speter	}
98318334Speter    }
98418334Speter}
98518334Speter
98618334Speter#endif
987132718Skan
98818334Speter/* Given a chain of ..._TYPE nodes, all of which have names,
98918334Speter   output definitions of those names, as typedefs.  */
99018334Speter
99118334Spetervoid
992132718Skansdbout_types (tree types)
99318334Speter{
99490075Sobrien  tree link;
99518334Speter
99618334Speter  for (link = types; link; link = TREE_CHAIN (link))
99718334Speter    sdbout_one_type (link);
99818334Speter
99918334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES
100018334Speter  sdbout_dequeue_anonymous_types ();
100118334Speter#endif
100218334Speter}
100318334Speter
100418334Speterstatic void
1005132718Skansdbout_type (tree type)
100618334Speter{
100718334Speter  if (type == error_mark_node)
100818334Speter    type = integer_type_node;
100918334Speter  PUT_SDB_TYPE (plain_type (type));
101018334Speter}
101118334Speter
101218334Speter/* Output types of the fields of type TYPE, if they are structs.
101318334Speter
101418334Speter   Formerly did not chase through pointer types, since that could be circular.
101518334Speter   They must come before TYPE, since forward refs are not allowed.
101618334Speter   Now james@bigtex.cactus.org says to try them.  */
101718334Speter
101818334Speterstatic void
1019132718Skansdbout_field_types (tree type)
102018334Speter{
102118334Speter  tree tail;
102250397Sobrien
102318334Speter  for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
102490075Sobrien    /* This condition should match the one for emitting the actual
102590075Sobrien       members below.  */
102652284Sobrien    if (TREE_CODE (tail) == FIELD_DECL
102790075Sobrien	&& DECL_NAME (tail)
102890075Sobrien	&& DECL_SIZE (tail)
102990075Sobrien	&& host_integerp (DECL_SIZE (tail), 1)
103090075Sobrien	&& host_integerp (bit_position (tail), 0))
103152284Sobrien      {
103252284Sobrien	if (POINTER_TYPE_P (TREE_TYPE (tail)))
103352284Sobrien	  sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
103452284Sobrien	else
103552284Sobrien	  sdbout_one_type (TREE_TYPE (tail));
103652284Sobrien      }
103718334Speter}
103818334Speter
103918334Speter/* Use this to put out the top level defined record and union types
104018334Speter   for later reference.  If this is a struct with a name, then put that
104118334Speter   name out.  Other unnamed structs will have .xxfake labels generated so
104218334Speter   that they may be referred to later.
104318334Speter   The label will be stored in the KNOWN_TYPE_TAG slot of a type.
104418334Speter   It may NOT be called recursively.  */
104518334Speter
104618334Speterstatic void
1047132718Skansdbout_one_type (tree type)
104818334Speter{
104918334Speter  if (current_function_decl != NULL_TREE
105018334Speter      && DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
105118334Speter    ; /* Don't change section amid function.  */
105218334Speter  else
1053169689Skan    switch_to_section (text_section);
105418334Speter
105518334Speter  switch (TREE_CODE (type))
105618334Speter    {
105718334Speter    case RECORD_TYPE:
105818334Speter    case UNION_TYPE:
105918334Speter    case QUAL_UNION_TYPE:
106018334Speter    case ENUMERAL_TYPE:
106118334Speter      type = TYPE_MAIN_VARIANT (type);
106218334Speter      /* Don't output a type twice.  */
106318334Speter      if (TREE_ASM_WRITTEN (type))
106418334Speter	/* James said test TREE_ASM_BEING_WRITTEN here.  */
106518334Speter	return;
106618334Speter
106718334Speter      /* Output nothing if type is not yet defined.  */
106890075Sobrien      if (!COMPLETE_TYPE_P (type))
106918334Speter	return;
107018334Speter
107118334Speter      TREE_ASM_WRITTEN (type) = 1;
1072132718Skan
107318334Speter      /* This is reputed to cause trouble with the following case,
107418334Speter	 but perhaps checking TYPE_SIZE above will fix it.  */
107518334Speter
1076132718Skan      /* Here is a testcase:
107718334Speter
107818334Speter	struct foo {
107918334Speter	  struct badstr *bbb;
108018334Speter	} forwardref;
108118334Speter
108218334Speter	typedef struct intermediate {
108318334Speter	  int aaaa;
108418334Speter	} intermediate_ref;
108518334Speter
108618334Speter	typedef struct badstr {
108718334Speter	  int ccccc;
108818334Speter	} badtype;   */
108918334Speter
109018334Speter      /* This change, which ought to make better output,
109118334Speter	 used to make the COFF assembler unhappy.
109218334Speter	 Changes involving KNOWN_TYPE_TAG may fix the problem.  */
109318334Speter      /* Before really doing anything, output types we want to refer to.  */
109418334Speter      /* Note that in version 1 the following two lines
109518334Speter	 are not used if forward references are in use.  */
109618334Speter      if (TREE_CODE (type) != ENUMERAL_TYPE)
109718334Speter	sdbout_field_types (type);
109818334Speter
109918334Speter      /* Output a structure type.  */
110018334Speter      {
110118334Speter	int size = int_size_in_bytes (type);
110290075Sobrien	int member_scl = 0;
110318334Speter	tree tem;
110418334Speter
110518334Speter	/* Record the type tag, but not in its permanent place just yet.  */
110618334Speter	sdbout_record_type_name (type);
110718334Speter
110818334Speter	PUT_SDB_DEF (KNOWN_TYPE_TAG (type));
110918334Speter
111018334Speter	switch (TREE_CODE (type))
111118334Speter	  {
111218334Speter	  case UNION_TYPE:
111318334Speter	  case QUAL_UNION_TYPE:
111418334Speter	    PUT_SDB_SCL (C_UNTAG);
111518334Speter	    PUT_SDB_TYPE (T_UNION);
111618334Speter	    member_scl = C_MOU;
111718334Speter	    break;
111818334Speter
111918334Speter	  case RECORD_TYPE:
112018334Speter	    PUT_SDB_SCL (C_STRTAG);
112118334Speter	    PUT_SDB_TYPE (T_STRUCT);
112218334Speter	    member_scl = C_MOS;
112318334Speter	    break;
112418334Speter
112518334Speter	  case ENUMERAL_TYPE:
112618334Speter	    PUT_SDB_SCL (C_ENTAG);
112718334Speter	    PUT_SDB_TYPE (T_ENUM);
112818334Speter	    member_scl = C_MOE;
112918334Speter	    break;
113050397Sobrien
113150397Sobrien	  default:
113250397Sobrien	    break;
113318334Speter	  }
113418334Speter
113518334Speter	PUT_SDB_SIZE (size);
113618334Speter	PUT_SDB_ENDEF;
113718334Speter
113818334Speter	/* Print out the base class information with fields
113918334Speter	   named after the types they hold.  */
114090075Sobrien	/* This is only relevant to aggregate types.  TYPE_BINFO is used
114152284Sobrien	   for other purposes in an ENUMERAL_TYPE, so we must exclude that
114252284Sobrien	   case.  */
1143169689Skan	if (TREE_CODE (type) != ENUMERAL_TYPE && TYPE_BINFO (type))
114418334Speter	  {
1145169689Skan	    int i;
1146169689Skan	    tree binfo, child;
1147169689Skan
1148169689Skan	    for (binfo = TYPE_BINFO (type), i = 0;
1149169689Skan		 BINFO_BASE_ITERATE (binfo, i, child); i++)
115018334Speter	      {
115152284Sobrien		tree child_type = BINFO_TYPE (child);
115252284Sobrien		tree child_type_name;
1153169689Skan
115452284Sobrien		if (TYPE_NAME (child_type) == 0)
115552284Sobrien		  continue;
115652284Sobrien		if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
115752284Sobrien		  child_type_name = TYPE_NAME (child_type);
115852284Sobrien		else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL)
115952284Sobrien		  {
116052284Sobrien		    child_type_name = DECL_NAME (TYPE_NAME (child_type));
116152284Sobrien		    if (child_type_name && template_name_p (child_type_name))
116252284Sobrien		      child_type_name
116352284Sobrien			= DECL_ASSEMBLER_NAME (TYPE_NAME (child_type));
116452284Sobrien		  }
116552284Sobrien		else
116652284Sobrien		  continue;
116752284Sobrien
116852284Sobrien		PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
116990075Sobrien		PUT_SDB_INT_VAL (tree_low_cst (BINFO_OFFSET (child), 0));
117052284Sobrien		PUT_SDB_SCL (member_scl);
117152284Sobrien		sdbout_type (BINFO_TYPE (child));
117252284Sobrien		PUT_SDB_ENDEF;
117318334Speter	      }
117418334Speter	  }
117518334Speter
1176132718Skan	/* Output the individual fields.  */
117718334Speter
117818334Speter	if (TREE_CODE (type) == ENUMERAL_TYPE)
117990075Sobrien	  {
1180169689Skan	    for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
118190075Sobrien	      if (host_integerp (TREE_VALUE (tem), 0))
118290075Sobrien		{
118390075Sobrien		  PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
118490075Sobrien		  PUT_SDB_INT_VAL (tree_low_cst (TREE_VALUE (tem), 0));
118590075Sobrien		  PUT_SDB_SCL (C_MOE);
118690075Sobrien		  PUT_SDB_TYPE (T_MOE);
118790075Sobrien		  PUT_SDB_ENDEF;
118890075Sobrien		}
118990075Sobrien	  }
119018334Speter	else			/* record or union type */
119118334Speter	  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
119218334Speter	    /* Output the name, type, position (in bits), size (in bits)
119318334Speter	       of each field.  */
119418334Speter
119518334Speter	    /* Omit here the nameless fields that are used to skip bits.
119618334Speter	       Also omit fields with variable size or position.
119718334Speter	       Also omit non FIELD_DECL nodes that GNU C++ may put here.  */
119818334Speter	    if (TREE_CODE (tem) == FIELD_DECL
119990075Sobrien		&& DECL_NAME (tem)
120090075Sobrien		&& DECL_SIZE (tem)
120190075Sobrien		&& host_integerp (DECL_SIZE (tem), 1)
120290075Sobrien		&& host_integerp (bit_position (tem), 0))
120318334Speter	      {
120490075Sobrien		const char *name;
120518334Speter
120690075Sobrien		name = IDENTIFIER_POINTER (DECL_NAME (tem));
120718334Speter		PUT_SDB_DEF (name);
120818334Speter		if (DECL_BIT_FIELD_TYPE (tem))
120918334Speter		  {
121090075Sobrien		    PUT_SDB_INT_VAL (int_bit_position (tem));
121118334Speter		    PUT_SDB_SCL (C_FIELD);
121218334Speter		    sdbout_type (DECL_BIT_FIELD_TYPE (tem));
121390075Sobrien		    PUT_SDB_SIZE (tree_low_cst (DECL_SIZE (tem), 1));
121418334Speter		  }
121518334Speter		else
121618334Speter		  {
121790075Sobrien		    PUT_SDB_INT_VAL (int_bit_position (tem) / BITS_PER_UNIT);
121818334Speter		    PUT_SDB_SCL (member_scl);
121918334Speter		    sdbout_type (TREE_TYPE (tem));
122018334Speter		  }
122118334Speter		PUT_SDB_ENDEF;
122218334Speter	      }
1223132718Skan	/* Output end of a structure,union, or enumeral definition.  */
122418334Speter
122518334Speter	PUT_SDB_PLAIN_DEF ("eos");
122618334Speter	PUT_SDB_INT_VAL (size);
122718334Speter	PUT_SDB_SCL (C_EOS);
122818334Speter	PUT_SDB_TAG (KNOWN_TYPE_TAG (type));
122918334Speter	PUT_SDB_SIZE (size);
123018334Speter	PUT_SDB_ENDEF;
123118334Speter	break;
123250397Sobrien
123350397Sobrien      default:
123450397Sobrien	break;
123518334Speter      }
123618334Speter    }
123718334Speter}
1238132718Skan
123918334Speter/* The following two functions output definitions of function parameters.
124018334Speter   Each parameter gets a definition locating it in the parameter list.
124118334Speter   Each parameter that is a register variable gets a second definition
124218334Speter   locating it in the register.
124318334Speter
124418334Speter   Printing or argument lists in gdb uses the definitions that
124518334Speter   locate in the parameter list.  But reference to the variable in
124618334Speter   expressions uses preferentially the definition as a register.  */
124718334Speter
124818334Speter/* Output definitions, referring to storage in the parmlist,
124918334Speter   of all the parms in PARMS, which is a chain of PARM_DECL nodes.  */
125018334Speter
125118334Speterstatic void
1252132718Skansdbout_parms (tree parms)
125318334Speter{
125418334Speter  for (; parms; parms = TREE_CHAIN (parms))
125518334Speter    if (DECL_NAME (parms))
125618334Speter      {
125718334Speter	int current_sym_value = 0;
125890075Sobrien	const char *name = IDENTIFIER_POINTER (DECL_NAME (parms));
125918334Speter
126018334Speter	if (name == 0 || *name == 0)
126118334Speter	  name = gen_fake_label ();
126218334Speter
126318334Speter	/* Perform any necessary register eliminations on the parameter's rtl,
126418334Speter	   so that the debugging output will be accurate.  */
126550397Sobrien	DECL_INCOMING_RTL (parms)
126650397Sobrien	  = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
126790075Sobrien	SET_DECL_RTL (parms,
126890075Sobrien		      eliminate_regs (DECL_RTL (parms), 0, NULL_RTX));
126918334Speter
127018334Speter	if (PARM_PASSED_IN_MEMORY (parms))
127118334Speter	  {
127218334Speter	    rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
127318334Speter	    tree type;
127418334Speter
127518334Speter	    /* ??? Here we assume that the parm address is indexed
127618334Speter	       off the frame pointer or arg pointer.
127718334Speter	       If that is not true, we produce meaningless results,
127818334Speter	       but do not crash.  */
127918334Speter	    if (GET_CODE (addr) == PLUS
128018334Speter		&& GET_CODE (XEXP (addr, 1)) == CONST_INT)
128118334Speter	      current_sym_value = INTVAL (XEXP (addr, 1));
128218334Speter	    else
128318334Speter	      current_sym_value = 0;
128418334Speter
1285169689Skan	    if (REG_P (DECL_RTL (parms))
128618334Speter		&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
128718334Speter	      type = DECL_ARG_TYPE (parms);
128818334Speter	    else
128918334Speter	      {
129018334Speter		int original_sym_value = current_sym_value;
129118334Speter
129218334Speter		/* This is the case where the parm is passed as an int or
129318334Speter		   double and it is converted to a char, short or float
129418334Speter		   and stored back in the parmlist.  In this case, describe
129518334Speter		   the parm with the variable's declared type, and adjust
129618334Speter		   the address if the least significant bytes (which we are
129718334Speter		   using) are not the first ones.  */
129818334Speter		if (BYTES_BIG_ENDIAN
129918334Speter		    && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
130018334Speter		  current_sym_value +=
130118334Speter		    (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
130218334Speter		     - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
130318334Speter
1304169689Skan		if (MEM_P (DECL_RTL (parms))
130518334Speter		    && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
130618334Speter		    && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
130718334Speter			== CONST_INT)
130818334Speter		    && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1))
130918334Speter			== current_sym_value))
131018334Speter		  type = TREE_TYPE (parms);
131118334Speter		else
131218334Speter		  {
131318334Speter		    current_sym_value = original_sym_value;
131418334Speter		    type = DECL_ARG_TYPE (parms);
131518334Speter		  }
131618334Speter	      }
131718334Speter
131818334Speter	    PUT_SDB_DEF (name);
131918334Speter	    PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, addr));
132018334Speter	    PUT_SDB_SCL (C_ARG);
132118334Speter	    PUT_SDB_TYPE (plain_type (type));
132218334Speter	    PUT_SDB_ENDEF;
132318334Speter	  }
1324169689Skan	else if (REG_P (DECL_RTL (parms)))
132518334Speter	  {
132618334Speter	    rtx best_rtl;
132718334Speter	    /* Parm passed in registers and lives in registers or nowhere.  */
132818334Speter
132918334Speter	    /* If parm lives in a register, use that register;
133018334Speter	       pretend the parm was passed there.  It would be more consistent
133118334Speter	       to describe the register where the parm was passed,
133218334Speter	       but in practice that register usually holds something else.  */
133390075Sobrien	    if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
133418334Speter	      best_rtl = DECL_RTL (parms);
133518334Speter	    /* If the parm lives nowhere,
133618334Speter	       use the register where it was passed.  */
133718334Speter	    else
133818334Speter	      best_rtl = DECL_INCOMING_RTL (parms);
133918334Speter
134018334Speter	    PUT_SDB_DEF (name);
134118334Speter	    PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl)));
134218334Speter	    PUT_SDB_SCL (C_REGPARM);
134350397Sobrien	    PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
134418334Speter	    PUT_SDB_ENDEF;
134518334Speter	  }
1346169689Skan	else if (MEM_P (DECL_RTL (parms))
134718334Speter		 && XEXP (DECL_RTL (parms), 0) != const0_rtx)
134818334Speter	  {
134918334Speter	    /* Parm was passed in registers but lives on the stack.  */
135018334Speter
135118334Speter	    /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))),
135218334Speter	       in which case we want the value of that CONST_INT,
135318334Speter	       or (MEM (REG ...)) or (MEM (MEM ...)),
135418334Speter	       in which case we use a value of zero.  */
1355169689Skan	    if (REG_P (XEXP (DECL_RTL (parms), 0))
1356169689Skan		|| MEM_P (XEXP (DECL_RTL (parms), 0)))
135718334Speter	      current_sym_value = 0;
135818334Speter	    else
135918334Speter	      current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
136018334Speter
136118334Speter	    /* Again, this assumes the offset is based on the arg pointer.  */
136218334Speter	    PUT_SDB_DEF (name);
136318334Speter	    PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value,
136418334Speter						  XEXP (DECL_RTL (parms), 0)));
136518334Speter	    PUT_SDB_SCL (C_ARG);
136650397Sobrien	    PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
136718334Speter	    PUT_SDB_ENDEF;
136818334Speter	  }
136918334Speter      }
137018334Speter}
137118334Speter
137218334Speter/* Output definitions for the places where parms live during the function,
137318334Speter   when different from where they were passed, when the parms were passed
137418334Speter   in memory.
137518334Speter
137618334Speter   It is not useful to do this for parms passed in registers
137718334Speter   that live during the function in different registers, because it is
137818334Speter   impossible to look in the passed register for the passed value,
137918334Speter   so we use the within-the-function register to begin with.
138018334Speter
138118334Speter   PARMS is a chain of PARM_DECL nodes.  */
138218334Speter
138318334Speterstatic void
1384132718Skansdbout_reg_parms (tree parms)
138518334Speter{
138618334Speter  for (; parms; parms = TREE_CHAIN (parms))
138718334Speter    if (DECL_NAME (parms))
138818334Speter      {
138990075Sobrien	const char *name = IDENTIFIER_POINTER (DECL_NAME (parms));
139018334Speter
139118334Speter	/* Report parms that live in registers during the function
139218334Speter	   but were passed in memory.  */
1393169689Skan	if (REG_P (DECL_RTL (parms))
139418334Speter	    && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
139518334Speter	    && PARM_PASSED_IN_MEMORY (parms))
139618334Speter	  {
139718334Speter	    if (name == 0 || *name == 0)
139818334Speter	      name = gen_fake_label ();
139918334Speter	    PUT_SDB_DEF (name);
140018334Speter	    PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))));
140118334Speter	    PUT_SDB_SCL (C_REG);
140250397Sobrien	    PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
140318334Speter	    PUT_SDB_ENDEF;
140418334Speter	  }
140518334Speter	/* Report parms that live in memory but not where they were passed.  */
1406169689Skan	else if (MEM_P (DECL_RTL (parms))
140718334Speter		 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
140818334Speter		 && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
140918334Speter		 && PARM_PASSED_IN_MEMORY (parms)
141018334Speter		 && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms)))
141118334Speter	  {
141218334Speter#if 0 /* ??? It is not clear yet what should replace this.  */
141318334Speter	    int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
141418334Speter	    /* A parm declared char is really passed as an int,
141518334Speter	       so it occupies the least significant bytes.
141618334Speter	       On a big-endian machine those are not the low-numbered ones.  */
141718334Speter	    if (BYTES_BIG_ENDIAN
141818334Speter		&& offset != -1
141918334Speter		&& TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
142018334Speter	      offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
142118334Speter			 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
142218334Speter	    if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
142318334Speter#endif
142418334Speter	      {
142518334Speter		if (name == 0 || *name == 0)
142618334Speter		  name = gen_fake_label ();
142718334Speter		PUT_SDB_DEF (name);
142818334Speter		PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET
142918334Speter				 (XEXP (DECL_RTL (parms), 0)));
143018334Speter		PUT_SDB_SCL (C_AUTO);
143118334Speter		PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
143218334Speter		PUT_SDB_ENDEF;
143318334Speter	      }
143418334Speter	  }
143518334Speter      }
143618334Speter}
1437132718Skan
143890075Sobrien/* Output debug information for a global DECL.  Called from toplev.c
143990075Sobrien   after compilation proper has finished.  */
144090075Sobrien
144190075Sobrienstatic void
1442132718Skansdbout_global_decl (tree decl)
144390075Sobrien{
144490075Sobrien  if (TREE_CODE (decl) == VAR_DECL
144590075Sobrien      && !DECL_EXTERNAL (decl)
144690075Sobrien      && DECL_RTL_SET_P (decl))
144790075Sobrien    {
144890075Sobrien      /* The COFF linker can move initialized global vars to the end.
144990075Sobrien	 And that can screw up the symbol ordering.  Defer those for
145090075Sobrien	 sdbout_finish ().  */
145190075Sobrien      if (!DECL_INITIAL (decl) || !TREE_PUBLIC (decl))
145290075Sobrien	sdbout_symbol (decl, 0);
1453169689Skan      else
1454169689Skan	VARRAY_PUSH_TREE (deferred_global_decls, decl);
145590075Sobrien
145690075Sobrien      /* Output COFF information for non-global file-scope initialized
145790075Sobrien	 variables.  */
1458169689Skan      if (DECL_INITIAL (decl) && MEM_P (DECL_RTL (decl)))
145990075Sobrien	sdbout_toplevel_data (decl);
146090075Sobrien    }
146190075Sobrien}
146290075Sobrien
146390075Sobrien/* Output initialized global vars at the end, in the order of
146490075Sobrien   definition.  See comment in sdbout_global_decl.  */
146590075Sobrien
146690075Sobrienstatic void
1467132718Skansdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
146890075Sobrien{
1469169689Skan  size_t i;
147090075Sobrien
1471169689Skan  for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_global_decls); i++)
1472169689Skan    sdbout_symbol (VARRAY_TREE (deferred_global_decls, i), 0);
147390075Sobrien}
1474132718Skan
147518334Speter/* Describe the beginning of an internal block within a function.
147618334Speter   Also output descriptions of variables defined in this block.
147718334Speter
147818334Speter   N is the number of the block, by order of beginning, counting from 1,
147918334Speter   and not counting the outermost (function top-level) block.
148018334Speter   The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
148118334Speter   if the count starts at 0 for the outermost one.  */
148218334Speter
148390075Sobrienstatic void
1484132718Skansdbout_begin_block (unsigned int line, unsigned int n)
148518334Speter{
148618334Speter  tree decl = current_function_decl;
148718334Speter  MAKE_LINE_SAFE (line);
148818334Speter
148918334Speter  /* The SCO compiler does not emit a separate block for the function level
149018334Speter     scope, so we avoid it here also.  However, mips ECOFF compilers do emit
149118334Speter     a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined.  */
149218334Speter#ifndef MIPS_DEBUGGING_INFO
149318334Speter  if (n != 1)
149418334Speter#endif
149518334Speter    PUT_SDB_BLOCK_START (line - sdb_begin_function_line);
149618334Speter
149718334Speter  if (n == 1)
149818334Speter    {
149918334Speter      /* Include the outermost BLOCK's variables in block 1.  */
150090075Sobrien      do_block = BLOCK_NUMBER (DECL_INITIAL (decl));
150118334Speter      sdbout_block (DECL_INITIAL (decl));
150218334Speter    }
150318334Speter  /* If -g1, suppress all the internal symbols of functions
150418334Speter     except for arguments.  */
150518334Speter  if (debug_info_level != DINFO_LEVEL_TERSE)
150618334Speter    {
150718334Speter      do_block = n;
150818334Speter      sdbout_block (DECL_INITIAL (decl));
150918334Speter    }
151018334Speter
151118334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES
151218334Speter  sdbout_dequeue_anonymous_types ();
151318334Speter#endif
151418334Speter}
151518334Speter
151618334Speter/* Describe the end line-number of an internal block within a function.  */
151718334Speter
151890075Sobrienstatic void
1519132718Skansdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED)
152018334Speter{
152118334Speter  MAKE_LINE_SAFE (line);
152218334Speter
152318334Speter  /* The SCO compiler does not emit a separate block for the function level
152418334Speter     scope, so we avoid it here also.  However, mips ECOFF compilers do emit
152518334Speter     a separate block, so we retain it when MIPS_DEBUGGING_INFO is defined.  */
152618334Speter#ifndef MIPS_DEBUGGING_INFO
152718334Speter  if (n != 1)
152818334Speter#endif
152918334Speter  PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
153018334Speter}
153118334Speter
1532132718Skan/* Output a line number symbol entry for source file FILENAME and line
1533132718Skan   number LINE.  */
1534132718Skan
153590075Sobrienstatic void
1536132718Skansdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED)
153790075Sobrien{
153890075Sobrien  /* COFF relative line numbers must be positive.  */
153990075Sobrien  if ((int) line > sdb_begin_function_line)
154090075Sobrien    {
1541169689Skan#ifdef SDB_OUTPUT_SOURCE_LINE
1542169689Skan      SDB_OUTPUT_SOURCE_LINE (asm_out_file, line);
154390075Sobrien#else
154490075Sobrien      fprintf (asm_out_file, "\t.ln\t%d\n",
154590075Sobrien	       ((sdb_begin_function_line > -1)
154690075Sobrien		? line - sdb_begin_function_line : 1));
154790075Sobrien#endif
154890075Sobrien    }
154990075Sobrien}
155090075Sobrien
155118334Speter/* Output sdb info for the current function name.
155218334Speter   Called from assemble_start_function.  */
155318334Speter
155490075Sobrienstatic void
1555132718Skansdbout_begin_function (tree decl ATTRIBUTE_UNUSED)
155618334Speter{
155718334Speter  sdbout_symbol (current_function_decl, 0);
155818334Speter}
155918334Speter
156090075Sobrien/* Called at beginning of function body (before or after prologue,
156190075Sobrien   depending on MIPS_DEBUGGING_INFO).  Record the function's starting
156290075Sobrien   line number, so we can output relative line numbers for the other
156390075Sobrien   lines.  Describe beginning of outermost block.  Also describe the
156490075Sobrien   parameter list.  */
156518334Speter
156690075Sobrien#ifndef MIPS_DEBUGGING_INFO
156790075Sobrienstatic void
1568132718Skansdbout_begin_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
156918334Speter{
1570117395Skan  sdbout_end_prologue (line, file);
157190075Sobrien}
157290075Sobrien#endif
157390075Sobrien
157490075Sobrienstatic void
1575132718Skansdbout_end_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
157690075Sobrien{
157718334Speter  sdb_begin_function_line = line - 1;
157818334Speter  PUT_SDB_FUNCTION_START (line);
157918334Speter  sdbout_parms (DECL_ARGUMENTS (current_function_decl));
158018334Speter  sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl));
158118334Speter}
158218334Speter
158318334Speter/* Called at end of function (before epilogue).
158418334Speter   Describe end of outermost block.  */
158518334Speter
158690075Sobrienstatic void
1587132718Skansdbout_end_function (unsigned int line)
158818334Speter{
158918334Speter#ifdef SDB_ALLOW_FORWARD_REFERENCES
159018334Speter  sdbout_dequeue_anonymous_types ();
159118334Speter#endif
159218334Speter
159318334Speter  MAKE_LINE_SAFE (line);
159418334Speter  PUT_SDB_FUNCTION_END (line - sdb_begin_function_line);
159518334Speter
159618334Speter  /* Indicate we are between functions, for line-number output.  */
159718334Speter  sdb_begin_function_line = -1;
159818334Speter}
159918334Speter
160018334Speter/* Output sdb info for the absolute end of a function.
160118334Speter   Called after the epilogue is output.  */
160218334Speter
160390075Sobrienstatic void
1604132718Skansdbout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
1605132718Skan		     const char *file ATTRIBUTE_UNUSED)
160618334Speter{
160790075Sobrien  const char *const name ATTRIBUTE_UNUSED
160890075Sobrien    = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
160990075Sobrien
161090075Sobrien#ifdef PUT_SDB_EPILOGUE_END
161118334Speter  PUT_SDB_EPILOGUE_END (name);
161290075Sobrien#else
161390075Sobrien  fprintf (asm_out_file, "\t.def\t");
161490075Sobrien  assemble_name (asm_out_file, name);
161590075Sobrien  fprintf (asm_out_file, "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n",
161690075Sobrien	   SDB_DELIM, SDB_DELIM, SDB_DELIM);
161790075Sobrien#endif
161818334Speter}
161918334Speter
162018334Speter/* Output sdb info for the given label.  Called only if LABEL_NAME (insn)
162118334Speter   is present.  */
162218334Speter
162390075Sobrienstatic void
1624132718Skansdbout_label (rtx insn)
162518334Speter{
162618334Speter  PUT_SDB_DEF (LABEL_NAME (insn));
162718334Speter  PUT_SDB_VAL (insn);
162818334Speter  PUT_SDB_SCL (C_LABEL);
162918334Speter  PUT_SDB_TYPE (T_NULL);
163018334Speter  PUT_SDB_ENDEF;
163118334Speter}
163218334Speter
163350397Sobrien/* Change to reading from a new source file.  */
163450397Sobrien
163590075Sobrienstatic void
1636132718Skansdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
1637132718Skan			  const char *filename ATTRIBUTE_UNUSED)
163850397Sobrien{
163950397Sobrien#ifdef MIPS_DEBUGGING_INFO
1640132718Skan  struct sdb_file *n = xmalloc (sizeof *n);
164150397Sobrien
164250397Sobrien  n->next = current_file;
164350397Sobrien  n->name = filename;
164450397Sobrien  current_file = n;
1645169689Skan  output_file_directive (asm_out_file, filename);
164650397Sobrien#endif
164750397Sobrien}
164850397Sobrien
164950397Sobrien/* Revert to reading a previous source file.  */
165050397Sobrien
165190075Sobrienstatic void
1652132718Skansdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
165350397Sobrien{
165450397Sobrien#ifdef MIPS_DEBUGGING_INFO
165550397Sobrien  struct sdb_file *next;
165650397Sobrien
165750397Sobrien  next = current_file->next;
165850397Sobrien  free (current_file);
165950397Sobrien  current_file = next;
1660169689Skan  output_file_directive (asm_out_file, current_file->name);
166150397Sobrien#endif
166250397Sobrien}
166350397Sobrien
166490075Sobrien/* Set up for SDB output at the start of compilation.  */
166590075Sobrien
166690075Sobrienstatic void
1667132718Skansdbout_init (const char *input_file_name ATTRIBUTE_UNUSED)
166890075Sobrien{
1669169689Skan  tree t;
1670169689Skan
167190075Sobrien#ifdef MIPS_DEBUGGING_INFO
1672132718Skan  current_file = xmalloc (sizeof *current_file);
167390075Sobrien  current_file->next = NULL;
167490075Sobrien  current_file->name = input_file_name;
167590075Sobrien#endif
1676169689Skan
1677169689Skan  VARRAY_TREE_INIT (deferred_global_decls, 12, "deferred_global_decls");
1678169689Skan
1679169689Skan  /* Emit debug information which was queued by sdbout_symbol before
1680169689Skan     we got here.  */
1681169689Skan  sdbout_initialized = true;
1682169689Skan
1683169689Skan  for (t = nreverse (preinit_symbols); t; t = TREE_CHAIN (t))
1684169689Skan    sdbout_symbol (TREE_VALUE (t), 0);
1685169689Skan  preinit_symbols = 0;
168690075Sobrien}
168790075Sobrien
1688117395Skan#else  /* SDB_DEBUGGING_INFO */
1689117395Skan
1690117395Skan/* This should never be used, but its address is needed for comparisons.  */
1691117395Skanconst struct gcc_debug_hooks sdb_debug_hooks;
1692117395Skan
169318334Speter#endif /* SDB_DEBUGGING_INFO */
1694117395Skan
1695117395Skan#include "gt-sdbout.h"
1696