/* Output sdb-format symbol table information from GNU compiler.
- Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Free Software Foundation, Inc.
This file is part of GNU CC.
#include "reload.h"
#include "output.h"
#include "toplev.h"
+#include "tm_p.h"
/* Mips systems use the SDB functions to dump out symbols, but do not
supply usable syms.h include files. Which syms.h file to use is a
target parameter so don't use the native one if we're cross compiling. */
-#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(CROSS_COMPILE)
+#if defined(USG) && !defined(MIPS) && !defined (hpux) && !defined(_WIN32) && !defined(__linux__) && !defined(__INTERIX) && !defined(CROSS_COMPILE)
#include <syms.h>
/* Use T_INT if we don't have T_VOID. */
#ifndef T_VOID
#include "sdbout.h"
-static char *gen_fake_label PROTO((void));
-static int plain_type PROTO((tree));
-static int template_name_p PROTO((tree));
-static void sdbout_record_type_name PROTO((tree));
-static int plain_type_1 PROTO((tree, int));
-static void sdbout_block PROTO((tree));
-static void sdbout_syms PROTO((tree));
-static void sdbout_queue_anonymous_type PROTO((tree));
-static void sdbout_dequeue_anonymous_types PROTO((void));
-static void sdbout_type PROTO((tree));
-static void sdbout_field_types PROTO((tree));
-static void sdbout_one_type PROTO((tree));
-static void sdbout_parms PROTO((tree));
-static void sdbout_reg_parms PROTO((tree));
-\f
-/* Define the default sizes for various types. */
-
-#ifndef CHAR_TYPE_SIZE
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-#endif
-
-#ifndef SHORT_TYPE_SIZE
-#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2))
-#endif
-
-#ifndef INT_TYPE_SIZE
-#define INT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef LONG_TYPE_SIZE
-#define LONG_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef LONG_LONG_TYPE_SIZE
-#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
-#endif
-
-#ifndef FLOAT_TYPE_SIZE
-#define FLOAT_TYPE_SIZE BITS_PER_WORD
-#endif
-
-#ifndef DOUBLE_TYPE_SIZE
-#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
-#endif
-
-#ifndef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
+static char *gen_fake_label PARAMS ((void));
+static int plain_type PARAMS ((tree));
+static int template_name_p PARAMS ((tree));
+static void sdbout_record_type_name PARAMS ((tree));
+static int plain_type_1 PARAMS ((tree, int));
+static void sdbout_block PARAMS ((tree));
+static void sdbout_syms PARAMS ((tree));
+#ifdef SDB_ALLOW_FORWARD_REFERENCES
+static void sdbout_queue_anonymous_type PARAMS ((tree));
+static void sdbout_dequeue_anonymous_types PARAMS ((void));
#endif
+static void sdbout_type PARAMS ((tree));
+static void sdbout_field_types PARAMS ((tree));
+static void sdbout_one_type PARAMS ((tree));
+static void sdbout_parms PARAMS ((tree));
+static void sdbout_reg_parms PARAMS ((tree));
\f
/* Random macros describing parts of SDB data. */
#ifndef PUT_SDB_DEF
#define PUT_SDB_DEF(a) \
+
+#undef PUT_SDB_DEF
+PUT_SDB_DEF(a) \
+char *a; {
do { fprintf (asm_out_file, "\t.def\t"); \
- ASM_OUTPUT_LABELREF (asm_out_file, a); \
+ assemble_name (asm_out_file, a); \
fprintf (asm_out_file, SDB_DELIM); } while (0)
+; }
#endif
#ifndef PUT_SDB_PLAIN_DEF
#ifndef PUT_SDB_TAG
#define PUT_SDB_TAG(a) \
do { fprintf (asm_out_file, "\t.tag\t"); \
- ASM_OUTPUT_LABELREF (asm_out_file, a); \
+ assemble_name (asm_out_file, a); \
fprintf (asm_out_file, SDB_DELIM); } while (0)
#endif
#ifndef PUT_SDB_EPILOGUE_END
#define PUT_SDB_EPILOGUE_END(NAME) \
do { fprintf (asm_out_file, "\t.def\t"); \
- ASM_OUTPUT_LABELREF (asm_out_file, NAME); \
+ assemble_name (asm_out_file, NAME); \
fprintf (asm_out_file, \
"%s\t.val\t.%s\t.scl\t-1%s\t.endef\n", \
SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0)
struct sdb_file
{
struct sdb_file *next;
- char *name;
+ const char *name;
};
/* This is the top of the stack. */
void
sdbout_init (asm_file, input_file_name, syms)
- FILE *asm_file;
- char *input_file_name;
- tree syms;
+ FILE *asm_file ATTRIBUTE_UNUSED;
+ const char *input_file_name ATTRIBUTE_UNUSED;
+ tree syms ATTRIBUTE_UNUSED;
{
#ifdef MIPS_DEBUGGING_INFO
current_file = (struct sdb_file *) xmalloc (sizeof *current_file);
{
case VOID_TYPE:
return T_VOID;
+ case BOOLEAN_TYPE:
case INTEGER_TYPE:
{
int size = int_size_in_bytes (type) * BITS_PER_UNIT;
if (sdb_n_dims < SDB_MAX_DIM)
sdb_dims[sdb_n_dims++]
= (TYPE_DOMAIN (type)
- && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
- && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST
- && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST
- ? (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
- - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1)
+ && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != 0
+ && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != 0
+ && host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
+ && host_integerp (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0)
+ ? (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
+ - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1)
: 0);
+
return PUSH_DERIVED_LEVEL (DT_ARY, m);
}
}
\f
/* Output the symbols defined in block number DO_BLOCK.
- Set NEXT_BLOCK_NUMBER to 0 before calling.
This function works by walking the tree structure of blocks,
counting blocks until it finds the desired block. */
static int do_block = 0;
-static int next_block_number;
-
static void
sdbout_block (block)
register tree block;
if (TREE_USED (block))
{
/* When we reach the specified block, output its symbols. */
- if (next_block_number == do_block)
- {
- sdbout_syms (BLOCK_VARS (block));
- }
+ if (BLOCK_NUMBER (block) == do_block)
+ sdbout_syms (BLOCK_VARS (block));
/* If we are past the specified block, stop the scan. */
- if (next_block_number > do_block)
+ if (BLOCK_NUMBER (block) > do_block)
return;
- next_block_number++;
-
/* Scan the blocks within this block. */
sdbout_block (BLOCK_SUBBLOCKS (block));
}
DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
#ifdef LEAF_REG_REMAP
- if (leaf_function)
+ if (current_function_uses_only_leaf_regs)
leaf_renumber_regs_insn (DECL_RTL (decl));
#endif
value = DECL_RTL (decl);
|| TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE)
{
- if (TYPE_SIZE (type) != 0 /* not a forward reference */
+ if (COMPLETE_TYPE_P (type) /* not a forward reference */
&& KNOWN_TYPE_TAG (type) == 0) /* not yet declared */
sdbout_one_type (type);
}
PUT_SDB_SCL (C_AUTO);
}
- type = build_pointer_type (TREE_TYPE (decl));
+ /* Effectively do build_pointer_type, but don't cache this type,
+ since it might be temporary whereas the type it points to
+ might have been saved for inlining. */
+ /* Don't use REFERENCE_TYPE because dbx can't handle that. */
+ type = make_node (POINTER_TYPE);
+ TREE_TYPE (type) = TREE_TYPE (decl);
}
else if (GET_CODE (value) == MEM
&& ((GET_CODE (XEXP (value, 0)) == PLUS
tree tail;
for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
- if (POINTER_TYPE_P (TREE_TYPE (tail)))
- sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
- else
- sdbout_one_type (TREE_TYPE (tail));
+ /* This condition should match the one for emitting the actual members
+ below. */
+ if (TREE_CODE (tail) == FIELD_DECL
+ && DECL_NAME (tail) != 0
+ && ! host_integerp (DECL_SIZE (tail), 1)
+ && ! host_integerp (bit_position (tail), 0))
+ {
+ if (POINTER_TYPE_P (TREE_TYPE (tail)))
+ sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
+ else
+ sdbout_one_type (TREE_TYPE (tail));
+ }
}
/* Use this to put out the top level defined record and union types
return;
/* Output nothing if type is not yet defined. */
- if (TYPE_SIZE (type) == 0)
+ if (!COMPLETE_TYPE_P (type))
return;
TREE_ASM_WRITTEN (type) = 1;
/* Output a structure type. */
{
int size = int_size_in_bytes (type);
- int member_scl;
+ int member_scl = 0;
tree tem;
int i, n_baseclasses = 0;
/* Print out the base class information with fields
named after the types they hold. */
- if (TYPE_BINFO (type)
- && TYPE_BINFO_BASETYPES (type))
- n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
- for (i = 0; i < n_baseclasses; i++)
+ /* This is only relevent to aggregate types. TYPE_BINFO is used
+ for other purposes in an ENUMERAL_TYPE, so we must exclude that
+ case. */
+ if (TREE_CODE (type) != ENUMERAL_TYPE)
{
- tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
- tree child_type = BINFO_TYPE (child);
- tree child_type_name;
- if (TYPE_NAME (child_type) == 0)
- continue;
- if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
- child_type_name = TYPE_NAME (child_type);
- else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL)
+ if (TYPE_BINFO (type)
+ && TYPE_BINFO_BASETYPES (type))
+ n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
+ for (i = 0; i < n_baseclasses; i++)
{
- child_type_name = DECL_NAME (TYPE_NAME (child_type));
- if (child_type_name && template_name_p (child_type_name))
- child_type_name
- = DECL_ASSEMBLER_NAME (TYPE_NAME (child_type));
- }
- else
- continue;
+ tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)),
+ i);
+ tree child_type = BINFO_TYPE (child);
+ tree child_type_name;
+ if (TYPE_NAME (child_type) == 0)
+ continue;
+ if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
+ child_type_name = TYPE_NAME (child_type);
+ else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL)
+ {
+ child_type_name = DECL_NAME (TYPE_NAME (child_type));
+ if (child_type_name && template_name_p (child_type_name))
+ child_type_name
+ = DECL_ASSEMBLER_NAME (TYPE_NAME (child_type));
+ }
+ else
+ continue;
- CONTIN;
- PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
- PUT_SDB_INT_VAL (TREE_INT_CST_LOW (BINFO_OFFSET (child)));
- PUT_SDB_SCL (member_scl);
- sdbout_type (BINFO_TYPE (child));
- PUT_SDB_ENDEF;
+ CONTIN;
+ PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
+ PUT_SDB_INT_VAL (tree_low_cst (BINFO_OFFSET (child), 0));
+ PUT_SDB_SCL (member_scl);
+ sdbout_type (BINFO_TYPE (child));
+ PUT_SDB_ENDEF;
+ }
}
/* output the individual fields */
if (TREE_CODE (type) == ENUMERAL_TYPE)
- for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
- {
- PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
- PUT_SDB_INT_VAL (TREE_INT_CST_LOW (TREE_VALUE (tem)));
- PUT_SDB_SCL (C_MOE);
- PUT_SDB_TYPE (T_MOE);
- PUT_SDB_ENDEF;
- }
-
+ {
+ for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
+ if (host_integerp (TREE_VALUE (tem), 0))
+ {
+ PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
+ PUT_SDB_INT_VAL (tree_low_cst (TREE_VALUE (tem), 0));
+ PUT_SDB_SCL (C_MOE);
+ PUT_SDB_TYPE (T_MOE);
+ PUT_SDB_ENDEF;
+ }
+ }
else /* record or union type */
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
/* Output the name, type, position (in bits), size (in bits)
Also omit non FIELD_DECL nodes that GNU C++ may put here. */
if (TREE_CODE (tem) == FIELD_DECL
&& DECL_NAME (tem) != 0
- && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST
- && TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)
+ && host_integerp (DECL_SIZE (tem), 1)
+ && host_integerp (bit_position (tem), 0))
{
char *name;
PUT_SDB_DEF (name);
if (DECL_BIT_FIELD_TYPE (tem))
{
- PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
+ PUT_SDB_INT_VAL (int_bit_position (tem));
PUT_SDB_SCL (C_FIELD);
sdbout_type (DECL_BIT_FIELD_TYPE (tem));
- PUT_SDB_SIZE (TREE_INT_CST_LOW (DECL_SIZE (tem)));
+ PUT_SDB_SIZE (tree_low_cst (DECL_SIZE (tem), 1));
}
else
{
- PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))
- / BITS_PER_UNIT);
+ PUT_SDB_INT_VAL (int_bit_position (tem) / BITS_PER_UNIT);
PUT_SDB_SCL (member_scl);
sdbout_type (TREE_TYPE (tem));
}
current_sym_value = 0;
if (GET_CODE (DECL_RTL (parms)) == REG
- && REGNO (DECL_RTL (parms)) >= 0
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
type = DECL_ARG_TYPE (parms);
else
pretend the parm was passed there. It would be more consistent
to describe the register where the parm was passed,
but in practice that register usually holds something else. */
- if (REGNO (DECL_RTL (parms)) >= 0
- && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
+ if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
best_rtl = DECL_RTL (parms);
/* If the parm lives nowhere,
use the register where it was passed. */
/* Report parms that live in registers during the function
but were passed in memory. */
if (GET_CODE (DECL_RTL (parms)) == REG
- && REGNO (DECL_RTL (parms)) >= 0
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
&& PARM_PASSED_IN_MEMORY (parms))
{
void
sdbout_begin_block (file, line, n)
- FILE *file;
+ FILE *file ATTRIBUTE_UNUSED;
int line;
int n;
{
if (n == 1)
{
/* Include the outermost BLOCK's variables in block 1. */
- next_block_number = 0;
- do_block = 0;
+ do_block = BLOCK_NUMBER (DECL_INITIAL (decl));
sdbout_block (DECL_INITIAL (decl));
}
/* If -g1, suppress all the internal symbols of functions
except for arguments. */
if (debug_info_level != DINFO_LEVEL_TERSE)
{
- next_block_number = 0;
do_block = n;
sdbout_block (DECL_INITIAL (decl));
}
void
sdbout_end_block (file, line, n)
- FILE *file;
+ FILE *file ATTRIBUTE_UNUSED;
int line;
- int n;
+ int n ATTRIBUTE_UNUSED;
{
MAKE_LINE_SAFE (line);
void
sdbout_start_new_source_file (filename)
- char *filename;
+ const char *filename ATTRIBUTE_UNUSED;
{
#ifdef MIPS_DEBUGGING_INFO
struct sdb_file *n = (struct sdb_file *) xmalloc (sizeof *n);