X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fdwarf2out.c;h=ac0258c98d39a8e5a36246de85fd36e44295d938;hb=3f9da5596a39ec1c557502bf3f559aaeaf48fc0d;hp=a4cb347b80c2220e98ed895b66a9920bc7946055;hpb=7765d0dbc2566112b60c627e41b02a13dd943b43;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index a4cb347b80c..ac0258c98d3 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -79,7 +79,6 @@ along with GCC; see the file COPYING3. If not see #include "dwarf2out.h" #include "dwarf2asm.h" #include "toplev.h" -#include "varray.h" #include "ggc.h" #include "md5.h" #include "tm_p.h" @@ -1040,7 +1039,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p) cfi = new_cfi (); - if (loc.reg == old_cfa.reg && !loc.indirect) + if (loc.reg == old_cfa.reg && !loc.indirect && !old_cfa.indirect) { /* Construct a "DW_CFA_def_cfa_offset " instruction, indicating the CFA register did not change but the offset did. The data @@ -1056,7 +1055,8 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p) #ifndef MIPS_DEBUGGING_INFO /* SGI dbx thinks this means no offset. */ else if (loc.offset == old_cfa.offset && old_cfa.reg != INVALID_REGNUM - && !loc.indirect) + && !loc.indirect + && !old_cfa.indirect) { /* Construct a "DW_CFA_def_cfa_register " instruction, indicating the CFA register has changed to but the @@ -3771,6 +3771,11 @@ output_call_frame_info (int for_eh) } dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation"); + if (dw_cie_version >= 4) + { + dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "CIE Address Size"); + dw2_asm_output_data (1, 0, "CIE Segment Size"); + } dw2_asm_output_data_uleb128 (1, "CIE Code Alignment Factor"); dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT, "CIE Data Alignment Factor"); @@ -5710,8 +5715,7 @@ static GTY(()) comdat_type_node *comdat_type_list; static GTY(()) limbo_die_node *limbo_die_list; /* A list of DIEs for which we may have to generate - DW_AT_MIPS_linkage_name once their DECL_ASSEMBLER_NAMEs are - set. */ + DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set. */ static GTY(()) limbo_die_node *deferred_asm_name; /* Filenames referenced by this compilation unit. */ @@ -5744,8 +5748,12 @@ struct GTY ((chain_next ("%h.next"))) var_loc_node { struct GTY (()) var_loc_list_def { struct var_loc_node * GTY (()) first; - /* Do not mark the last element of the chained list because - it is marked through the chain. */ + /* Pointer to the last but one or last element of the + chained list. If the list is empty, both first and + last are NULL, if the list contains just one node + or the last node certainly is not redundant, it points + to the last node, otherwise points to the last but one. + Do not mark it for GC because it is marked through the chain. */ struct var_loc_node * GTY ((skip ("%h"))) last; /* DECL_UID of the variable decl. */ @@ -5987,7 +5995,7 @@ static hashval_t decl_loc_table_hash (const void *); static int decl_loc_table_eq (const void *, const void *); static var_loc_list *lookup_decl_loc (const_tree); static void equate_decl_number_to_die (tree, dw_die_ref); -static struct var_loc_node *add_var_loc_to_decl (tree, rtx); +static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *); static void print_spaces (FILE *); static void print_die (dw_die_ref, FILE *); static void print_dwarf_line_table (FILE *); @@ -6273,6 +6281,12 @@ static void gen_remaining_tmpl_value_param_die_attribute (void); #define DEBUG_MACINFO_SECTION_LABEL "Ldebug_macinfo" #endif +/* Mangled name attribute to use. This used to be a vendor extension + until DWARF 4 standardized it. */ +#define AT_linkage_name \ + (dwarf_version >= 4 ? DW_AT_linkage_name : DW_AT_MIPS_linkage_name) + + /* Definitions of defaults for formats and names of various special (artificial) labels which may be generated within this file (when the -g options is used and DWARF2_DEBUGGING_INFO is in effect. @@ -7745,7 +7759,7 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die) /* Add a variable location node to the linked list for DECL. */ static struct var_loc_node * -add_var_loc_to_decl (tree decl, rtx loc_note) +add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) { unsigned int decl_id = DECL_UID (decl); var_loc_list *temp; @@ -7764,23 +7778,62 @@ add_var_loc_to_decl (tree decl, rtx loc_note) if (temp->last) { + struct var_loc_node *last = temp->last, *unused = NULL; + if (last->next) + { + last = last->next; + gcc_assert (last->next == NULL); + } + /* TEMP->LAST here is either pointer to the last but one or + last element in the chained list, LAST is pointer to the + last element. */ + /* If the last note doesn't cover any instructions, remove it. */ + if (label && strcmp (last->label, label) == 0) + { + if (temp->last != last) + { + temp->last->next = NULL; + unused = last; + last = temp->last; + gcc_assert (strcmp (last->label, label) != 0); + } + else + { + gcc_assert (temp->first == temp->last); + memset (temp->last, '\0', sizeof (*temp->last)); + return temp->last; + } + } /* If the current location is the same as the end of the list, and either both or neither of the locations is uninitialized, we have nothing to do. */ - if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note), + if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last->var_loc_note), NOTE_VAR_LOCATION_LOC (loc_note))) - || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note) + || ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note) != NOTE_VAR_LOCATION_STATUS (loc_note)) - && ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note) + && ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note) == VAR_INIT_STATUS_UNINITIALIZED) || (NOTE_VAR_LOCATION_STATUS (loc_note) == VAR_INIT_STATUS_UNINITIALIZED)))) { - /* Add LOC to the end of list and update LAST. */ - loc = GGC_CNEW (struct var_loc_node); - temp->last->next = loc; - temp->last = loc; + /* Add LOC to the end of list and update LAST. If the last + element of the list has been removed above, reuse its + memory for the new node, otherwise allocate a new one. */ + if (unused) + { + loc = unused; + memset (loc, '\0', sizeof (*loc)); + } + else + loc = GGC_CNEW (struct var_loc_node); + last->next = loc; + /* Ensure TEMP->LAST will point either to the new last but one + element of the chain, or to the last element in it. */ + if (last != temp->last) + temp->last = last; } + else if (unused) + ggc_free (unused); } else { @@ -8245,6 +8298,7 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_ref at, if ((at->dw_attr == DW_AT_type && (tag == DW_TAG_pointer_type || tag == DW_TAG_reference_type + || tag == DW_TAG_rvalue_reference_type || tag == DW_TAG_ptr_to_member_type)) || (at->dw_attr == DW_AT_friend && tag == DW_TAG_friend)) @@ -8959,6 +9013,7 @@ is_type_die (dw_die_ref die) case DW_TAG_enumeration_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_string_type: case DW_TAG_structure_type: case DW_TAG_subroutine_type: @@ -8996,6 +9051,7 @@ is_comdat_die (dw_die_ref c) if (c->die_tag == DW_TAG_pointer_type || c->die_tag == DW_TAG_reference_type + || c->die_tag == DW_TAG_rvalue_reference_type || c->die_tag == DW_TAG_const_type || c->die_tag == DW_TAG_volatile_type) { @@ -9244,6 +9300,7 @@ should_move_die_to_comdat (dw_die_ref die) case DW_TAG_interface_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_string_type: case DW_TAG_subroutine_type: case DW_TAG_ptr_to_member_type: @@ -9327,6 +9384,7 @@ clone_as_declaration (dw_die_ref die) case DW_AT_name: case DW_AT_type: case DW_AT_virtuality: + case DW_AT_linkage_name: case DW_AT_MIPS_linkage_name: add_dwarf_attr (clone, a); break; @@ -12192,7 +12250,11 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, } else if (code == REFERENCE_TYPE) { - mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type); + if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4) + mod_type_die = new_die (DW_TAG_rvalue_reference_type, comp_unit_die, + type); + else + mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type); add_AT_unsigned (mod_type_die, DW_AT_byte_size, simple_type_size_in_bits (type) / BITS_PER_UNIT); item_type = TREE_TYPE (type); @@ -15906,7 +15968,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, loc_list = lookup_decl_loc (decl); if (loc_list && loc_list->first - && loc_list->first == loc_list->last + && loc_list->first->next == NULL && NOTE_VAR_LOCATION (loc_list->first->var_loc_note) && NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note)) { @@ -16335,6 +16397,7 @@ lower_bound_default (void) return 1; case DW_LANG_UPC: case DW_LANG_D: + case DW_LANG_Python: return dwarf_version >= 4 ? 0 : -1; case DW_LANG_Ada95: case DW_LANG_Ada83: @@ -16745,8 +16808,7 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl) if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) && TREE_PUBLIC (decl) && !DECL_ABSTRACT (decl) - && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) - && !is_fortran ()) + && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))) { /* Defer until we have an assembler name set. */ if (!DECL_ASSEMBLER_NAME_SET_P (decl)) @@ -16760,7 +16822,7 @@ add_name_and_src_coords_attributes (dw_die_ref die, tree decl) deferred_asm_name = asm_name; } else if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)) - add_AT_string (die, DW_AT_MIPS_linkage_name, + add_AT_string (die, AT_linkage_name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); } } @@ -18633,8 +18695,12 @@ gen_pointer_type_die (tree type, dw_die_ref context_die) static void gen_reference_type_die (tree type, dw_die_ref context_die) { - dw_die_ref ref_die - = new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type); + dw_die_ref ref_die, scope_die = scope_die_for (type, context_die); + + if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4) + ref_die = new_die (DW_TAG_rvalue_reference_type, scope_die, type); + else + ref_die = new_die (DW_TAG_reference_type, scope_die, type); equate_type_number_to_die (type, ref_die); add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die); @@ -20360,22 +20426,33 @@ dwarf2out_var_location (rtx loc_note) if (next_real == NULL_RTX) return; + /* If there were any real insns between note we processed last time + and this note (or if it is the first note), clear + last_{,postcall_}label so that they are not reused this time. */ + if (last_var_location_insn == NULL_RTX + || last_var_location_insn != next_real + || last_in_cold_section_p != in_cold_section_p) + { + last_label = NULL; + last_postcall_label = NULL; + } + decl = NOTE_VAR_LOCATION_DECL (loc_note); - newloc = add_var_loc_to_decl (decl, loc_note); + newloc = add_var_loc_to_decl (decl, loc_note, + NOTE_DURING_CALL_P (loc_note) + ? last_postcall_label : last_label); if (newloc == NULL) return; /* If there were no real insns between note we processed last time - and this note, use the label we emitted last time. */ - if (last_var_location_insn == NULL_RTX - || last_var_location_insn != next_real - || last_in_cold_section_p != in_cold_section_p) + and this note, use the label we emitted last time. Otherwise + create a new label and emit it. */ + if (last_label == NULL) { ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num); loclabel_num++; last_label = ggc_strdup (loclabel); - last_postcall_label = NULL; } newloc->var_loc_note = loc_note; newloc->next = NULL; @@ -20906,6 +20983,7 @@ prune_unused_types_walk (dw_die_ref die) case DW_TAG_packed_type: case DW_TAG_pointer_type: case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: case DW_TAG_volatile_type: case DW_TAG_typedef: case DW_TAG_array_type: @@ -21125,7 +21203,7 @@ htab_ct_eq (const void *of1, const void *of2) DWARF_TYPE_SIGNATURE_SIZE)); } -/* Move a DW_AT_MIPS_linkage_name attribute just added to dw_die_ref +/* Move a DW_AT_{,MIPS_}linkage_name attribute just added to dw_die_ref to the location it would have been added, should we know its DECL_ASSEMBLER_NAME when we added other attributes. This will probably improve compactness of debug info, removing equivalent @@ -21138,7 +21216,7 @@ move_linkage_attr (dw_die_ref die) unsigned ix = VEC_length (dw_attr_node, die->die_attr); dw_attr_node linkage = *VEC_index (dw_attr_node, die->die_attr, ix - 1); - gcc_assert (linkage.dw_attr == DW_AT_MIPS_linkage_name); + gcc_assert (linkage.dw_attr == AT_linkage_name); while (--ix > 0) { @@ -21372,7 +21450,7 @@ dwarf2out_finish (const char *filename) tree decl = node->created_for; if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)) { - add_AT_string (node->die, DW_AT_MIPS_linkage_name, + add_AT_string (node->die, AT_linkage_name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); move_linkage_attr (node->die); }