/* Forward declarations for functions defined in this file. */
-static char *stripattributes PROTO((char *));
-static char *dwarf_cfi_name PROTO((unsigned));
+static char *stripattributes PROTO((const char *));
+static const char *dwarf_cfi_name PROTO((unsigned));
static dw_cfi_ref new_cfi PROTO((void));
static void add_cfi PROTO((dw_cfi_ref *, dw_cfi_ref));
static unsigned long size_of_uleb128 PROTO((unsigned long));
static void output_call_frame_info PROTO((int));
static unsigned reg_number PROTO((rtx));
static void dwarf2out_stack_adjust PROTO((rtx));
+static void dwarf2out_frame_debug_expr PROTO((rtx, char *));
/* Definitions of defaults for assembler-dependent names of various
pseudo-ops and section names.
#define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2) \
assemble_integer (gen_rtx_MINUS (HImode, \
- gen_rtx_SYMBOL_REF (Pmode, LABEL1), \
- gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
+ gen_rtx_SYMBOL_REF (Pmode, LABEL1), \
+ gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
2, 1)
#define ASM_OUTPUT_DWARF_DELTA4(FILE,LABEL1,LABEL2) \
assemble_integer (gen_rtx_MINUS (SImode, \
- gen_rtx_SYMBOL_REF (Pmode, LABEL1), \
- gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
+ gen_rtx_SYMBOL_REF (Pmode, LABEL1), \
+ gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
4, 1)
#define ASM_OUTPUT_DWARF_ADDR_DELTA(FILE,LABEL1,LABEL2) \
assemble_integer (gen_rtx_MINUS (Pmode, \
- gen_rtx_SYMBOL_REF (Pmode, LABEL1), \
- gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
+ gen_rtx_SYMBOL_REF (Pmode, LABEL1), \
+ gen_rtx_SYMBOL_REF (Pmode, LABEL2)), \
PTR_SIZE, 1)
#define ASM_OUTPUT_DWARF_DELTA(FILE,LABEL1,LABEL2) \
#define ASM_OUTPUT_DWARF_STRING(FILE,P) \
do { \
register int slen = strlen(P); \
- register char *p = (P); \
+ register const char *p = (P); \
register int i; \
fprintf (FILE, "\t.ascii \""); \
for (i = 0; i < slen; i++) \
register int c = p[i]; \
if (c == '\"' || c == '\\') \
putc ('\\', FILE); \
- if (c >= ' ' && c < 0177) \
+ if (ISPRINT(c)) \
putc (c, FILE); \
else \
{ \
static inline char *
stripattributes (s)
- char *s;
+ const char *s;
{
char *stripped = xmalloc (strlen (s) + 2);
char *p = stripped;
/* Convert a DWARF call frame info. operation to its string name */
-static char *
+static const char *
dwarf_cfi_name (cfi_opc)
register unsigned cfi_opc;
{
if (GET_CODE (x) == SET &&
(RTX_FRAME_RELATED_P (x) || par_index == 0))
- dwarf2out_frame_debug_expr (x, label);
+ dwarf2out_frame_debug_expr (x, label);
}
return;
}
if (cfa_reg != (unsigned) REGNO (src))
abort ();
if (REGNO (dest) != STACK_POINTER_REGNUM
- && !(frame_pointer_needed
- && REGNO (dest) == HARD_FRAME_POINTER_REGNUM))
+ && !(frame_pointer_needed
+ && REGNO (dest) == HARD_FRAME_POINTER_REGNUM))
abort ();
cfa_reg = REGNO (dest);
break;
case MINUS:
if (dest == stack_pointer_rtx)
{
- /* Adjusting SP. */
- switch (GET_CODE (XEXP (src, 1)))
- {
- case CONST_INT:
- offset = INTVAL (XEXP (src, 1));
- break;
- case REG:
- if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp_reg)
- abort ();
- offset = cfa_temp_value;
- break;
- default:
- abort ();
- }
-
- if (XEXP (src, 0) == hard_frame_pointer_rtx)
- {
- /* Restoring SP from FP in the epilogue. */
- if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
- abort ();
- cfa_reg = STACK_POINTER_REGNUM;
- }
- else if (XEXP (src, 0) != stack_pointer_rtx)
- abort ();
-
- if (GET_CODE (src) == PLUS)
- offset = -offset;
- if (cfa_reg == STACK_POINTER_REGNUM)
- cfa_offset += offset;
- if (cfa_store_reg == STACK_POINTER_REGNUM)
- cfa_store_offset += offset;
+ /* Adjusting SP. */
+ switch (GET_CODE (XEXP (src, 1)))
+ {
+ case CONST_INT:
+ offset = INTVAL (XEXP (src, 1));
+ break;
+ case REG:
+ if ((unsigned) REGNO (XEXP (src, 1)) != cfa_temp_reg)
+ abort ();
+ offset = cfa_temp_value;
+ break;
+ default:
+ abort ();
+ }
+
+ if (XEXP (src, 0) == hard_frame_pointer_rtx)
+ {
+ /* Restoring SP from FP in the epilogue. */
+ if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
+ abort ();
+ cfa_reg = STACK_POINTER_REGNUM;
+ }
+ else if (XEXP (src, 0) != stack_pointer_rtx)
+ abort ();
+
+ if (GET_CODE (src) == PLUS)
+ offset = -offset;
+ if (cfa_reg == STACK_POINTER_REGNUM)
+ cfa_offset += offset;
+ if (cfa_store_reg == STACK_POINTER_REGNUM)
+ cfa_store_offset += offset;
}
else if (dest == hard_frame_pointer_rtx)
{
- /* Either setting the FP from an offset of the SP,
- or adjusting the FP */
- if (! frame_pointer_needed
- || REGNO (dest) != HARD_FRAME_POINTER_REGNUM)
- abort ();
-
- if (XEXP (src, 0) == stack_pointer_rtx
- && GET_CODE (XEXP (src, 1)) == CONST_INT)
- {
- if (cfa_reg != STACK_POINTER_REGNUM)
- abort ();
- offset = INTVAL (XEXP (src, 1));
- if (GET_CODE (src) == PLUS)
- offset = -offset;
- cfa_offset += offset;
- cfa_reg = HARD_FRAME_POINTER_REGNUM;
- }
- else if (XEXP (src, 0) == hard_frame_pointer_rtx
- && GET_CODE (XEXP (src, 1)) == CONST_INT)
- {
- if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
- abort ();
- offset = INTVAL (XEXP (src, 1));
- if (GET_CODE (src) == PLUS)
- offset = -offset;
- cfa_offset += offset;
- }
-
- else
- abort();
+ /* Either setting the FP from an offset of the SP,
+ or adjusting the FP */
+ if (! frame_pointer_needed
+ || REGNO (dest) != HARD_FRAME_POINTER_REGNUM)
+ abort ();
+
+ if (XEXP (src, 0) == stack_pointer_rtx
+ && GET_CODE (XEXP (src, 1)) == CONST_INT)
+ {
+ if (cfa_reg != STACK_POINTER_REGNUM)
+ abort ();
+ offset = INTVAL (XEXP (src, 1));
+ if (GET_CODE (src) == PLUS)
+ offset = -offset;
+ cfa_offset += offset;
+ cfa_reg = HARD_FRAME_POINTER_REGNUM;
+ }
+ else if (XEXP (src, 0) == hard_frame_pointer_rtx
+ && GET_CODE (XEXP (src, 1)) == CONST_INT)
+ {
+ if (cfa_reg != (unsigned) HARD_FRAME_POINTER_REGNUM)
+ abort ();
+ offset = INTVAL (XEXP (src, 1));
+ if (GET_CODE (src) == PLUS)
+ offset = -offset;
+ cfa_offset += offset;
+ }
+
+ else
+ abort();
}
else
{
- if (GET_CODE (src) != PLUS
- || XEXP (src, 1) != stack_pointer_rtx)
- abort ();
- if (GET_CODE (XEXP (src, 0)) != REG
- || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg)
- abort ();
- if (cfa_reg != STACK_POINTER_REGNUM)
- abort ();
- cfa_store_reg = REGNO (dest);
- cfa_store_offset = cfa_offset - cfa_temp_value;
+ if (GET_CODE (src) != PLUS
+ || XEXP (src, 1) != stack_pointer_rtx)
+ abort ();
+ if (GET_CODE (XEXP (src, 0)) != REG
+ || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg)
+ abort ();
+ if (cfa_reg != STACK_POINTER_REGNUM)
+ abort ();
+ cfa_store_reg = REGNO (dest);
+ cfa_store_offset = cfa_offset - cfa_temp_value;
}
break;
case IOR:
if (GET_CODE (XEXP (src, 0)) != REG
- || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg
- || (unsigned) REGNO (dest) != cfa_temp_reg
- || GET_CODE (XEXP (src, 1)) != CONST_INT)
+ || (unsigned) REGNO (XEXP (src, 0)) != cfa_temp_reg
+ || (unsigned) REGNO (dest) != cfa_temp_reg
+ || GET_CODE (XEXP (src, 1)) != CONST_INT)
abort ();
cfa_temp_value |= INTVAL (XEXP (src, 1));
break;
abort ();
}
dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
- break;
+ break;
- case MEM:
- /* Saving a register to the stack. Make sure dest is relative to the
- CFA register. */
- if (GET_CODE (src) != REG)
- abort ();
- switch (GET_CODE (XEXP (dest, 0)))
- {
- /* With a push. */
- case PRE_INC:
- case PRE_DEC:
- offset = GET_MODE_SIZE (GET_MODE (dest));
- if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
- offset = -offset;
-
- if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM
- || cfa_store_reg != STACK_POINTER_REGNUM)
- abort ();
- cfa_store_offset += offset;
- if (cfa_reg == STACK_POINTER_REGNUM)
- cfa_offset = cfa_store_offset;
+ case MEM:
+ /* Saving a register to the stack. Make sure dest is relative to the
+ CFA register. */
+ if (GET_CODE (src) != REG)
+ abort ();
+ switch (GET_CODE (XEXP (dest, 0)))
+ {
+ /* With a push. */
+ case PRE_INC:
+ case PRE_DEC:
+ offset = GET_MODE_SIZE (GET_MODE (dest));
+ if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
+ offset = -offset;
- offset = -cfa_store_offset;
- break;
+ if (REGNO (XEXP (XEXP (dest, 0), 0)) != STACK_POINTER_REGNUM
+ || cfa_store_reg != STACK_POINTER_REGNUM)
+ abort ();
+ cfa_store_offset += offset;
+ if (cfa_reg == STACK_POINTER_REGNUM)
+ cfa_offset = cfa_store_offset;
- /* With an offset. */
- case PLUS:
- case MINUS:
- offset = INTVAL (XEXP (XEXP (dest, 0), 1));
- if (GET_CODE (XEXP (dest, 0)) == MINUS)
- offset = -offset;
+ offset = -cfa_store_offset;
+ break;
- if (cfa_store_reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
- abort ();
- offset -= cfa_store_offset;
- break;
-
- /* Without an offset. */
- case REG:
- if (cfa_store_reg != (unsigned) REGNO (XEXP (dest, 0)))
- abort();
- offset = -cfa_store_offset;
- break;
-
- default:
- abort ();
- }
- dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
- dwarf2out_reg_save (label, REGNO (src), offset);
- break;
+ /* With an offset. */
+ case PLUS:
+ case MINUS:
+ offset = INTVAL (XEXP (XEXP (dest, 0), 1));
+ if (GET_CODE (XEXP (dest, 0)) == MINUS)
+ offset = -offset;
- default:
- abort ();
- }
+ if (cfa_store_reg != (unsigned) REGNO (XEXP (XEXP (dest, 0), 0)))
+ abort ();
+ offset -= cfa_store_offset;
+ break;
+
+ /* Without an offset. */
+ case REG:
+ if (cfa_store_reg != (unsigned) REGNO (XEXP (dest, 0)))
+ abort();
+ offset = -cfa_store_offset;
+ break;
+
+ default:
+ abort ();
+ }
+ dwarf2out_def_cfa (label, cfa_reg, cfa_offset);
+ dwarf2out_reg_save (label, REGNO (src), offset);
+ break;
+
+ default:
+ abort ();
+ }
}
}
}
-#if !defined (EH_FRAME_SECTION)
-#if defined (EH_FRAME_SECTION_ASM_OP)
-#define EH_FRAME_SECTION() eh_frame_section();
-#else
-#if defined (ASM_OUTPUT_SECTION_NAME)
-#define EH_FRAME_SECTION() \
- do { \
- named_section (NULL_TREE, ".eh_frame", 0); \
- } while (0)
-#endif
-#endif
-#endif
-
-/* If we aren't using crtstuff to run ctors, don't use it for EH. */
-#if !defined (HAS_INIT_SECTION) && !defined (INIT_SECTION_ASM_OP)
-#undef EH_FRAME_SECTION
-#endif
-
/* Output the call frame information used to used to record information
that relates to calculating the frame pointer, and records the
location of saved registers. */
dwarf2out_frame_init ()
{
/* Allocate the initial hunk of the fde_table. */
- fde_table
- = (dw_fde_ref) xmalloc (FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
- bzero ((char *) fde_table, FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
+ fde_table = (dw_fde_ref) xcalloc (FDE_TABLE_INCREMENT, sizeof (dw_fde_node));
fde_table_allocated = FDE_TABLE_INCREMENT;
fde_table_in_use = 0;
/* And now, the support for symbolic debugging information. */
#ifdef DWARF2_DEBUGGING_INFO
-extern char *getpwd PROTO((void));
-
/* NOTE: In the comments in this file, many references are made to
"Debugging Information Entries". This term is abbreviated as `DIE'
throughout the remainder of this file. */
extern int flag_traditional;
extern char *version_string;
-extern char *language_string;
/* Fixed size portion of the DWARF compilation unit header. */
#define DWARF_COMPILE_UNIT_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 3)
#define DWARF_ARANGES_HEADER_SIZE \
(DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, PTR_SIZE * 2) - DWARF_OFFSET_SIZE)
+/* The default is to have gcc emit the line number tables. */
+#ifndef DWARF2_ASM_LINE_DEBUG_INFO
+#define DWARF2_ASM_LINE_DEBUG_INFO 0
+#endif
+
/* Define the architecture-dependent minimum instruction length (in bytes).
In this implementation of DWARF, this field is used for information
purposes only. Since GCC generates assembly language, we have
be enough for most typical programs. */
#define PENDING_TYPES_INCREMENT 64
+/* A pointer to the base of a list of incomplete types which might be
+ completed at some later time. */
+
+static tree *incomplete_types_list;
+
+/* Number of elements currently allocated for the incomplete_types_list. */
+static unsigned incomplete_types_allocated;
+
+/* Number of elements of incomplete_types_list currently in use. */
+static unsigned incomplete_types;
+
+/* Size (in elements) of increments by which we may expand the incomplete
+ types list. Actually, a single hunk of space of this size should
+ be enough for most typical programs. */
+#define INCOMPLETE_TYPES_INCREMENT 64
+
/* Record whether the function being analyzed contains inlined functions. */
static int current_function_has_inlines;
#if 0 && defined (MIPS_DEBUGGING_INFO)
static int is_pseudo_reg PROTO((rtx));
static tree type_main_variant PROTO((tree));
static int is_tagged_type PROTO((tree));
-static char *dwarf_tag_name PROTO((unsigned));
-static char *dwarf_attr_name PROTO((unsigned));
-static char *dwarf_form_name PROTO((unsigned));
-static char *dwarf_stack_op_name PROTO((unsigned));
+static const char *dwarf_tag_name PROTO((unsigned));
+static const char *dwarf_attr_name PROTO((unsigned));
+static const char *dwarf_form_name PROTO((unsigned));
+static const char *dwarf_stack_op_name PROTO((unsigned));
#if 0
-static char *dwarf_type_encoding_name PROTO((unsigned));
+static const char *dwarf_type_encoding_name PROTO((unsigned));
#endif
static tree decl_ultimate_origin PROTO((tree));
static tree block_ultimate_origin PROTO((tree));
enum dwarf_attribute,
unsigned, long *));
static void add_AT_string PROTO((dw_die_ref,
- enum dwarf_attribute, char *));
+ enum dwarf_attribute,
+ const char *));
static void add_AT_die_ref PROTO((dw_die_ref,
enum dwarf_attribute,
dw_die_ref));
static unsigned long sibling_offset PROTO((dw_die_ref));
static void output_die PROTO((dw_die_ref));
static void output_compilation_unit_header PROTO((void));
-static char *dwarf2_name PROTO((tree, int));
+static const char *dwarf2_name PROTO((tree, int));
static void add_pubname PROTO((tree, dw_die_ref));
static void output_pubnames PROTO((void));
static void add_arange PROTO((tree, dw_die_ref));
static dw_loc_descr_ref reg_loc_descriptor PROTO((rtx));
static dw_loc_descr_ref based_loc_descr PROTO((unsigned, long));
static int is_based_loc PROTO((rtx));
-static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx));
+static dw_loc_descr_ref mem_loc_descriptor PROTO((rtx, enum machine_mode mode));
static dw_loc_descr_ref concat_loc_descriptor PROTO((rtx, rtx));
static dw_loc_descr_ref loc_descriptor PROTO((rtx));
static unsigned ceiling PROTO((unsigned, unsigned));
static void add_data_member_location_attribute PROTO((dw_die_ref, tree));
static void add_const_value_attribute PROTO((dw_die_ref, rtx));
static void add_location_or_const_value_attribute PROTO((dw_die_ref, tree));
-static void add_name_attribute PROTO((dw_die_ref, char *));
+static void add_name_attribute PROTO((dw_die_ref, const char *));
static void add_bound_info PROTO((dw_die_ref,
enum dwarf_attribute, tree));
static void add_subscript_info PROTO((dw_die_ref, tree));
static void decls_for_scope PROTO((tree, dw_die_ref, int));
static int is_redundant_typedef PROTO((tree));
static void gen_decl_die PROTO((tree, dw_die_ref));
-static unsigned lookup_filename PROTO((char *));
+static unsigned lookup_filename PROTO((const char *));
+static void add_incomplete_type PROTO((tree));
+static void retry_incomplete_types PROTO((void));
/* Section names used to hold DWARF debugging information. */
#ifndef DEBUG_INFO_SECTION
dyn_string_append (STR, NAME + 1); \
else \
{ \
- char *newstr; \
+ const char *newstr; \
STRIP_NAME_ENCODING (newstr, NAME); \
dyn_string_append (STR, user_label_prefix); \
dyn_string_append (STR, newstr); \
/* Convert a DIE tag into its string name. */
-static char *
+static const char *
dwarf_tag_name (tag)
register unsigned tag;
{
/* Convert a DWARF attribute code into its string name. */
-static char *
+static const char *
dwarf_attr_name (attr)
register unsigned attr;
{
/* Convert a DWARF value form code into its string name. */
-static char *
+static const char *
dwarf_form_name (form)
register unsigned form;
{
/* Convert a DWARF stack opcode into its string name. */
-static char *
+static const char *
dwarf_stack_op_name (op)
register unsigned op;
{
/* Convert a DWARF type code into its string name. */
#if 0
-static char *
+static const char *
dwarf_type_encoding_name (enc)
register unsigned enc;
{
add_AT_string (die, attr_kind, str)
register dw_die_ref die;
register enum dwarf_attribute attr_kind;
- register char *str;
+ register const char *str;
{
register dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
register enum dwarf_attribute attr_kind;
{
register dw_attr_ref a;
- register dw_attr_ref removed = NULL;;
+ register dw_attr_ref removed = NULL;
if (die != NULL)
{
{
print_indent = 0;
print_die (comp_unit_die, stderr);
- print_dwarf_line_table (stderr);
+ if (! DWARF2_ASM_LINE_DEBUG_INFO)
+ print_dwarf_line_table (stderr);
}
\f
/* Traverse the DIE, and add a sibling attribute if it may have the
fprintf (asm_out_file, "\t%s\t0,0\n", ASM_BYTE_OP);
}
+
+ /* Terminate the table. */
+ fprintf (asm_out_file, "\t%s\t0\n", ASM_BYTE_OP);
}
/* Output location description stack opcode's operands (if any). */
of decl_printable_name for C++ looks like "A::f(int)". Let's drop the
argument list, and maybe the scope. */
-static char *
+static const char *
dwarf2_name (decl, scope)
tree decl;
int scope;
ASM_COMMENT_START);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 4);
- if (PTR_SIZE == 8)
+ /* We need to align to twice the pointer size here.
+ If DWARF_OFFSET_SIZE == 4, then we have emitted 12 bytes, and need 4
+ bytes of padding to align for either 4 or 8 byte pointers. */
+ ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
+ /* If DWARF_OFFSET_SIZE == 8, then we have emitted 20 bytes, and need 12
+ bytes of padding to align for 8 byte pointers. We have already emitted
+ 4 bytes of padding, so emit 8 more here. */
+ if (DWARF_OFFSET_SIZE == 8)
fprintf (asm_out_file, ",0,0");
if (flag_debug_asm)
When creating memory location descriptors, we are effectively transforming
the RTL for a memory-resident object into its Dwarf postfix expression
equivalent. This routine recursively descends an RTL tree, turning
- it into Dwarf postfix code as it goes. */
+ it into Dwarf postfix code as it goes.
+
+ MODE is the mode of the memory reference, needed to handle some
+ autoincrement addressing modes. */
static dw_loc_descr_ref
-mem_loc_descriptor (rtl)
+mem_loc_descriptor (rtl, mode)
register rtx rtl;
+ enum machine_mode mode;
{
dw_loc_descr_ref mem_loc_result = NULL;
/* Note that for a dynamically sized array, the location we will generate a
switch (GET_CODE (rtl))
{
+ case POST_INC:
+ case POST_DEC:
+ /* POST_INC and POST_DEC can be handled just like a SUBREG. So we
+ just fall into the SUBREG code. */
+
+ /* ... fall through ... */
+
case SUBREG:
/* The case of a subreg may arise when we have a local (register)
variable or a formal (register) parameter which doesn't quite fill
break;
case MEM:
- mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0));
+ mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
break;
+ case LABEL_REF:
+ /* Some ports can transform a symbol ref into a label ref, because
+ the symbol ref is too far away and has to be dumped into a constant
+ pool. */
case CONST:
case SYMBOL_REF:
mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
mem_loc_result->dw_loc_oprnd1.v.val_addr = addr_to_string (rtl);
break;
+ case PRE_INC:
+ case PRE_DEC:
+ /* Turn these into a PLUS expression and fall into the PLUS code
+ below. */
+ rtl = gen_rtx_PLUS (word_mode, XEXP (rtl, 0),
+ GEN_INT (GET_CODE (rtl) == PRE_INC
+ ? GET_MODE_UNIT_SIZE (mode)
+ : - GET_MODE_UNIT_SIZE (mode)));
+
+ /* ... fall through ... */
+
case PLUS:
if (is_based_loc (rtl))
mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)),
INTVAL (XEXP (rtl, 1)));
else
{
- add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0)));
- add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1)));
+ add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0),
+ mode));
+ add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1),
+ mode));
add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_plus, 0, 0));
}
break;
case MULT:
/* If a pseudo-reg is optimized away, it is possible for it to
be replaced with a MEM containing a multiply. */
- add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0)));
- add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1)));
+ add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 0), mode));
+ add_loc_descr (&mem_loc_result, mem_loc_descriptor (XEXP (rtl, 1), mode));
add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
break;
break;
case MEM:
- loc_result = mem_loc_descriptor (XEXP (rtl, 0));
+ loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
break;
case CONCAT:
rtl = DECL_INCOMING_RTL (decl);
else if (! BYTES_BIG_ENDIAN
&& TREE_CODE (declared_type) == INTEGER_TYPE
- && TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
+ && (GET_MODE_SIZE (TYPE_MODE (declared_type))
+ <= GET_MODE_SIZE (TYPE_MODE (passed_type))))
rtl = DECL_INCOMING_RTL (decl);
}
static inline void
add_name_attribute (die, name_string)
register dw_die_ref die;
- register char *name_string;
+ register const char *name_string;
{
if (name_string != NULL && *name_string != 0)
add_AT_string (die, DW_AT_name, name_string);
rtx new_addr = fix_lexical_addr (XEXP (loc, 0), bound);
if (XEXP (loc, 0) != new_addr)
- loc = gen_rtx (MEM, GET_MODE (loc), new_addr);
+ loc = gen_rtx_MEM (GET_MODE (loc), new_addr);
}
add_AT_flag (decl_die, DW_AT_artificial, 1);
}
}
+/* Remember a type in the incomplete_types_list. */
+
+static void
+add_incomplete_type (type)
+ tree type;
+{
+ if (incomplete_types == incomplete_types_allocated)
+ {
+ incomplete_types_allocated += INCOMPLETE_TYPES_INCREMENT;
+ incomplete_types_list
+ = (tree *) xrealloc (incomplete_types_list,
+ sizeof (tree) * incomplete_types_allocated);
+ }
+
+ incomplete_types_list[incomplete_types++] = type;
+}
+
+/* Walk through the list of incomplete types again, trying once more to
+ emit full debugging info for them. */
+
+static void
+retry_incomplete_types ()
+{
+ register tree type;
+
+ while (incomplete_types)
+ {
+ --incomplete_types;
+ type = incomplete_types_list[incomplete_types];
+ gen_type_die (type, comp_unit_die);
+ }
+}
+
/* Generate a DIE to represent an inlined instance of an enumeration type. */
static void
static void
gen_unspecified_parameters_die (decl_or_type, context_die)
- register tree decl_or_type;
+ register tree decl_or_type ATTRIBUTE_UNUSED;
register dw_die_ref context_die;
{
new_die (DW_TAG_unspecified_parameters, context_die);
we should detect this case and ignore it. For now, if we have
already reported an error, any error at all, then assume that
we got here because of a input error, not a dwarf2 bug. */
- extern int errorcount;
if (errorcount)
return;
abort ();
|| context_die == NULL)
&& get_AT_unsigned (old_die, DW_AT_decl_file) == file_index
&& (get_AT_unsigned (old_die, DW_AT_decl_line)
- == DECL_SOURCE_LINE (decl)))
+ == (unsigned)DECL_SOURCE_LINE (decl)))
{
subr_die = old_die;
if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index)
add_AT_unsigned (subr_die, DW_AT_decl_file, file_index);
if (get_AT_unsigned (old_die, DW_AT_decl_line)
- != DECL_SOURCE_LINE (decl))
+ != (unsigned)DECL_SOURCE_LINE (decl))
add_AT_unsigned
(subr_die, DW_AT_decl_line, DECL_SOURCE_LINE (decl));
}
add_AT_unsigned (var_die, DW_AT_decl_file, file_index);
if (get_AT_unsigned (old_die, DW_AT_decl_line)
- != DECL_SOURCE_LINE (decl))
+ != (unsigned)DECL_SOURCE_LINE (decl))
add_AT_unsigned (var_die, DW_AT_decl_line,
DECL_SOURCE_LINE (decl));
}
}
else
- add_AT_flag (type_die, DW_AT_declaration, 1);
+ {
+ add_AT_flag (type_die, DW_AT_declaration, 1);
+
+ /* We can't do this for function-local types, and we don't need to. */
+ if (TREE_PERMANENT (type))
+ add_incomplete_type (type);
+ }
}
/* Generate a DIE for a subroutine _type_. */
static unsigned
lookup_filename (file_name)
- char *file_name;
+ const char *file_name;
{
static unsigned last_file_lookup_index = 0;
register unsigned i;
void
dwarf2out_line (filename, line)
- register char *filename;
+ register const char *filename;
register unsigned line;
{
if (debug_info_level >= DINFO_LEVEL_NORMAL)
{
function_section (current_function_decl);
- if (DECL_SECTION_NAME (current_function_decl))
+ if (DWARF2_ASM_LINE_DEBUG_INFO)
+ {
+ static const char *lastfile;
+
+ /* Emit the .file and .loc directives understood by GNU as. */
+ if (lastfile == 0 || strcmp (filename, lastfile))
+ {
+ fprintf (asm_out_file, "\t.file 0 \"%s\"\n", filename);
+ lastfile = filename;
+ }
+
+ fprintf (asm_out_file, "\t.loc 0 %d 0\n", line);
+
+ /* Indicate that line number info exists. */
+ ++line_info_table_in_use;
+
+ /* Indicate that multiple line number tables exist. */
+ if (DECL_SECTION_NAME (current_function_decl))
+ ++separate_line_info_table_in_use;
+ }
+ else if (DECL_SECTION_NAME (current_function_decl))
{
register dw_separate_line_info_ref line_info;
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, SEPARATE_LINE_CODE_LABEL,
separate_line_info_table_in_use);
+ if (flag_debug_asm)
+ fprintf (asm_out_file, "\t%s line %d", ASM_COMMENT_START, line);
fputc ('\n', asm_out_file);
/* expand the line info table if necessary */
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
line_info_table_in_use);
+ if (flag_debug_asm)
+ fprintf (asm_out_file, "\t%s line %d", ASM_COMMENT_START, line);
fputc ('\n', asm_out_file);
/* Expand the line info table if necessary. */
void
dwarf2out_start_source_file (filename)
- register char *filename ATTRIBUTE_UNUSED;
+ register const char *filename ATTRIBUTE_UNUSED;
{
}
void
dwarf2out_define (lineno, buffer)
- register unsigned lineno;
- register char *buffer;
+ register unsigned lineno ATTRIBUTE_UNUSED;
+ register const char *buffer ATTRIBUTE_UNUSED;
{
static int initialized = 0;
if (!initialized)
void
dwarf2out_undef (lineno, buffer)
register unsigned lineno ATTRIBUTE_UNUSED;
- register char *buffer ATTRIBUTE_UNUSED;
+ register const char *buffer ATTRIBUTE_UNUSED;
{
}
primary_filename = main_input_filename;
/* Allocate the initial hunk of the file_table. */
- file_table = (char **) xmalloc (FILE_TABLE_INCREMENT * sizeof (char *));
- bzero ((char *) file_table, FILE_TABLE_INCREMENT * sizeof (char *));
+ file_table = (char **) xcalloc (FILE_TABLE_INCREMENT, sizeof (char *));
file_table_allocated = FILE_TABLE_INCREMENT;
/* Skip the first entry - file numbers begin at 1. */
/* Allocate the initial hunk of the decl_die_table. */
decl_die_table
- = (dw_die_ref *) xmalloc (DECL_DIE_TABLE_INCREMENT * sizeof (dw_die_ref));
- bzero ((char *) decl_die_table,
- DECL_DIE_TABLE_INCREMENT * sizeof (dw_die_ref));
+ = (dw_die_ref *) xcalloc (DECL_DIE_TABLE_INCREMENT, sizeof (dw_die_ref));
decl_die_table_allocated = DECL_DIE_TABLE_INCREMENT;
decl_die_table_in_use = 0;
/* Allocate the initial hunk of the decl_scope_table. */
decl_scope_table
- = (decl_scope_node *) xmalloc (DECL_SCOPE_TABLE_INCREMENT
- * sizeof (decl_scope_node));
- bzero ((char *) decl_scope_table,
- DECL_SCOPE_TABLE_INCREMENT * sizeof (decl_scope_node));
+ = (decl_scope_node *) xcalloc (DECL_SCOPE_TABLE_INCREMENT,
+ sizeof (decl_scope_node));
decl_scope_table_allocated = DECL_SCOPE_TABLE_INCREMENT;
decl_scope_depth = 0;
/* Allocate the initial hunk of the abbrev_die_table. */
abbrev_die_table
- = (dw_die_ref *) xmalloc (ABBREV_DIE_TABLE_INCREMENT
- * sizeof (dw_die_ref));
- bzero ((char *) abbrev_die_table,
- ABBREV_DIE_TABLE_INCREMENT * sizeof (dw_die_ref));
+ = (dw_die_ref *) xcalloc (ABBREV_DIE_TABLE_INCREMENT,
+ sizeof (dw_die_ref));
abbrev_die_table_allocated = ABBREV_DIE_TABLE_INCREMENT;
/* Zero-th entry is allocated, but unused */
abbrev_die_table_in_use = 1;
/* Allocate the initial hunk of the line_info_table. */
line_info_table
- = (dw_line_info_ref) xmalloc (LINE_INFO_TABLE_INCREMENT
- * sizeof (dw_line_info_entry));
- bzero ((char *) line_info_table,
- LINE_INFO_TABLE_INCREMENT * sizeof (dw_line_info_entry));
+ = (dw_line_info_ref) xcalloc (LINE_INFO_TABLE_INCREMENT,
+ sizeof (dw_line_info_entry));
line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
/* Zero-th entry is allocated, but unused */
line_info_table_in_use = 1;
ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label, ABBREV_SECTION_LABEL, 0);
- ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
+ if (DWARF2_GENERATE_TEXT_SECTION_LABEL)
+ ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
+ else
+ strcpy (text_section_label, stripattributes (TEXT_SECTION));
ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label,
DEBUG_INFO_SECTION_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
ASM_OUTPUT_SECTION (asm_out_file, ABBREV_SECTION);
ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
ASM_OUTPUT_SECTION (asm_out_file, TEXT_SECTION);
- ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
+ if (DWARF2_GENERATE_TEXT_SECTION_LABEL)
+ ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
ASM_OUTPUT_SECTION (asm_out_file, DEBUG_INFO_SECTION);
ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label);
ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
free (node);
}
+ /* Walk through the list of incomplete types again, trying once more to
+ emit full debugging info for them. */
+ retry_incomplete_types ();
+
/* Traverse the DIE tree and add sibling attributes to those DIE's
that have children. */
add_sibling_attributes (comp_unit_die);
/* Output the source line correspondence table. */
if (line_info_table_in_use > 1 || separate_line_info_table_in_use)
{
- fputc ('\n', asm_out_file);
- ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
- output_line_info ();
+ if (! DWARF2_ASM_LINE_DEBUG_INFO)
+ {
+ fputc ('\n', asm_out_file);
+ ASM_OUTPUT_SECTION (asm_out_file, DEBUG_LINE_SECTION);
+ output_line_info ();
+ }
/* We can only use the low/high_pc attributes if all of the code
was in .text. */