/* Output Dwarf format symbol table information from the GNU C compiler.
- Copyright (C) 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com) of Network Computing Devices.
This file is part of GNU CC.
static void output_signed_leb128 PROTO((long));
static inline int is_body_block PROTO((tree));
static int fundamental_type_code PROTO((tree));
+static tree root_type_1 PROTO((tree, int));
static tree root_type PROTO((tree));
+static void write_modifier_bytes_1 PROTO((tree, int, int, int));
static void write_modifier_bytes PROTO((tree, int, int));
static inline int type_is_fundamental PROTO((tree));
static void equate_decl_number_to_die_number PROTO((tree));
*/
#ifndef TEXT_BEGIN_LABEL
-#define TEXT_BEGIN_LABEL ".L_text_b"
+#define TEXT_BEGIN_LABEL "*.L_text_b"
#endif
#ifndef TEXT_END_LABEL
-#define TEXT_END_LABEL ".L_text_e"
+#define TEXT_END_LABEL "*.L_text_e"
#endif
#ifndef DATA_BEGIN_LABEL
-#define DATA_BEGIN_LABEL ".L_data_b"
+#define DATA_BEGIN_LABEL "*.L_data_b"
#endif
#ifndef DATA_END_LABEL
-#define DATA_END_LABEL ".L_data_e"
+#define DATA_END_LABEL "*.L_data_e"
#endif
#ifndef DATA1_BEGIN_LABEL
-#define DATA1_BEGIN_LABEL ".L_data1_b"
+#define DATA1_BEGIN_LABEL "*.L_data1_b"
#endif
#ifndef DATA1_END_LABEL
-#define DATA1_END_LABEL ".L_data1_e"
+#define DATA1_END_LABEL "*.L_data1_e"
#endif
#ifndef RODATA_BEGIN_LABEL
-#define RODATA_BEGIN_LABEL ".L_rodata_b"
+#define RODATA_BEGIN_LABEL "*.L_rodata_b"
#endif
#ifndef RODATA_END_LABEL
-#define RODATA_END_LABEL ".L_rodata_e"
+#define RODATA_END_LABEL "*.L_rodata_e"
#endif
#ifndef RODATA1_BEGIN_LABEL
-#define RODATA1_BEGIN_LABEL ".L_rodata1_b"
+#define RODATA1_BEGIN_LABEL "*.L_rodata1_b"
#endif
#ifndef RODATA1_END_LABEL
-#define RODATA1_END_LABEL ".L_rodata1_e"
+#define RODATA1_END_LABEL "*.L_rodata1_e"
#endif
#ifndef BSS_BEGIN_LABEL
-#define BSS_BEGIN_LABEL ".L_bss_b"
+#define BSS_BEGIN_LABEL "*.L_bss_b"
#endif
#ifndef BSS_END_LABEL
-#define BSS_END_LABEL ".L_bss_e"
+#define BSS_END_LABEL "*.L_bss_e"
#endif
#ifndef LINE_BEGIN_LABEL
-#define LINE_BEGIN_LABEL ".L_line_b"
+#define LINE_BEGIN_LABEL "*.L_line_b"
#endif
#ifndef LINE_LAST_ENTRY_LABEL
-#define LINE_LAST_ENTRY_LABEL ".L_line_last"
+#define LINE_LAST_ENTRY_LABEL "*.L_line_last"
#endif
#ifndef LINE_END_LABEL
-#define LINE_END_LABEL ".L_line_e"
+#define LINE_END_LABEL "*.L_line_e"
#endif
#ifndef DEBUG_BEGIN_LABEL
-#define DEBUG_BEGIN_LABEL ".L_debug_b"
+#define DEBUG_BEGIN_LABEL "*.L_debug_b"
#endif
#ifndef SFNAMES_BEGIN_LABEL
-#define SFNAMES_BEGIN_LABEL ".L_sfnames_b"
+#define SFNAMES_BEGIN_LABEL "*.L_sfnames_b"
#endif
#ifndef SRCINFO_BEGIN_LABEL
-#define SRCINFO_BEGIN_LABEL ".L_srcinfo_b"
+#define SRCINFO_BEGIN_LABEL "*.L_srcinfo_b"
#endif
#ifndef MACINFO_BEGIN_LABEL
-#define MACINFO_BEGIN_LABEL ".L_macinfo_b"
+#define MACINFO_BEGIN_LABEL "*.L_macinfo_b"
#endif
#ifndef DIE_BEGIN_LABEL_FMT
-#define DIE_BEGIN_LABEL_FMT ".L_D%u"
+#define DIE_BEGIN_LABEL_FMT "*.L_D%u"
#endif
#ifndef DIE_END_LABEL_FMT
-#define DIE_END_LABEL_FMT ".L_D%u_e"
+#define DIE_END_LABEL_FMT "*.L_D%u_e"
#endif
#ifndef PUB_DIE_LABEL_FMT
-#define PUB_DIE_LABEL_FMT ".L_P%u"
+#define PUB_DIE_LABEL_FMT "*.L_P%u"
#endif
#ifndef INSN_LABEL_FMT
-#define INSN_LABEL_FMT ".L_I%u_%u"
+#define INSN_LABEL_FMT "*.L_I%u_%u"
#endif
#ifndef BLOCK_BEGIN_LABEL_FMT
-#define BLOCK_BEGIN_LABEL_FMT ".L_B%u"
+#define BLOCK_BEGIN_LABEL_FMT "*.L_B%u"
#endif
#ifndef BLOCK_END_LABEL_FMT
-#define BLOCK_END_LABEL_FMT ".L_B%u_e"
+#define BLOCK_END_LABEL_FMT "*.L_B%u_e"
#endif
#ifndef SS_BEGIN_LABEL_FMT
-#define SS_BEGIN_LABEL_FMT ".L_s%u"
+#define SS_BEGIN_LABEL_FMT "*.L_s%u"
#endif
#ifndef SS_END_LABEL_FMT
-#define SS_END_LABEL_FMT ".L_s%u_e"
+#define SS_END_LABEL_FMT "*.L_s%u_e"
#endif
#ifndef EE_BEGIN_LABEL_FMT
-#define EE_BEGIN_LABEL_FMT ".L_e%u"
+#define EE_BEGIN_LABEL_FMT "*.L_e%u"
#endif
#ifndef EE_END_LABEL_FMT
-#define EE_END_LABEL_FMT ".L_e%u_e"
+#define EE_END_LABEL_FMT "*.L_e%u_e"
#endif
#ifndef MT_BEGIN_LABEL_FMT
-#define MT_BEGIN_LABEL_FMT ".L_t%u"
+#define MT_BEGIN_LABEL_FMT "*.L_t%u"
#endif
#ifndef MT_END_LABEL_FMT
-#define MT_END_LABEL_FMT ".L_t%u_e"
+#define MT_END_LABEL_FMT "*.L_t%u_e"
#endif
#ifndef LOC_BEGIN_LABEL_FMT
-#define LOC_BEGIN_LABEL_FMT ".L_l%u"
+#define LOC_BEGIN_LABEL_FMT "*.L_l%u"
#endif
#ifndef LOC_END_LABEL_FMT
-#define LOC_END_LABEL_FMT ".L_l%u_e"
+#define LOC_END_LABEL_FMT "*.L_l%u_e"
#endif
#ifndef BOUND_BEGIN_LABEL_FMT
-#define BOUND_BEGIN_LABEL_FMT ".L_b%u_%u_%c"
+#define BOUND_BEGIN_LABEL_FMT "*.L_b%u_%u_%c"
#endif
#ifndef BOUND_END_LABEL_FMT
-#define BOUND_END_LABEL_FMT ".L_b%u_%u_%c_e"
+#define BOUND_END_LABEL_FMT "*.L_b%u_%u_%c_e"
#endif
#ifndef DERIV_BEGIN_LABEL_FMT
-#define DERIV_BEGIN_LABEL_FMT ".L_d%u"
+#define DERIV_BEGIN_LABEL_FMT "*.L_d%u"
#endif
#ifndef DERIV_END_LABEL_FMT
-#define DERIV_END_LABEL_FMT ".L_d%u_e"
+#define DERIV_END_LABEL_FMT "*.L_d%u_e"
#endif
#ifndef SL_BEGIN_LABEL_FMT
-#define SL_BEGIN_LABEL_FMT ".L_sl%u"
+#define SL_BEGIN_LABEL_FMT "*.L_sl%u"
#endif
#ifndef SL_END_LABEL_FMT
-#define SL_END_LABEL_FMT ".L_sl%u_e"
+#define SL_END_LABEL_FMT "*.L_sl%u_e"
#endif
#ifndef BODY_BEGIN_LABEL_FMT
-#define BODY_BEGIN_LABEL_FMT ".L_b%u"
+#define BODY_BEGIN_LABEL_FMT "*.L_b%u"
#endif
#ifndef BODY_END_LABEL_FMT
-#define BODY_END_LABEL_FMT ".L_b%u_e"
+#define BODY_END_LABEL_FMT "*.L_b%u_e"
#endif
#ifndef FUNC_END_LABEL_FMT
-#define FUNC_END_LABEL_FMT ".L_f%u_e"
+#define FUNC_END_LABEL_FMT "*.L_f%u_e"
#endif
#ifndef TYPE_NAME_FMT
-#define TYPE_NAME_FMT ".L_T%u"
+#define TYPE_NAME_FMT "*.L_T%u"
#endif
#ifndef DECL_NAME_FMT
-#define DECL_NAME_FMT ".L_E%u"
+#define DECL_NAME_FMT "*.L_E%u"
#endif
#ifndef LINE_CODE_LABEL_FMT
-#define LINE_CODE_LABEL_FMT ".L_LC%u"
+#define LINE_CODE_LABEL_FMT "*.L_LC%u"
#endif
#ifndef SFNAMES_ENTRY_LABEL_FMT
-#define SFNAMES_ENTRY_LABEL_FMT ".L_F%u"
+#define SFNAMES_ENTRY_LABEL_FMT "*.L_F%u"
#endif
#ifndef LINE_ENTRY_LABEL_FMT
-#define LINE_ENTRY_LABEL_FMT ".L_LE%u"
+#define LINE_ENTRY_LABEL_FMT "*.L_LE%u"
#endif
\f
/* Definitions of defaults for various types of primitive assembly language
fprintf ((FILE), "\t%s\n", POPSECTION_ASM_OP)
#endif
-#ifndef ASM_OUTPUT_SOURCE_FILENAME
-#define ASM_OUTPUT_SOURCE_FILENAME(FILE,NAME) \
- do { fprintf (FILE, "\t%s\t", FILE_ASM_OP); \
- output_quoted_string (FILE, NAME); \
- fputc ('\n', FILE); \
- } while (0)
-#endif
-
#ifndef ASM_OUTPUT_DWARF_DELTA2
#define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2) \
do { fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
qualifiers. */
static tree
-root_type (type)
+root_type_1 (type, count)
register tree type;
+ register int count;
{
- if (TREE_CODE (type) == ERROR_MARK)
+ /* Give up after searching 1000 levels, in case this is a recursive
+ pointer type. Such types are possible in Ada, but it is not possible
+ to represent them in DWARF1 debug info. */
+ if (count > 1000)
return error_mark_node;
switch (TREE_CODE (type))
case POINTER_TYPE:
case REFERENCE_TYPE:
- return type_main_variant (root_type (TREE_TYPE (type)));
+ return root_type_1 (TREE_TYPE (type), count+1);
default:
- return type_main_variant (type);
+ return type;
}
}
+static tree
+root_type (type)
+ register tree type;
+{
+ type = root_type_1 (type, 0);
+ if (type != error_mark_node)
+ type = type_main_variant (type);
+ return type;
+}
+
/* Given a pointer to an arbitrary ..._TYPE tree node, write out a sequence
of zero or more Dwarf "type-modifier" bytes applicable to the type. */
static void
-write_modifier_bytes (type, decl_const, decl_volatile)
+write_modifier_bytes_1 (type, decl_const, decl_volatile, count)
register tree type;
register int decl_const;
register int decl_volatile;
+ register int count;
{
if (TREE_CODE (type) == ERROR_MARK)
return;
+ /* Give up after searching 1000 levels, in case this is a recursive
+ pointer type. Such types are possible in Ada, but it is not possible
+ to represent them in DWARF1 debug info. */
+ if (count > 1000)
+ return;
+
if (TYPE_READONLY (type) || decl_const)
ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_const);
if (TYPE_VOLATILE (type) || decl_volatile)
{
case POINTER_TYPE:
ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_pointer_to);
- write_modifier_bytes (TREE_TYPE (type), 0, 0);
+ write_modifier_bytes_1 (TREE_TYPE (type), 0, 0, count+1);
return;
case REFERENCE_TYPE:
ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_reference_to);
- write_modifier_bytes (TREE_TYPE (type), 0, 0);
+ write_modifier_bytes_1 (TREE_TYPE (type), 0, 0, count+1);
return;
case ERROR_MARK:
return;
}
}
+
+static void
+write_modifier_bytes (type, decl_const, decl_volatile)
+ register tree type;
+ register int decl_const;
+ register int decl_volatile;
+{
+ write_modifier_bytes_1 (type, decl_const, decl_volatile, 0);
+}
\f
/* Given a pointer to an arbitrary ..._TYPE tree node, return non-zero if the
given input type is a Dwarf "fundamental" type. Otherwise return zero. */
if (TREE_CODE (bound) == SAVE_EXPR)
output_loc_descriptor
- (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX));
+ (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX, 0));
}
ASM_OUTPUT_LABEL (asm_out_file, end_label);
/* Compute the offset of the containing object in bytes. */
object_offset_in_bytes = object_offset_in_align_units * type_align_in_bytes;
+ /* The above code assumes that the field does not cross an alignment
+ boundary. This can happen if PCC_BITFIELD_TYPE_MATTERS is not defined,
+ or if the structure is packed. If this happens, then we get an object
+ which starts after the bitfield, which means that the bit offset is
+ negative. Gdb fails when given negative bit offsets. We avoid this
+ by recomputing using the first bit of the bitfield. This will give
+ us an object which does not completely contain the bitfield, but it
+ will be aligned, and it will contain the first bit of the bitfield. */
+ if (object_offset_in_bits > bitpos_int)
+ {
+ deepest_bitpos = bitpos_int + 1;
+ object_offset_in_bits
+ = ceiling (deepest_bitpos, type_align_in_bits) - type_size_in_bits;
+ object_offset_in_align_units = (object_offset_in_bits
+ / type_align_in_bits);
+ object_offset_in_bytes = (object_offset_in_align_units
+ * type_align_in_bytes);
+ }
+
return object_offset_in_bytes;
}
if (! is_pseudo_reg (rtl)
&& (GET_CODE (rtl) != MEM || ! is_pseudo_reg (XEXP (rtl, 0))))
- output_loc_descriptor (eliminate_regs (rtl, 0, NULL_RTX));
+ output_loc_descriptor (rtl);
ASM_OUTPUT_LABEL (asm_out_file, end_label);
}
if (rtl == NULL_RTX)
return;
+ rtl = eliminate_regs (rtl, 0, NULL_RTX, 0);
+#ifdef LEAF_REG_REMAP
+ if (leaf_function)
+ leaf_renumber_regs_insn (rtl);
+#endif
+
switch (GET_CODE (rtl))
{
+ case ADDRESSOF:
+ /* The address of a variable that was optimized away; don't emit
+ anything. */
+ break;
+
case CONST_INT:
case CONST_DOUBLE:
case CONST_STRING:
location_attribute (rtl);
break;
+ case CONCAT:
+ /* ??? CONCAT is used for complex variables, which may have the real
+ part stored in one place and the imag part stored somewhere else.
+ DWARF1 has no way to describe a variable that lives in two different
+ places, so we just describe where the first part lives, and hope that
+ the second part is stored after it. */
+ location_attribute (XEXP (rtl, 0));
+ break;
+
default:
abort (); /* Should never happen. */
}
register enum tree_code code = TREE_CODE (type);
register int root_type_modified;
- if (TREE_CODE (type) == ERROR_MARK)
+ if (code == ERROR_MARK)
return;
/* Handle a special case. For functions whose return type is void,
we generate *no* type attribute. (Note that no object may have
type `void', so this only applies to function return types. */
- if (TREE_CODE (type) == VOID_TYPE)
+ if (code == VOID_TYPE)
return;
+ /* If this is a subtype, find the underlying type. Eventually,
+ this should write out the appropriate subtype info. */
+ while ((code == INTEGER_TYPE || code == REAL_TYPE)
+ && TREE_TYPE (type) != 0)
+ type = TREE_TYPE (type), code = TREE_CODE (type);
+
root_type_modified = (code == POINTER_TYPE || code == REFERENCE_TYPE
|| decl_const || decl_volatile
|| TYPE_READONLY (type) || TYPE_VOLATILE (type));
language_attribute (LANG_ADA83);
else if (strcmp (language_string, "GNU F77") == 0)
language_attribute (LANG_FORTRAN77);
+ else if (strcmp (language_string, "GNU Pascal") == 0)
+ language_attribute (LANG_PASCAL83);
else if (flag_traditional)
language_attribute (LANG_C);
else
case POINTER_TYPE:
case REFERENCE_TYPE:
+ /* Prevent infinite recursion in cases where this is a recursive
+ type. Recursive types are possible in Ada. */
+ TREE_ASM_WRITTEN (type) = 1;
/* For these types, all that is required is that we output a DIE
(or a set of DIEs) to represent the "basis" type. */
output_type (TREE_TYPE (type), containing_scope);
can safely generate correct Dwarf descriptions for these file-
scope tagged types. */
- if (TYPE_SIZE (type) == 0 && !finalizing)
+ if (TYPE_SIZE (type) == 0
+ && (TYPE_CONTEXT (type) == NULL
+ || TREE_CODE_CLASS (TREE_CODE (TYPE_CONTEXT (type))) == 't')
+ && !finalizing)
return; /* EARLY EXIT! Avoid setting TREE_ASM_WRITTEN. */
/* Prevent infinite recursion in cases where the type of some
a return type or a formal parameter type of some function. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
- if (DECL_NAME (decl) != NULL
+ if (! TYPE_DECL_IS_STUB (decl)
|| ! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl)))
return;
ASM_OUTPUT_LABEL (asm_out_file, label);
fputc ('\n', asm_out_file);
- ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION);
if (use_gnu_debug_info_extensions)
this_file_entry_num = lookup_filename (filename);
else
this_file_entry_num = (unsigned) -1;
+ ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION);
if (this_file_entry_num != prev_file_entry_num)
{
char line_entry_label[MAX_ARTIFICIAL_LABEL_BYTES];
sprintf (label, SFNAMES_ENTRY_LABEL_FMT, lookup_filename (filename));
sprintf (type_and_offset, "0x%08x+%s-%s",
- ((unsigned) MACINFO_start << 24), label, SFNAMES_BEGIN_LABEL);
+ ((unsigned) MACINFO_start << 24),
+ /* Hack: skip leading '*' . */
+ (*label == '*') + label,
+ (*SFNAMES_BEGIN_LABEL == '*') + SFNAMES_BEGIN_LABEL);
generate_macinfo_entry (type_and_offset, "");
}