diff options
author | Richard Stallman <rms@gnu.org> | 1992-04-25 01:51:43 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1992-04-25 01:51:43 +0000 |
commit | 9a631e8e94fa51e132f7c6c6d6c2098cc68c5518 (patch) | |
tree | a934b7089f99f5698e0d2c77ab9e66938e5679e0 /gcc/dwarfout.c | |
parent | c53a8ab63a01bb24b6139345144f93a8abd5b05b (diff) | |
download | gcc-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.c | 803 |
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); |