aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarfout.c
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1992-04-25 01:51:43 +0000
committerRichard Stallman <rms@gnu.org>1992-04-25 01:51:43 +0000
commit9a631e8e94fa51e132f7c6c6d6c2098cc68c5518 (patch)
treea934b7089f99f5698e0d2c77ab9e66938e5679e0 /gcc/dwarfout.c
parentc53a8ab63a01bb24b6139345144f93a8abd5b05b (diff)
downloadgcc-9a631e8e94fa51e132f7c6c6d6c2098cc68c5518.zip
gcc-9a631e8e94fa51e132f7c6c6d6c2098cc68c5518.tar.gz
gcc-9a631e8e94fa51e132f7c6c6d6c2098cc68c5518.tar.bz2
*** empty log message ***
From-SVN: r832
Diffstat (limited to 'gcc/dwarfout.c')
-rw-r--r--gcc/dwarfout.c803
1 files changed, 530 insertions, 273 deletions
diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c
index 5a4d6fa..ad6750c 100644
--- a/gcc/dwarfout.c
+++ b/gcc/dwarfout.c
@@ -31,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "insn-config.h"
#include "reload.h"
#include "output.h"
+#include "defaults.h"
/* #define NDEBUG 1 */
#include <assert.h>
@@ -55,8 +56,7 @@ extern time_t time ();
#define strrchr rindex
#endif
-char *getpwd ();
-
+extern char *getpwd ();
/* IMPORTANT NOTE: Please see the file README.DWARF for important details
regarding the GNU implementation of Dwarf. */
@@ -104,13 +104,6 @@ char *getpwd ();
#define TYPE_USED_FOR_FUNCTION(tagged_type) (TYPE_SIZE (tagged_type) == 0)
-#define BITFIELD_OFFSET_BITS(DECL) \
- ((unsigned) TREE_INT_CST_LOW (DECL_FIELD_BITPOS (DECL)))
-#define BITFIELD_OFFSET_UNITS(DECL) \
- (BITFIELD_OFFSET_BITS(DECL) / (unsigned) BITS_PER_UNIT)
-#define BITFIELD_OFFSET_WORDS_IN_UNITS(DECL) \
- ((BITFIELD_OFFSET_BITS(DECL) / (unsigned) BITS_PER_WORD) * UNITS_PER_WORD)
-
extern int flag_traditional;
extern char *version_string;
extern char *language_string;
@@ -318,12 +311,12 @@ static unsigned lookup_filename ();
#ifndef UNALIGNED_INT_ASM_OP
#define UNALIGNED_INT_ASM_OP ".4byte"
#endif
+#ifndef ASM_BYTE_OP
+#define ASM_BYTE_OP ".byte"
+#endif
#ifndef DEF_ASM_OP
#define DEF_ASM_OP ".set"
#endif
-#ifndef ASM_BYTE_OP
-#define ASM_BYTE_OP "\t.byte"
-#endif
/* Pseudo-ops for pushing the current section onto the section stack (and
simultaneously changing to a new section) and for poping back to the
@@ -334,10 +327,10 @@ static unsigned lookup_filename ();
OK because we only use at most one level of the section stack herein. */
#ifndef PUSHSECTION_ASM_OP
-#define PUSHSECTION_ASM_OP "\t.section"
+#define PUSHSECTION_ASM_OP ".section"
#endif
#ifndef POPSECTION_ASM_OP
-#define POPSECTION_ASM_OP "\t.previous"
+#define POPSECTION_ASM_OP ".previous"
#endif
/* The default format used by the ASM_OUTPUT_PUSH_SECTION macro (see below)
@@ -394,147 +387,157 @@ static unsigned lookup_filename ();
the -g options is used and DWARF_DEBUGGING_INFO is in effect.
If necessary, these may be overridden from within your tm.h file,
- but typically, you should never need to override these. */
+ but typically, you should never need to override these.
+
+ These labels have been hacked (temporarily) so that they all begin with
+ a `.L' sequence so as to appease the sparc/svr4 assmebler (which needs
+ to see .L at the start of a label in order to prevent that label from
+ going into the linker symbol table). When I get time, I'll have to
+ fix this the right way so that we use ASM_GENERATE_INTERNAL_LABEL and
+ ASM_OUTPUT_INTERNAL_LABEL throughout dwarfout.c, but that will require
+ a rather massive set of changes. For the moment, the following definitions
+ out to produce the right results for all svr4 and svr3 assemblers. -- rfg
+*/
#ifndef TEXT_BEGIN_LABEL
-#define TEXT_BEGIN_LABEL "._text_b"
+#define TEXT_BEGIN_LABEL ".L_text_b"
#endif
#ifndef TEXT_END_LABEL
-#define TEXT_END_LABEL "._text_e"
+#define TEXT_END_LABEL ".L_text_e"
#endif
#ifndef DATA_BEGIN_LABEL
-#define DATA_BEGIN_LABEL "._data_b"
+#define DATA_BEGIN_LABEL ".L_data_b"
#endif
#ifndef DATA_END_LABEL
-#define DATA_END_LABEL "._data_e"
+#define DATA_END_LABEL ".L_data_e"
#endif
#ifndef DATA1_BEGIN_LABEL
-#define DATA1_BEGIN_LABEL "._data1_b"
+#define DATA1_BEGIN_LABEL ".L_data1_b"
#endif
#ifndef DATA1_END_LABEL
-#define DATA1_END_LABEL "._data1_e"
+#define DATA1_END_LABEL ".L_data1_e"
#endif
#ifndef RODATA_BEGIN_LABEL
-#define RODATA_BEGIN_LABEL "._rodata_b"
+#define RODATA_BEGIN_LABEL ".L_rodata_b"
#endif
#ifndef RODATA_END_LABEL
-#define RODATA_END_LABEL "._rodata_e"
+#define RODATA_END_LABEL ".L_rodata_e"
#endif
#ifndef RODATA1_BEGIN_LABEL
-#define RODATA1_BEGIN_LABEL "._rodata1_b"
+#define RODATA1_BEGIN_LABEL ".L_rodata1_b"
#endif
#ifndef RODATA1_END_LABEL
-#define RODATA1_END_LABEL "._rodata1_e"
+#define RODATA1_END_LABEL ".L_rodata1_e"
#endif
#ifndef BSS_BEGIN_LABEL
-#define BSS_BEGIN_LABEL "._bss_b"
+#define BSS_BEGIN_LABEL ".L_bss_b"
#endif
#ifndef BSS_END_LABEL
-#define BSS_END_LABEL "._bss_e"
+#define BSS_END_LABEL ".L_bss_e"
#endif
#ifndef LINE_BEGIN_LABEL
-#define LINE_BEGIN_LABEL "._line_b"
+#define LINE_BEGIN_LABEL ".L_line_b"
#endif
#ifndef LINE_LAST_ENTRY_LABEL
-#define LINE_LAST_ENTRY_LABEL "._line_last"
+#define LINE_LAST_ENTRY_LABEL ".L_line_last"
#endif
#ifndef LINE_END_LABEL
-#define LINE_END_LABEL "._line_e"
+#define LINE_END_LABEL ".L_line_e"
#endif
#ifndef DEBUG_BEGIN_LABEL
-#define DEBUG_BEGIN_LABEL "._debug_b"
+#define DEBUG_BEGIN_LABEL ".L_debug_b"
#endif
#ifndef SFNAMES_BEGIN_LABEL
-#define SFNAMES_BEGIN_LABEL "._sfnames_b"
+#define SFNAMES_BEGIN_LABEL ".L_sfnames_b"
#endif
#ifndef SRCINFO_BEGIN_LABEL
-#define SRCINFO_BEGIN_LABEL "._srcinfo_b"
+#define SRCINFO_BEGIN_LABEL ".L_srcinfo_b"
#endif
#ifndef MACINFO_BEGIN_LABEL
-#define MACINFO_BEGIN_LABEL "._macinfo_b"
+#define MACINFO_BEGIN_LABEL ".L_macinfo_b"
#endif
#ifndef DIE_BEGIN_LABEL_FMT
-#define DIE_BEGIN_LABEL_FMT "._D%u"
+#define DIE_BEGIN_LABEL_FMT ".L_D%u"
#endif
#ifndef DIE_END_LABEL_FMT
-#define DIE_END_LABEL_FMT "._D%u_e"
+#define DIE_END_LABEL_FMT ".L_D%u_e"
#endif
#ifndef PUB_DIE_LABEL_FMT
-#define PUB_DIE_LABEL_FMT "._P%u"
+#define PUB_DIE_LABEL_FMT ".L_P%u"
#endif
#ifndef INSN_LABEL_FMT
-#define INSN_LABEL_FMT "._I%u_%u"
+#define INSN_LABEL_FMT ".L_I%u_%u"
#endif
#ifndef BLOCK_BEGIN_LABEL_FMT
-#define BLOCK_BEGIN_LABEL_FMT "._B%u"
+#define BLOCK_BEGIN_LABEL_FMT ".L_B%u"
#endif
#ifndef BLOCK_END_LABEL_FMT
-#define BLOCK_END_LABEL_FMT "._B%u_e"
+#define BLOCK_END_LABEL_FMT ".L_B%u_e"
#endif
#ifndef SS_BEGIN_LABEL_FMT
-#define SS_BEGIN_LABEL_FMT "._s%u"
+#define SS_BEGIN_LABEL_FMT ".L_s%u"
#endif
#ifndef SS_END_LABEL_FMT
-#define SS_END_LABEL_FMT "._s%u_e"
+#define SS_END_LABEL_FMT ".L_s%u_e"
#endif
#ifndef EE_BEGIN_LABEL_FMT
-#define EE_BEGIN_LABEL_FMT "._e%u"
+#define EE_BEGIN_LABEL_FMT ".L_e%u"
#endif
#ifndef EE_END_LABEL_FMT
-#define EE_END_LABEL_FMT "._e%u_e"
+#define EE_END_LABEL_FMT ".L_e%u_e"
#endif
#ifndef MT_BEGIN_LABEL_FMT
-#define MT_BEGIN_LABEL_FMT "._t%u"
+#define MT_BEGIN_LABEL_FMT ".L_t%u"
#endif
#ifndef MT_END_LABEL_FMT
-#define MT_END_LABEL_FMT "._t%u_e"
+#define MT_END_LABEL_FMT ".L_t%u_e"
#endif
#ifndef LOC_BEGIN_LABEL_FMT
-#define LOC_BEGIN_LABEL_FMT "._l%u"
+#define LOC_BEGIN_LABEL_FMT ".L_l%u"
#endif
#ifndef LOC_END_LABEL_FMT
-#define LOC_END_LABEL_FMT "._l%u_e"
+#define LOC_END_LABEL_FMT ".L_l%u_e"
#endif
#ifndef BOUND_BEGIN_LABEL_FMT
-#define BOUND_BEGIN_LABEL_FMT "._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 "._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 "._d%u"
+#define DERIV_BEGIN_LABEL_FMT ".L_d%u"
#endif
#ifndef DERIV_END_LABEL_FMT
-#define DERIV_END_LABEL_FMT "._d%u_e"
+#define DERIV_END_LABEL_FMT ".L_d%u_e"
#endif
#ifndef SL_BEGIN_LABEL_FMT
-#define SL_BEGIN_LABEL_FMT "._sl%u"
+#define SL_BEGIN_LABEL_FMT ".L_sl%u"
#endif
#ifndef SL_END_LABEL_FMT
-#define SL_END_LABEL_FMT "._sl%u_e"
+#define SL_END_LABEL_FMT ".L_sl%u_e"
#endif
#ifndef FUNC_END_LABEL_FMT
-#define FUNC_END_LABEL_FMT "._f%u_e"
+#define FUNC_END_LABEL_FMT ".L_f%u_e"
#endif
#ifndef TYPE_NAME_FMT
-#define TYPE_NAME_FMT "._T%u"
+#define TYPE_NAME_FMT ".L_T%u"
#endif
#ifndef LINE_CODE_LABEL_FMT
-#define LINE_CODE_LABEL_FMT "._LC%u"
+#define LINE_CODE_LABEL_FMT ".L_LC%u"
#endif
#ifndef SFNAMES_ENTRY_LABEL_FMT
-#define SFNAMES_ENTRY_LABEL_FMT "._F%u"
+#define SFNAMES_ENTRY_LABEL_FMT ".L_F%u"
#endif
#ifndef LINE_ENTRY_LABEL_FMT
-#define LINE_ENTRY_LABEL_FMT "._LE%u"
+#define LINE_ENTRY_LABEL_FMT ".L_LE%u"
#endif
/* Definitions of defaults for various types of primitive assembly language
@@ -553,7 +556,7 @@ static unsigned lookup_filename ();
#ifndef ASM_OUTPUT_POP_SECTION
#define ASM_OUTPUT_POP_SECTION(FILE) \
- fprintf ((FILE), "%s\n", POPSECTION_ASM_OP)
+ fprintf ((FILE), "\t%s\n", POPSECTION_ASM_OP)
#endif
#ifndef ASM_OUTPUT_SOURCE_FILENAME
@@ -593,38 +596,71 @@ static unsigned lookup_filename ();
#ifndef ASM_OUTPUT_DWARF_TAG
#define ASM_OUTPUT_DWARF_TAG(FILE,TAG) \
- fprintf ((FILE), "\t%s\t0x%x\t%s %s\n", UNALIGNED_SHORT_ASM_OP, \
- (unsigned) TAG, ASM_COMMENT_START, tag_name (TAG))
+ do { \
+ fprintf ((FILE), "\t%s\t0x%x", \
+ UNALIGNED_SHORT_ASM_OP, (unsigned) TAG); \
+ if (flag_verbose_asm) \
+ fprintf ((FILE), "\t%s %s", \
+ ASM_COMMENT_START, dwarf_tag_name (TAG)); \
+ fputc ('\n', (FILE)); \
+ } while (0)
#endif
#ifndef ASM_OUTPUT_DWARF_ATTRIBUTE
-#define ASM_OUTPUT_DWARF_ATTRIBUTE(FILE,ATTRIBUTE) \
- fprintf ((FILE), "\t%s\t0x%x\t%s %s\n", UNALIGNED_SHORT_ASM_OP, \
- (unsigned) ATTRIBUTE, ASM_COMMENT_START, attribute_name (ATTRIBUTE))
+#define ASM_OUTPUT_DWARF_ATTRIBUTE(FILE,ATTR) \
+ do { \
+ fprintf ((FILE), "\t%s\t0x%x", \
+ UNALIGNED_SHORT_ASM_OP, (unsigned) ATTR); \
+ if (flag_verbose_asm) \
+ fprintf ((FILE), "\t%s %s", \
+ ASM_COMMENT_START, dwarf_attr_name (ATTR)); \
+ fputc ('\n', (FILE)); \
+ } while (0)
#endif
#ifndef ASM_OUTPUT_DWARF_STACK_OP
#define ASM_OUTPUT_DWARF_STACK_OP(FILE,OP) \
- fprintf ((FILE), "%s\t0x%x\t%s %s\n", ASM_BYTE_OP, \
- (unsigned) OP, ASM_COMMENT_START, stack_op_name (OP))
+ do { \
+ fprintf ((FILE), "%s\t0x%x", ASM_BYTE_OP, (unsigned) OP); \
+ if (flag_verbose_asm) \
+ fprintf ((FILE), "\t%s %s", \
+ ASM_COMMENT_START, dwarf_stack_op_name (OP)); \
+ fputc ('\n', (FILE)); \
+ } while (0)
#endif
#ifndef ASM_OUTPUT_DWARF_FUND_TYPE
#define ASM_OUTPUT_DWARF_FUND_TYPE(FILE,FT) \
- fprintf ((FILE), "\t%s\t0x%x\t%s %s\n", UNALIGNED_SHORT_ASM_OP, \
- (unsigned) FT, ASM_COMMENT_START, fundamental_type_name (FT))
+ do { \
+ fprintf ((FILE), "\t%s\t0x%x", \
+ UNALIGNED_SHORT_ASM_OP, (unsigned) FT); \
+ if (flag_verbose_asm) \
+ fprintf ((FILE), "\t%s %s", \
+ ASM_COMMENT_START, dwarf_fund_type_name (FT)); \
+ fputc ('\n', (FILE)); \
+ } while (0)
#endif
#ifndef ASM_OUTPUT_DWARF_FMT_BYTE
#define ASM_OUTPUT_DWARF_FMT_BYTE(FILE,FMT) \
- fprintf ((FILE), "%s\t0x%x\t%s %s\n", ASM_BYTE_OP, \
- (unsigned) FMT, ASM_COMMENT_START, format_byte_name (FMT))
+ do { \
+ fprintf ((FILE), "%s\t0x%x", ASM_BYTE_OP, (unsigned) FMT); \
+ if (flag_verbose_asm) \
+ fprintf ((FILE), "\t%s %s", \
+ ASM_COMMENT_START, dwarf_fmt_byte_name (FMT)); \
+ fputc ('\n', (FILE)); \
+ } while (0)
#endif
#ifndef ASM_OUTPUT_DWARF_TYPE_MODIFIER
#define ASM_OUTPUT_DWARF_TYPE_MODIFIER(FILE,MOD) \
- fprintf ((FILE), "%s\t0x%x\t%s %s\n", ASM_BYTE_OP, \
- (unsigned) MOD, ASM_COMMENT_START, modifier_name (MOD))
+ do { \
+ fprintf ((FILE), "%s\t0x%x", ASM_BYTE_OP, (unsigned) MOD); \
+ if (flag_verbose_asm) \
+ fprintf ((FILE), "\t%s %s", \
+ ASM_COMMENT_START, dwarf_typemod_name (MOD)); \
+ fputc ('\n', (FILE)); \
+ } while (0)
#endif
#ifndef ASM_OUTPUT_DWARF_ADDR
@@ -681,49 +717,6 @@ static unsigned lookup_filename ();
} while (0)
#endif
-/* choose a reasonable default for ASM_OUTPUT_ASCII, as that is what
- varasm.c does. If the below is changed, please also change
- definition in varasm.c Both of these should be factored out, into a
- higher layer. */
-#ifndef ASM_OUTPUT_ASCII
-#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
- do { \
- FILE *_hide_asm_out_file = MYFILE; \
- char *_hide_p = MYSTRING; \
- int _hide_thissize = MYLENGTH; \
- { \
- FILE *asm_out_file = _hide_asm_out_file; \
- char *p = _hide_p; \
- int thissize = _hide_thissize; \
- int i; \
- fprintf (asm_out_file, "\t.ascii \""); \
- \
- for (i = 0; i < thissize; i++) \
- { \
- register int c = p[i]; \
- if (c == '\"' || c == '\\') \
- putc ('\\', asm_out_file); \
- if (c >= ' ' && c < 0177) \
- putc (c, asm_out_file); \
- else \
- { \
- fprintf (asm_out_file, "\\%o", c); \
- /* After an octal-escape, if a digit follows, \
- terminate one string constant and start another. \
- The Vax assembler fails to stop reading the escape \
- after three digits, so this is the only way we \
- can get it to parse the data properly. */ \
- if (i < thissize - 1 \
- && p[i + 1] >= '0' && p[i + 1] <= '9') \
- fprintf (asm_out_file, "\"\n\t.ascii \""); \
- } \
- } \
- fprintf (asm_out_file, "\"\n"); \
- } \
- } \
- while (0)
-#endif
-
#ifndef ASM_OUTPUT_DWARF_STRING
#define ASM_OUTPUT_DWARF_STRING(FILE,P) \
ASM_OUTPUT_ASCII ((FILE), P, strlen (P)+1)
@@ -742,87 +735,133 @@ xstrdup (s)
}
static char *
-tag_name (tag)
+dwarf_tag_name (tag)
register unsigned tag;
{
switch (tag)
{
- case TAG_padding: return "TAG_padding";
- case TAG_array_type: return "TAG_array_type";
- case TAG_class_type: return "TAG_class_type";
- case TAG_entry_point: return "TAG_entry_point";
- case TAG_enumeration_type: return "TAG_enumeration_type";
- case TAG_formal_parameter: return "TAG_formal_parameter";
- case TAG_global_subroutine: return "TAG_global_subroutine";
- case TAG_global_variable: return "TAG_global_variable";
- case TAG_imported_declaration: return "TAG_imported_declaration";
- case TAG_label: return "TAG_label";
- case TAG_lexical_block: return "TAG_lexical_block";
- case TAG_local_variable: return "TAG_local_variable";
- case TAG_member: return "TAG_member";
- case TAG_pointer_type: return "TAG_pointer_type";
- case TAG_reference_type: return "TAG_reference_type";
- case TAG_compile_unit: return "TAG_compile_unit";
- case TAG_string_type: return "TAG_string_type";
- case TAG_structure_type: return "TAG_structure_type";
- case TAG_subroutine: return "TAG_subroutine";
- case TAG_subroutine_type: return "TAG_subroutine_type";
- case TAG_typedef: return "TAG_typedef";
- case TAG_union_type: return "TAG_union_type";
+ case TAG_padding: return "TAG_padding";
+ case TAG_array_type: return "TAG_array_type";
+ case TAG_class_type: return "TAG_class_type";
+ case TAG_entry_point: return "TAG_entry_point";
+ case TAG_enumeration_type: return "TAG_enumeration_type";
+ case TAG_formal_parameter: return "TAG_formal_parameter";
+ case TAG_global_subroutine: return "TAG_global_subroutine";
+ case TAG_global_variable: return "TAG_global_variable";
+ case TAG_label: return "TAG_label";
+ case TAG_lexical_block: return "TAG_lexical_block";
+ case TAG_local_variable: return "TAG_local_variable";
+ case TAG_member: return "TAG_member";
+ case TAG_pointer_type: return "TAG_pointer_type";
+ case TAG_reference_type: return "TAG_reference_type";
+ case TAG_compile_unit: return "TAG_compile_unit";
+ case TAG_string_type: return "TAG_string_type";
+ case TAG_structure_type: return "TAG_structure_type";
+ case TAG_subroutine: return "TAG_subroutine";
+ case TAG_subroutine_type: return "TAG_subroutine_type";
+ case TAG_typedef: return "TAG_typedef";
+ case TAG_union_type: return "TAG_union_type";
case TAG_unspecified_parameters: return "TAG_unspecified_parameters";
- case TAG_variant: return "TAG_variant";
- case TAG_format: return "TAG_format";
- case TAG_with_stmt: return "TAG_with_stmt";
- case TAG_set_type: return "TAG_set_type";
- default: return "<unknown tag>";
+ case TAG_variant: return "TAG_variant";
+ case TAG_common_block: return "TAG_common_block";
+ case TAG_common_inclusion: return "TAG_common_inclusion";
+ case TAG_inheritance: return "TAG_inheritance";
+ case TAG_inlined_subroutine: return "TAG_inlined_subroutine";
+ case TAG_module: return "TAG_module";
+ case TAG_ptr_to_member_type: return "TAG_ptr_to_member_type";
+ case TAG_set_type: return "TAG_set_type";
+ case TAG_subrange_type: return "TAG_subrange_type";
+ case TAG_with_stmt: return "TAG_with_stmt";
+
+ /* GNU extensions. */
+
+ case TAG_format_label: return "TAG_format_label";
+ case TAG_namelist: return "TAG_namelist";
+ case TAG_function_template: return "TAG_function_template";
+ case TAG_class_template: return "TAG_class_template";
+
+ default: return "<unknown tag>";
}
}
static char *
-attribute_name (attr)
+dwarf_attr_name (attr)
register unsigned attr;
{
switch (attr)
{
- case AT_sibling: return "AT_sibling";
- case AT_location: return "AT_location";
- case AT_name: return "AT_name";
- case AT_fund_type: return "AT_fund_type";
- case AT_mod_fund_type: return "AT_mod_fund_type";
- case AT_user_def_type: return "AT_user_def_type";
- case AT_mod_u_d_type: return "AT_mod_u_d_type";
- case AT_ordering: return "AT_ordering";
- case AT_subscr_data: return "AT_subscr_data";
- case AT_byte_size: return "AT_byte_size";
- case AT_bit_offset: return "AT_bit_offset";
- case AT_bit_size: return "AT_bit_size";
- case AT_element_list: return "AT_element_list";
- case AT_stmt_list: return "AT_stmt_list";
- case AT_low_pc: return "AT_low_pc";
- case AT_high_pc: return "AT_high_pc";
- case AT_language: return "AT_language";
- case AT_member: return "AT_member";
- case AT_discr: return "AT_discr";
- case AT_discr_value: return "AT_discr_value";
- case AT_visibility: return "AT_visibility";
- case AT_import: return "AT_import";
- case AT_string_length: return "AT_string_length";
- case AT_comp_dir: return "AT_comp_dir";
- case AT_producer: return "AT_producer";
- case AT_frame_base: return "AT_frame_base";
- case AT_start_scope: return "AT_start_scope";
- case AT_stride_size: return "AT_stride_size";
- case AT_src_info: return "AT_src_info";
- case AT_prototyped: return "AT_prototyped";
+ case AT_sibling: return "AT_sibling";
+ case AT_location: return "AT_location";
+ case AT_name: return "AT_name";
+ case AT_fund_type: return "AT_fund_type";
+ case AT_mod_fund_type: return "AT_mod_fund_type";
+ case AT_user_def_type: return "AT_user_def_type";
+ case AT_mod_u_d_type: return "AT_mod_u_d_type";
+ case AT_ordering: return "AT_ordering";
+ case AT_subscr_data: return "AT_subscr_data";
+ case AT_byte_size: return "AT_byte_size";
+ case AT_bit_offset: return "AT_bit_offset";
+ case AT_bit_size: return "AT_bit_size";
+ case AT_element_list: return "AT_element_list";
+ case AT_stmt_list: return "AT_stmt_list";
+ case AT_low_pc: return "AT_low_pc";
+ case AT_high_pc: return "AT_high_pc";
+ case AT_language: return "AT_language";
+ case AT_member: return "AT_member";
+ case AT_discr: return "AT_discr";
+ case AT_discr_value: return "AT_discr_value";
+ case AT_string_length: return "AT_string_length";
+ case AT_common_reference: return "AT_common_reference";
+ case AT_comp_dir: return "AT_comp_dir";
+ case AT_const_value_string: return "AT_const_value_string";
+ case AT_const_value_data2: return "AT_const_value_data2";
+ case AT_const_value_data4: return "AT_const_value_data4";
+ case AT_const_value_data8: return "AT_const_value_data8";
+ case AT_const_value_block2: return "AT_const_value_block2";
case AT_const_value_block4: return "AT_const_value_block4";
- case AT_sf_names: return "AT_sf_names";
- case AT_mac_info: return "AT_mac_info";
- default: return "<unknown attribute>";
+ case AT_containing_type: return "AT_containing_type";
+ case AT_default_value_addr: return "AT_default_value_addr";
+ case AT_default_value_data2: return "AT_default_value_data2";
+ case AT_default_value_data4: return "AT_default_value_data4";
+ case AT_default_value_data8: return "AT_default_value_data8";
+ case AT_default_value_string: return "AT_default_value_string";
+ case AT_friends: return "AT_friends";
+ case AT_inline: return "AT_inline";
+ case AT_is_optional: return "AT_is_optional";
+ case AT_lower_bound_ref: return "AT_lower_bound_ref";
+ case AT_lower_bound_data2: return "AT_lower_bound_data2";
+ case AT_lower_bound_data4: return "AT_lower_bound_data4";
+ case AT_lower_bound_data8: return "AT_lower_bound_data8";
+ case AT_private: return "AT_private";
+ case AT_producer: return "AT_producer";
+ case AT_program: return "AT_program";
+ case AT_protected: return "AT_protected";
+ case AT_prototyped: return "AT_prototyped";
+ case AT_public: return "AT_public";
+ case AT_pure_virtual: return "AT_pure_virtual";
+ case AT_return_addr: return "AT_return_addr";
+ case AT_specification: return "AT_specification";
+ case AT_start_scope: return "AT_start_scope";
+ case AT_stride_size: return "AT_stride_size";
+ case AT_upper_bound_ref: return "AT_upper_bound_ref";
+ case AT_upper_bound_data2: return "AT_upper_bound_data2";
+ case AT_upper_bound_data4: return "AT_upper_bound_data4";
+ case AT_upper_bound_data8: return "AT_upper_bound_data8";
+ case AT_virtual: return "AT_virtual";
+
+ /* GNU extensions */
+
+ case AT_sf_names: return "AT_sf_names";
+ case AT_src_info: return "AT_src_info";
+ case AT_mac_info: return "AT_mac_info";
+ case AT_src_coords: return "AT_src_coords";
+
+ default: return "<unknown attribute>";
}
}
static char *
-stack_op_name (op)
+dwarf_stack_op_name (op)
register unsigned op;
{
switch (op)
@@ -839,7 +878,7 @@ stack_op_name (op)
}
static char *
-modifier_name (mod)
+dwarf_typemod_name (mod)
register unsigned mod;
{
switch (mod)
@@ -853,7 +892,7 @@ modifier_name (mod)
}
static char *
-format_byte_name (fmt)
+dwarf_fmt_byte_name (fmt)
register unsigned fmt;
{
switch (fmt)
@@ -871,7 +910,7 @@ format_byte_name (fmt)
}
}
static char *
-fundamental_type_name (ft)
+dwarf_fund_type_name (ft)
register unsigned ft;
{
switch (ft)
@@ -896,9 +935,33 @@ fundamental_type_name (ft)
case FT_dbl_prec_complex: return "FT_dbl_prec_complex";
case FT_void: return "FT_void";
case FT_boolean: return "FT_boolean";
+ case FT_ext_prec_complex: return "FT_ext_prec_complex";
+ case FT_label: return "FT_label";
+
+ /* GNU extensions. */
+
case FT_long_long: return "FT_long_long";
case FT_signed_long_long: return "FT_signed_long_long";
case FT_unsigned_long_long: return "FT_unsigned_long_long";
+
+ case FT_int8: return "FT_int8";
+ case FT_signed_int8: return "FT_signed_int8";
+ case FT_unsigned_int8: return "FT_unsigned_int8";
+ case FT_int16: return "FT_int16";
+ case FT_signed_int16: return "FT_signed_int16";
+ case FT_unsigned_int16: return "FT_unsigned_int16";
+ case FT_int32: return "FT_int32";
+ case FT_signed_int32: return "FT_signed_int32";
+ case FT_unsigned_int32: return "FT_unsigned_int32";
+ case FT_int64: return "FT_int64";
+ case FT_signed_int64: return "FT_signed_int64";
+ case FT_unsigned_int64: return "FT_signed_int64";
+
+ case FT_real32: return "FT_real32";
+ case FT_real64: return "FT_real64";
+ case FT_real96: return "FT_real96";
+ case FT_real128: return "FT_real128";
+
default: return "<unknown fundamental type>";
}
}
@@ -1452,7 +1515,24 @@ location_attribute (rtl)
}
/* Output the specialized form of location attribute used for data members
- of struct types. */
+ of struct types.
+
+ In the special case of a FIELD_DECL node which represents a bit-field,
+ the "offset" part of this special location descriptor must indicate the
+ distance in bytes from the lowest-addressed byte of the containing
+ struct or union type to the lowest-addressed byte of the "containing
+ object" for the bit-field.
+
+ For any given bit-field, the "containing object" is a hypothetical
+ object (of some integral or enum type) within which the given bit-field
+ lives. The type of this hypothetical "containing object" is always the
+ same as the declared type of the individual bit-field itself.
+
+ Note that it is the size (in bytes) of the hypothetical "containing
+ object" which will be given in the AT_byte_size attribute for this
+ bit-field. (See the `byte_size_attribute' function below.)
+*/
+
static void
data_member_location_attribute (decl)
@@ -1460,6 +1540,12 @@ data_member_location_attribute (decl)
{
char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
+ register unsigned containing_object_size_in_bytes;
+ register unsigned containing_object_size_in_bits;
+ register unsigned member_offset_in_objects;
+ register unsigned member_offset_in_bytes;
+ register tree type;
+ register tree bitpos = DECL_FIELD_BITPOS (decl);
if (TREE_CODE (decl) == ERROR_MARK)
return;
@@ -1467,6 +1553,19 @@ data_member_location_attribute (decl)
if (TREE_CODE (decl) != FIELD_DECL)
abort ();
+ /* The bit position given by DECL_FIELD_BITPOS could be non-constant
+ in the case where one or more variable sized members preceeded this
+ member in the containing struct type. We could probably correctly
+ handle this case someday, by it's too complicated to deal with at
+ the moment (and probably too rare to worry about), so just punt on
+ the whole AT_location attribute for now. Eventually, we'll have
+ to analyze the expression given as the DECL_FIELD_BITPOS and turn
+ it into a member-style AT_location descriptor, but that'll be
+ tough to do. -- rfg */
+
+ if (TREE_CODE (bitpos) != CONST_INT)
+ return;
+
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_location);
sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum);
sprintf (end_label, LOC_END_LABEL_FMT, current_dienum);
@@ -1474,19 +1573,52 @@ data_member_location_attribute (decl)
ASM_OUTPUT_LABEL (asm_out_file, begin_label);
ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST);
- /* This is pretty strange, but existing compilers producing DWARF
- apparently calculate the byte offset of a field differently
- depending upon whether or not it is a bit-field. If the given
- field is *not* a bit-field, then the offset is simply the
- the byte offset of the given field from the beginning of the
- struct. For bit-fields however, the offset is the offset (in
- bytes) of the beginning of the *containing word* from the
- beginning of the whole struct. */
+ type = DECL_BIT_FIELD_TYPE (decl);
+ if (type == NULL)
+ type = TREE_TYPE (decl);
- ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
- (DECL_BIT_FIELD_TYPE (decl))
- ? BITFIELD_OFFSET_WORDS_IN_UNITS (decl)
- : BITFIELD_OFFSET_UNITS (decl));
+ containing_object_size_in_bytes = int_size_in_bytes (type);
+ containing_object_size_in_bits
+ = containing_object_size_in_bytes * BITS_PER_UNIT;
+
+ /* WARNING! Note that the GCC front-end doesn't make any attempt to
+ keep track of the starting bit offset (relative to the start of
+ the containing structure type) of the hypothetical "containing
+ object" for a bit-field. (See the comments at the start of this
+ function.) Thus, when computing the byte offset value for a
+ bit-field, all we can do is to divide the starting bit offset of
+ the bit-field by the size of the hypothetical "containing object"
+ (which we can easily find).
+
+ This solution only works right as long as the alignment used by the
+ compiler for the declared type of the bit-field is the same as the
+ size of that type.
+
+ Since GCC allows type `long long' to be the declared type for a
+ bit-field, and since some target configurations only align
+ `long longs' to 4-byte boundaries, we have to check here to see
+ that the alignment of the containing object is the same as the
+ size of that object. If it isn't, and if the field in question
+ is a bit-field, then we may be about to generate bogus Dwarf
+ output, so we need to warn the user about that.
+
+ Of course it would be nice to actually solve this problem, but
+ that would require a lot of changes elsewhere in the compiler
+ which could be quite painful, so for now we'll just live with
+ this minor annoyance.
+ */
+
+ if ((GET_MODE_ALIGNMENT (mode_for_size (containing_object_size_in_bits))
+ != containing_object_size_in_bits)
+ && (DECL_BIT_FIELD_TYPE (type) != NULL))
+ warning_with_decl (decl, "debugging info won't necessarily be reliable");
+
+ member_offset_in_objects
+ = (unsigned) TREE_INT_CST_LOW (bitpos) / containing_object_size_in_bits;
+ member_offset_in_bytes
+ = member_offset_in_objects * containing_object_size_in_bytes;
+
+ ASM_OUTPUT_DWARF_DATA4 (asm_out_file, member_offset_in_bytes);
ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD);
ASM_OUTPUT_LABEL (asm_out_file, end_label);
}
@@ -1591,27 +1723,22 @@ location_or_const_value_attribute (decl)
if ((TREE_CODE (decl) != VAR_DECL) && (TREE_CODE (decl) != PARM_DECL))
abort ();
- /* It's not really clear what existing Dwarf debuggers need or expect
- as regards to location information for formal parameters. A later
- version of the Dwarf specification should resolve such issues, but
- for the time being, we assume here that debuggers want information
- about the location where the parameter was passed into the function.
- That seems to be what USL's CI5 compiler generates. Note that this
- will probably be different from the place where the parameter actual
- resides during function execution. Dwarf Version 2 will provide us
- with a means to describe that location also, but for now we can only
- describe the "passing" location. */
-
-#if 1 /* This is probably right, but it leads to a lot of trouble.
- Fixing one problem has been exposing another,
- all of which seemed to have no ill effects before.
- Let's try it again for now. */
+ /* Existing Dwarf debuggers need and expect the location descriptors for
+ formal parameters to reflect the place where the parameter are passed,
+ as opposed to the places where they might reside during the execution
+ of the function. This isn't clearly spelled out in the current Dwarf
+ version 1 specification, but it's obvious if you look at the output of
+ the CI5 compiler, or if you try to use the svr4 SDB debugger. Hopefully,
+ a later version of the Dwarf specification will clarify this. For now,
+ we just need to generate the right thing. Note that Dwarf version 2
+ will provide us with a means to describe *all* of the locations in which
+ a given variable or parameter resides (and the PC ranges over which it
+ occupies each one), but for now we can only describe the "passing"
+ location. */
+
rtl = (TREE_CODE (decl) == PARM_DECL)
? DECL_INCOMING_RTL (decl)
: DECL_RTL (decl);
-#else
- rtl = DECL_RTL (decl);
-#endif
if (rtl == NULL)
return;
@@ -1640,17 +1767,14 @@ location_or_const_value_attribute (decl)
}
/* Generate an AT_name attribute given some string value to be included as
- the value of the attribute. If the name is null, don't do anything. */
+ the value of the attribute. */
inline void
name_attribute (name_string)
register char *name_string;
{
- if (name_string && *name_string)
- {
- ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_name);
- ASM_OUTPUT_DWARF_STRING (asm_out_file, name_string);
- }
+ ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_name);
+ ASM_OUTPUT_DWARF_STRING (asm_out_file, name_string);
}
inline void
@@ -1846,36 +1970,127 @@ byte_size_attribute (tree_node)
break;
case FIELD_DECL:
- {
- register unsigned words;
- register unsigned bits;
-
- bits = TREE_INT_CST_LOW (DECL_SIZE (tree_node));
- words = (bits + (BITS_PER_WORD-1)) / BITS_PER_WORD;
- size = words * (BITS_PER_WORD / BITS_PER_UNIT);
- }
+ /* For a data member of a struct or union, the AT_byte_size is
+ always given as the number of bytes normally allocated for
+ an object of the *declared* type of the member itself. This
+ is true even for bit-fields. */
+ size = int_size_in_bytes (DECL_BIT_FIELD_TYPE (tree_node)
+ ? DECL_BIT_FIELD_TYPE (tree_node)
+ : TREE_TYPE (tree_node));
break;
default:
abort ();
}
+
+ /* Note that `size' might be -1 when we get to this point. If it
+ is, that indicates that the byte size of the entity in question
+ is variable. We have no good way of expressing this fact in Dwarf
+ at the present time, so just let the -1 pass on through. */
+
ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size);
}
-/* For a FIELD_DECL node which represents a bit field, output an attribute
- which specifies the distance in bits from the start of the *word*
- containing the given field to the first bit of the field. */
+/* For a FIELD_DECL node which represents a bit-field, output an attribute
+ which specifies the distance in bits from the highest order bit of the
+ "containing object" for the bit-field to the highest order bit of the
+ bit-field itself.
+
+ For any given bit-field, the "containing object" is a hypothetical
+ object (of some integral or enum type) within which the given bit-field
+ lives. The type of this hypothetical "containing object" is always the
+ same as the declared type of the individual bit-field itself.
+
+ Note that it is the size (in bytes) of the hypothetical "containing
+ object" which will be given in the AT_byte_size attribute for this
+ bit-field. (See `byte_size_attribute' above.)
+*/
inline void
bit_offset_attribute (decl)
register tree decl;
{
+ register tree type = DECL_BIT_FIELD_TYPE (decl);
+ register unsigned containing_object_size_in_bits;
+ register unsigned dwarf_bit_offset;
+ register tree bitpos_tree = DECL_FIELD_BITPOS (decl);
+ register unsigned bitpos;
+
assert (TREE_CODE (decl) == FIELD_DECL); /* Must be a field. */
- assert (DECL_BIT_FIELD_TYPE (decl)); /* Must be a bit field. */
+ assert (type); /* Must be a bit field. */
+
+ /* The bit position given by DECL_FIELD_BITPOS could be non-constant
+ in the case where one or more variable sized members preceeded this
+ member in the containing struct type. We could probably correctly
+ handle this case someday, by it's too complicated to deal with at
+ the moment, so just punt on the whole AT_bit_offset attribute for
+ now. Eventually, we'll have to analyze the (variable) expression
+ given as the DECL_FIELD_BITPOS and see if we can factor out just
+ the (constant) bit offset part of that expression. -- rfg */
+
+ if (TREE_CODE (bitpos_tree) != CONST_INT)
+ return;
+
+ containing_object_size_in_bits = int_size_in_bytes (type) * BITS_PER_UNIT;
+
+ /* WARNING! Note that the GCC front-end doesn't make any attempt to
+ keep track of the starting bit offset (relative to the start of
+ the containing structure type) of the hypothetical "containing
+ object" for a bit-field. (See the comments at the start of this
+ function.) Thus, when computing the AT_bit_offset value for a
+ bit-field, all we can do is to divide the starting bit offset of
+ the bit-field by the size of the hypothetical "containing object"
+ (which we can easily find) and then get the remainder.
+
+ This solution only works right as long as the alignment used by the
+ compiler for the declared type of the bit-field is the same as the
+ size of that type.
+
+ Since GCC allows type `long long' to be the declared type for a
+ bit-field, and since some target configurations only align
+ `long longs' to 4-byte boundaries, we really should check here
+ to see that the alignment of the containing object is the same
+ as the size of that object and issue a warning if it isn't but
+ since we will also be generating an AT_location attribute for
+ the bit-field, and sinec it will generat a warning for this
+ condition we do not need to do it again here. That would just
+ cause the user to see two redundant warnings for the same single
+ bit-field declaration.
+
+ Of course it would be nice to actually solve this problem, but
+ that would require a lot of changes elsewhere in the compiler
+ which could be quite painful, so for now we'll just live with
+ this minor annoyance.
+ */
+
+#if 0
+ if (GET_MODE_ALIGNMENT (mode_for_size (containing_object_size_in_bits))
+ != containing_object_size_in_bits)
+ warning_with_decl (decl, "debugging info won't necessarily be reliable");
+#endif
+
+ bitpos = (unsigned) TREE_INT_CST_LOW (bitpos_tree);
+
+#if (BYTES_BIG_ENDIAN == 1)
+ {
+ register unsigned high_order_bitpos = bitpos;
+
+ dwarf_bit_offset = high_order_bitpos % containing_object_size_in_bits;
+ }
+#else
+ {
+ register unsigned low_order_bitpos = bitpos;
+ register unsigned field_width
+ = (unsigned) TREE_INT_CST_LOW (DECL_SIZE (decl));
+ register unsigned high_order_bitpos = low_order_bitpos + field_width;
+
+ dwarf_bit_offset = containing_object_size_in_bits
+ - (high_order_bitpos % containing_object_size_in_bits);
+ }
+#endif
ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_bit_offset);
- ASM_OUTPUT_DWARF_DATA2 (asm_out_file,
- BITFIELD_OFFSET_BITS (decl) % (unsigned) BITS_PER_WORD);
+ ASM_OUTPUT_DWARF_DATA2 (asm_out_file, dwarf_bit_offset);
}
/* For a FIELD_DECL node which represents a bit field, output an attribute
@@ -2077,10 +2292,39 @@ containing_type_attribute (containing_type)
ASM_OUTPUT_DWARF_REF (asm_out_file, label);
}
+inline void
+src_coords_attribute (src_fileno, src_lineno)
+ register unsigned src_fileno;
+ register unsigned src_lineno;
+{
+#ifdef DWARF_DECL_COORDINATES
+ ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_src_coords);
+ ASM_OUTPUT_DWARF_DATA2 (asm_out_file, src_fileno);
+ ASM_OUTPUT_DWARF_DATA2 (asm_out_file, src_lineno);
+#endif
+}
+
/************************* end of attributes *****************************/
/********************* utility routines for DIEs *************************/
+/* Output an AT_name attribute and an AT_src_coords attribute for the
+ given decl, but only if it actually has a name. */
+
+inline void
+name_and_src_coords_attributes (decl)
+ register tree decl;
+{
+ register tree decl_name = DECL_NAME (decl);
+
+ if (decl_name && IDENTIFIER_POINTER (decl_name))
+ {
+ name_attribute (IDENTIFIER_POINTER (decl_name));
+ src_coords_attribute (lookup_filename (DECL_SOURCE_FILE (decl)),
+ DECL_SOURCE_LINE (decl));
+ }
+}
+
/* Many forms of DIEs contain a "type description" part. The following
routine writes out these "type descriptor" parts. */
@@ -2219,10 +2463,11 @@ output_array_type_die (arg)
/* I believe that we can default the array ordering. SDB will probably
do the right things even if AT_ordering is not present. It's not
even an issue until we start to get into multidimensional arrays
- anyway. If SDB is shown to do the wrong thing in those cases, then
- we'll have to put the AT_ordering attribute back in, but only for
- multidimensional array. (After all, we don't want to waste space
- in the .debug section now do we?) */
+ anyway. If SDB is ever caught doing the Wrong Thing for multi-
+ dimensional arrays, then we'll have to put the AT_ordering attribute
+ back in. (But if and when we find out that we need to put these in,
+ we will only do so for multidimensional arrays. After all, we don't
+ want to waste space in the .debug section now do we?) */
#if 0
ordering_attribute (ORD_row_major);
@@ -2257,8 +2502,7 @@ output_entry_point_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_entry_point);
sibling_attribute ();
dienum_push ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
member_attribute (DECL_CONTEXT (decl));
type_attribute (return_type, 0, 0);
}
@@ -2321,8 +2565,7 @@ output_formal_parameter_die (arg)
sibling_attribute ();
if (decl)
{
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
location_or_const_value_attribute (decl);
}
@@ -2344,8 +2587,7 @@ output_global_subroutine_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_subroutine);
sibling_attribute ();
dienum_push ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
inline_attribute (decl);
prototyped_attribute (type);
member_attribute (DECL_CONTEXT (decl));
@@ -2354,7 +2596,7 @@ output_global_subroutine_die (arg)
{
char func_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
- low_pc_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ low_pc_attribute (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
sprintf (func_end_label, FUNC_END_LABEL_FMT, current_funcdef_number);
high_pc_attribute (func_end_label);
}
@@ -2372,8 +2614,7 @@ output_global_variable_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_variable);
sibling_attribute ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
member_attribute (DECL_CONTEXT (decl));
type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
if (!TREE_EXTERNAL (decl))
@@ -2397,8 +2638,7 @@ output_inline_subroutine_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_inline_subroutine);
sibling_attribute ();
dienum_push ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
prototyped_attribute (type);
member_attribute (DECL_CONTEXT (decl));
type_attribute (return_type, 0, 0);
@@ -2427,7 +2667,7 @@ output_inline_subroutine_die (arg)
{
char func_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
- low_pc_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ low_pc_attribute (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
sprintf (func_end_label, FUNC_END_LABEL_FMT, current_funcdef_number);
high_pc_attribute (func_end_label);
}
@@ -2444,7 +2684,7 @@ output_label_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_label);
sibling_attribute ();
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
/* When optimization is enabled (with -O) the code in jump.c and in flow.c
may cause insns representing one of more of the user's own labels to
@@ -2516,8 +2756,7 @@ output_local_variable_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_local_variable);
sibling_attribute ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
member_attribute (DECL_CONTEXT (decl));
type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
location_or_const_value_attribute (decl);
@@ -2531,8 +2770,7 @@ output_member_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_member);
sibling_attribute ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
member_attribute (DECL_CONTEXT (decl));
type_attribute (member_declared_type (decl),
TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
@@ -2699,8 +2937,7 @@ output_local_subroutine_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_subroutine);
sibling_attribute ();
dienum_push ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
inline_attribute (decl);
prototyped_attribute (type);
member_attribute (DECL_CONTEXT (decl));
@@ -2711,7 +2948,7 @@ output_local_subroutine_die (arg)
if (TREE_ASM_WRITTEN (decl))
{
- low_pc_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ low_pc_attribute (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
sprintf (func_end_label, FUNC_END_LABEL_FMT, current_funcdef_number);
high_pc_attribute (func_end_label);
}
@@ -2742,8 +2979,7 @@ output_typedef_die (arg)
ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_typedef);
sibling_attribute ();
- if (DECL_NAME (decl))
- name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ name_and_src_coords_attributes (decl);
member_attribute (DECL_CONTEXT (decl));
type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
}
@@ -3236,22 +3472,43 @@ output_type (type, containing_scope)
if (TYPE_SIZE (type))
{
- register tree member;
-
- /* First output info about the data members and type members. */
+ {
+ register tree normal_member;
- for (member = TYPE_FIELDS (type);
- member;
- member = TREE_CHAIN (member))
- output_decl (member, type);
+ /* First output info about the data members and type members. */
- /* Now output info about the function members (if any). */
+ for (normal_member = TYPE_FIELDS (type);
+ normal_member;
+ normal_member = TREE_CHAIN (normal_member))
+ output_decl (normal_member, type);
+ }
- if (TYPE_METHODS (type))
- for (member = TREE_VEC_ELT (TYPE_METHODS (type), 0);
- member;
- member = TREE_CHAIN (member))
- output_decl (member, type);
+ {
+ register tree vec_base;
+
+ /* Now output info about the function members (if any). */
+
+ vec_base = TYPE_METHODS (type);
+ if (vec_base)
+ {
+ register tree first_func_member = TREE_VEC_ELT (vec_base, 0);
+ register tree func_member;
+
+ /* This isn't documented, but the first element of the
+ vector of member functions can be NULL in cases where
+ the class type in question didn't have either a
+ constructor or a destructor declared for it. We have
+ to make allowances for that here. */
+
+ if (first_func_member == NULL)
+ first_func_member = TREE_VEC_ELT (vec_base, 1);
+
+ for (func_member = first_func_member;
+ func_member;
+ func_member = TREE_CHAIN (func_member))
+ output_decl (func_member, type);
+ }
+ }
end_sibling_chain (); /* Terminate member chain. */
}
@@ -3794,7 +4051,7 @@ dwarfout_file_scope_decl (decl, set_finalizing)
fputc ('\n', asm_out_file);
ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION);
ASM_OUTPUT_DWARF_ADDR (asm_out_file,
- IDENTIFIER_POINTER (DECL_NAME (decl)));
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
(unsigned) int_size_in_bytes (TREE_TYPE (decl)));
ASM_OUTPUT_POP_SECTION (asm_out_file);