From: jakub Date: Wed, 21 Apr 2010 07:05:00 +0000 (+0000) Subject: * dwarf2out.c (add_var_loc_to_decl): Add LABEL argument. Drop X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=822930eae5140a95906cedf6f409a6444e11a6f4 * dwarf2out.c (add_var_loc_to_decl): Add LABEL argument. Drop last chain entry if it starts with the still current label. (add_location_or_const_value_attribute): Check that loc_list->first->next is NULL instead of comparing ->first with ->last. (dwarf2out_var_location): Pass last_label resp. last_postcall_label to add_var_loc_to_decl. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158590 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94612c21fdd..9a6a1b34ac4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2010-04-21 Jakub Jelinek + * dwarf2out.c (add_var_loc_to_decl): Add LABEL argument. Drop + last chain entry if it starts with the still current label. + (add_location_or_const_value_attribute): Check that + loc_list->first->next is NULL instead of comparing ->first with + ->last. + (dwarf2out_var_location): Pass last_label resp. last_postcall_label + to add_var_loc_to_decl. + * dwarf2out.c (output_call_frame_info): For dw_cie_version >= 4 add also address size and segment size fields into CIE header. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index ed5257d9ae2..8d569384f30 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -79,6 +79,7 @@ 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" @@ -91,7 +92,6 @@ along with GCC; see the file COPYING3. If not see #include "input.h" #include "gimple.h" #include "tree-pass.h" -#include "tree-flow.h" #ifdef DWARF2_DEBUGGING_INFO static void dwarf2out_source_line (unsigned int, const char *, int, bool); @@ -1040,7 +1040,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p) cfi = new_cfi (); - if (loc.reg == old_cfa.reg && !loc.indirect && !old_cfa.indirect) + if (loc.reg == old_cfa.reg && !loc.indirect) { /* Construct a "DW_CFA_def_cfa_offset " instruction, indicating the CFA register did not change but the offset did. The data @@ -1056,8 +1056,7 @@ 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 - && !old_cfa.indirect) + && !loc.indirect) { /* Construct a "DW_CFA_def_cfa_register " instruction, indicating the CFA register has changed to but the @@ -4785,10 +4784,6 @@ size_of_loc_descr (dw_loc_descr_ref loc) case DW_OP_piece: size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); break; - case DW_OP_bit_piece: - size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned); - size += size_of_uleb128 (loc->dw_loc_oprnd2.v.val_unsigned); - break; case DW_OP_deref_size: case DW_OP_xderef_size: size += 1; @@ -5013,10 +5008,6 @@ output_loc_operands (dw_loc_descr_ref loc) case DW_OP_piece: dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); break; - case DW_OP_bit_piece: - dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL); - dw2_asm_output_data_uleb128 (val2->v.val_unsigned, NULL); - break; case DW_OP_deref_size: case DW_OP_xderef_size: dw2_asm_output_data (1, val1->v.val_int, NULL); @@ -5132,12 +5123,6 @@ output_loc_operands_raw (dw_loc_descr_ref loc) dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned); break; - case DW_OP_bit_piece: - fputc (',', asm_out_file); - dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned); - dw2_asm_output_data_uleb128_raw (val2->v.val_unsigned); - break; - case DW_OP_consts: case DW_OP_breg0: case DW_OP_breg1: @@ -5754,15 +5739,7 @@ DEF_VEC_ALLOC_O(die_arg_entry,gc); /* Node of the variable location list. */ struct GTY ((chain_next ("%h.next"))) var_loc_node { - /* Either NOTE_INSN_VAR_LOCATION, or, for SRA optimized variables, - EXPR_LIST chain. For small bitsizes, bitsize is encoded - in mode of the EXPR_LIST node and first EXPR_LIST operand - is either NOTE_INSN_VAR_LOCATION for a piece with a known - location or NULL for padding. For larger bitsizes, - mode is 0 and first operand is a CONCAT with bitsize - as first CONCAT operand and NOTE_INSN_VAR_LOCATION resp. - NULL as second operand. */ - rtx GTY (()) loc; + rtx GTY (()) var_loc_note; const char * GTY (()) label; struct var_loc_node * GTY (()) next; }; @@ -6139,7 +6116,6 @@ static void add_AT_location_description (dw_die_ref, enum dwarf_attribute, static void add_data_member_location_attribute (dw_die_ref, tree); static bool add_const_value_attribute (dw_die_ref, rtx); static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *); -static void insert_double (double_int, unsigned char *); static void insert_float (const_rtx, unsigned char *); static rtx rtl_for_decl_location (tree); static bool add_location_or_const_value_attribute (dw_die_ref, tree, @@ -7780,175 +7756,16 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die) decl_die->decl_id = decl_id; } -/* Return how many bits covers PIECE EXPR_LIST. */ - -static int -decl_piece_bitsize (rtx piece) -{ - int ret = (int) GET_MODE (piece); - if (ret) - return ret; - gcc_assert (GET_CODE (XEXP (piece, 0)) == CONCAT - && CONST_INT_P (XEXP (XEXP (piece, 0), 0))); - return INTVAL (XEXP (XEXP (piece, 0), 0)); -} - -/* Return pointer to the location of location note in PIECE EXPR_LIST. */ - -static rtx * -decl_piece_varloc_ptr (rtx piece) -{ - if ((int) GET_MODE (piece)) - return &XEXP (piece, 0); - else - return &XEXP (XEXP (piece, 0), 1); -} - -/* Create an EXPR_LIST for location note LOC_NOTE covering BITSIZE bits. - Next is the chain of following piece nodes. */ - -static rtx -decl_piece_node (rtx loc_note, HOST_WIDE_INT bitsize, rtx next) -{ - if (bitsize <= (int) MAX_MACHINE_MODE) - return alloc_EXPR_LIST (bitsize, loc_note, next); - else - return alloc_EXPR_LIST (0, gen_rtx_CONCAT (VOIDmode, - GEN_INT (bitsize), - loc_note), next); -} - -/* Return rtx that should be stored into loc field for - LOC_NOTE and BITPOS/BITSIZE. */ - -static rtx -construct_piece_list (rtx loc_note, HOST_WIDE_INT bitpos, - HOST_WIDE_INT bitsize) -{ - if (bitsize != -1) - { - loc_note = decl_piece_node (loc_note, bitsize, NULL_RTX); - if (bitpos != 0) - loc_note = decl_piece_node (NULL_RTX, bitpos, loc_note); - } - return loc_note; -} - -/* This function either modifies location piece list *DEST in - place (if SRC and INNER is NULL), or copies location piece list - *SRC to *DEST while modifying it. Location BITPOS is modified - to contain LOC_NOTE, any pieces overlapping it are removed resp. - not copied and if needed some padding around it is added. - When modifying in place, DEST should point to EXPR_LIST where - earlier pieces cover PIECE_BITPOS bits, when copying SRC points - to the start of the whole list and INNER points to the EXPR_LIST - where earlier pieces cover PIECE_BITPOS bits. */ - -static void -adjust_piece_list (rtx *dest, rtx *src, rtx *inner, - HOST_WIDE_INT bitpos, HOST_WIDE_INT piece_bitpos, - HOST_WIDE_INT bitsize, rtx loc_note) -{ - int diff; - bool copy = inner != NULL; - - if (copy) - { - /* First copy all nodes preceeding the current bitpos. */ - while (src != inner) - { - *dest = decl_piece_node (*decl_piece_varloc_ptr (*src), - decl_piece_bitsize (*src), NULL_RTX); - dest = &XEXP (*dest, 1); - src = &XEXP (*src, 1); - } - } - /* Add padding if needed. */ - if (bitpos != piece_bitpos) - { - *dest = decl_piece_node (NULL_RTX, bitpos - piece_bitpos, - copy ? NULL_RTX : *dest); - dest = &XEXP (*dest, 1); - } - else if (*dest && decl_piece_bitsize (*dest) == bitsize) - { - gcc_assert (!copy); - /* A piece with correct bitpos and bitsize already exist, - just update the location for it and return. */ - *decl_piece_varloc_ptr (*dest) = loc_note; - return; - } - /* Add the piece that changed. */ - *dest = decl_piece_node (loc_note, bitsize, copy ? NULL_RTX : *dest); - dest = &XEXP (*dest, 1); - /* Skip over pieces that overlap it. */ - diff = bitpos - piece_bitpos + bitsize; - if (!copy) - src = dest; - while (diff > 0 && *src) - { - rtx piece = *src; - diff -= decl_piece_bitsize (piece); - if (copy) - src = &XEXP (piece, 1); - else - { - *src = XEXP (piece, 1); - free_EXPR_LIST_node (piece); - } - } - /* Add padding if needed. */ - if (diff < 0 && *src) - { - if (!copy) - dest = src; - *dest = decl_piece_node (NULL_RTX, -diff, copy ? NULL_RTX : *dest); - dest = &XEXP (*dest, 1); - } - if (!copy) - return; - /* Finally copy all nodes following it. */ - while (*src) - { - *dest = decl_piece_node (*decl_piece_varloc_ptr (*src), - decl_piece_bitsize (*src), NULL_RTX); - dest = &XEXP (*dest, 1); - src = &XEXP (*src, 1); - } -} - /* 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, const char *label) { - unsigned int decl_id; + unsigned int decl_id = DECL_UID (decl); var_loc_list *temp; void **slot; struct var_loc_node *loc = NULL; - HOST_WIDE_INT bitsize = -1, bitpos = -1; - - if (DECL_DEBUG_EXPR_IS_FROM (decl)) - { - tree realdecl = DECL_DEBUG_EXPR (decl); - if (realdecl && handled_component_p (realdecl)) - { - HOST_WIDE_INT maxsize; - tree innerdecl; - innerdecl - = get_ref_base_and_extent (realdecl, &bitpos, &bitsize, &maxsize); - if (!DECL_P (innerdecl) - || DECL_IGNORED_P (innerdecl) - || TREE_STATIC (innerdecl) - || bitsize <= 0 - || bitpos + bitsize > 256 - || bitsize != maxsize) - return NULL; - decl = innerdecl; - } - } - decl_id = DECL_UID (decl); slot = htab_find_slot_with_hash (decl_loc_table, decl, decl_id, INSERT); if (*slot == NULL) { @@ -7962,40 +7779,17 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) if (temp->last) { struct var_loc_node *last = temp->last, *unused = NULL; - rtx *piece_loc = NULL, last_loc_note; - int piece_bitpos = 0; if (last->next) { last = last->next; gcc_assert (last->next == NULL); } - if (bitsize != -1 && GET_CODE (last->loc) == EXPR_LIST) - { - piece_loc = &last->loc; - do - { - int cur_bitsize = decl_piece_bitsize (*piece_loc); - if (piece_bitpos + cur_bitsize > bitpos) - break; - piece_bitpos += cur_bitsize; - piece_loc = &XEXP (*piece_loc, 1); - } - while (*piece_loc); - } /* 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) { - /* For SRA optimized variables if there weren't any real - insns since last note, just modify the last node. */ - if (piece_loc != NULL) - { - adjust_piece_list (piece_loc, NULL, NULL, - bitpos, piece_bitpos, bitsize, loc_note); - return NULL; - } - /* If the last note doesn't cover any instructions, remove it. */ if (temp->last != last) { temp->last->next = NULL; @@ -8007,28 +7801,17 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) { gcc_assert (temp->first == temp->last); memset (temp->last, '\0', sizeof (*temp->last)); - temp->last->loc = construct_piece_list (loc_note, bitpos, bitsize); return temp->last; } } - if (bitsize == -1 && NOTE_P (last->loc)) - last_loc_note = last->loc; - else if (piece_loc != NULL - && *piece_loc != NULL_RTX - && piece_bitpos == bitpos - && decl_piece_bitsize (*piece_loc) == bitsize) - last_loc_note = *decl_piece_varloc_ptr (*piece_loc); - else - last_loc_note = NULL_RTX; /* 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 (last_loc_note == NULL_RTX - || (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last_loc_note), - NOTE_VAR_LOCATION_LOC (loc_note))) - || ((NOTE_VAR_LOCATION_STATUS (last_loc_note) + if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last->var_loc_note), + NOTE_VAR_LOCATION_LOC (loc_note))) + || ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note) != NOTE_VAR_LOCATION_STATUS (loc_note)) - && ((NOTE_VAR_LOCATION_STATUS (last_loc_note) + && ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note) == VAR_INIT_STATUS_UNINITIALIZED) || (NOTE_VAR_LOCATION_STATUS (loc_note) == VAR_INIT_STATUS_UNINITIALIZED)))) @@ -8043,11 +7826,6 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) } else loc = GGC_CNEW (struct var_loc_node); - if (bitsize == -1 || piece_loc == NULL) - loc->loc = construct_piece_list (loc_note, bitpos, bitsize); - else - adjust_piece_list (&loc->loc, &last->loc, piece_loc, - bitpos, piece_bitpos, bitsize, loc_note); 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. */ @@ -8062,7 +7840,6 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) loc = GGC_CNEW (struct var_loc_node); temp->first = loc; temp->last = loc; - loc->loc = construct_piece_list (loc_note, bitpos, bitsize); } return loc; } @@ -12295,6 +12072,10 @@ base_type_die (tree type) base_type_result = new_die (DW_TAG_base_type, comp_unit_die, type); + /* This probably indicates a bug. */ + if (! TYPE_NAME (type)) + add_name_attribute (base_type_result, "__unknown__"); + add_AT_unsigned (base_type_result, DW_AT_byte_size, int_size_in_bytes (type)); add_AT_unsigned (base_type_result, DW_AT_encoding, encoding); @@ -12412,21 +12193,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, ((is_const_type ? TYPE_QUAL_CONST : 0) | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0))); - if (qualified_type == sizetype - && TYPE_NAME (qualified_type) - && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL) - { -#ifdef ENABLE_CHECKING - gcc_assert (TREE_CODE (TREE_TYPE (TYPE_NAME (qualified_type))) - == INTEGER_TYPE - && TYPE_PRECISION (TREE_TYPE (TYPE_NAME (qualified_type))) - == TYPE_PRECISION (qualified_type) - && TYPE_UNSIGNED (TREE_TYPE (TYPE_NAME (qualified_type))) - == TYPE_UNSIGNED (qualified_type)); -#endif - qualified_type = TREE_TYPE (TYPE_NAME (qualified_type)); - } - /* If we do, then we can just use its DIE, if it exists. */ if (qualified_type) { @@ -12543,9 +12309,6 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type, name = DECL_NAME (name); add_name_attribute (mod_type_die, IDENTIFIER_POINTER (name)); } - /* This probably indicates a bug. */ - else if (mod_type_die && mod_type_die->die_tag == DW_TAG_base_type) - add_name_attribute (mod_type_die, "__unknown__"); if (qualified_type) equate_type_number_to_die (qualified_type, mod_type_die); @@ -14124,8 +13887,10 @@ loc_descriptor (rtx rtl, enum machine_mode mode, else { loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double; - loc_result->dw_loc_oprnd2.v.val_double - = rtx_to_double_int (rtl); + loc_result->dw_loc_oprnd2.v.val_double.high + = CONST_DOUBLE_HIGH (rtl); + loc_result->dw_loc_oprnd2.v.val_double.low + = CONST_DOUBLE_LOW (rtl); } } break; @@ -14149,14 +13914,39 @@ loc_descriptor (rtx rtl, enum machine_mode mode, for (i = 0, p = array; i < length; i++, p += elt_size) { rtx elt = CONST_VECTOR_ELT (rtl, i); - double_int val = rtx_to_double_int (elt); + HOST_WIDE_INT lo, hi; + + switch (GET_CODE (elt)) + { + case CONST_INT: + lo = INTVAL (elt); + hi = -(lo < 0); + break; + + case CONST_DOUBLE: + lo = CONST_DOUBLE_LOW (elt); + hi = CONST_DOUBLE_HIGH (elt); + break; + + default: + gcc_unreachable (); + } if (elt_size <= sizeof (HOST_WIDE_INT)) - insert_int (double_int_to_shwi (val), elt_size, p); + insert_int (lo, elt_size, p); else { + unsigned char *p0 = p; + unsigned char *p1 = p + sizeof (HOST_WIDE_INT); + gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT)); - insert_double (val, p); + if (WORDS_BIG_ENDIAN) + { + p0 = p1; + p1 = p; + } + insert_int (lo, sizeof (HOST_WIDE_INT), p0); + insert_int (hi, sizeof (HOST_WIDE_INT), p1); } } break; @@ -14306,11 +14096,7 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address, } else { - if (GET_CODE (varloc) == VAR_LOCATION) - mode = DECL_MODE (PAT_VAR_LOCATION_DECL (varloc)); - else - mode = DECL_MODE (loc); - descr = loc_descriptor (varloc, mode, initialized); + descr = loc_descriptor (varloc, DECL_MODE (loc), initialized); have_address = 1; } @@ -14360,125 +14146,6 @@ dw_loc_list_1 (tree loc, rtx varloc, int want_address, return descr; } -/* Create a DW_OP_piece or DW_OP_bit_piece for bitsize, or return NULL - if it is not possible. */ - -static dw_loc_descr_ref -new_loc_descr_op_bit_piece (HOST_WIDE_INT bitsize) -{ - if ((bitsize % BITS_PER_UNIT) == 0) - return new_loc_descr (DW_OP_piece, bitsize / BITS_PER_UNIT, 0); - else if (dwarf_version >= 3 || !dwarf_strict) - return new_loc_descr (DW_OP_bit_piece, bitsize, 0); - else - return NULL; -} - -/* Helper function for dw_loc_list. Compute proper Dwarf location descriptor - for VAR_LOC_NOTE for variable DECL that has been optimized by SRA. */ - -static dw_loc_descr_ref -dw_sra_loc_expr (tree decl, rtx loc) -{ - rtx p; - unsigned int padsize = 0; - dw_loc_descr_ref descr, *descr_tail; - unsigned HOST_WIDE_INT decl_size; - rtx varloc; - enum var_init_status initialized; - - if (DECL_SIZE (decl) == NULL - || !host_integerp (DECL_SIZE (decl), 1)) - return NULL; - - decl_size = tree_low_cst (DECL_SIZE (decl), 1); - descr = NULL; - descr_tail = &descr; - - for (p = loc; p; p = XEXP (p, 1)) - { - unsigned int bitsize = decl_piece_bitsize (p); - rtx loc_note = *decl_piece_varloc_ptr (p); - dw_loc_descr_ref cur_descr; - dw_loc_descr_ref *tail, last = NULL; - unsigned int opsize = 0; - - if (loc_note == NULL_RTX - || NOTE_VAR_LOCATION_LOC (loc_note) == NULL_RTX) - { - padsize += bitsize; - continue; - } - initialized = NOTE_VAR_LOCATION_STATUS (loc_note); - varloc = NOTE_VAR_LOCATION (loc_note); - cur_descr = dw_loc_list_1 (decl, varloc, 2, initialized); - if (cur_descr == NULL) - { - padsize += bitsize; - continue; - } - - /* Check that cur_descr either doesn't use - DW_OP_*piece operations, or their sum is equal - to bitsize. Otherwise we can't embed it. */ - for (tail = &cur_descr; *tail != NULL; - tail = &(*tail)->dw_loc_next) - if ((*tail)->dw_loc_opc == DW_OP_piece) - { - opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned - * BITS_PER_UNIT; - last = *tail; - } - else if ((*tail)->dw_loc_opc == DW_OP_bit_piece) - { - opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned; - last = *tail; - } - - if (last != NULL && opsize != bitsize) - { - padsize += bitsize; - continue; - } - - /* If there is a hole, add DW_OP_*piece after empty DWARF - expression, which means that those bits are optimized out. */ - if (padsize) - { - if (padsize > decl_size) - return NULL; - decl_size -= padsize; - *descr_tail = new_loc_descr_op_bit_piece (padsize); - if (*descr_tail == NULL) - return NULL; - descr_tail = &(*descr_tail)->dw_loc_next; - padsize = 0; - } - *descr_tail = cur_descr; - descr_tail = tail; - if (bitsize > decl_size) - return NULL; - decl_size -= bitsize; - if (last == NULL) - { - *descr_tail = new_loc_descr_op_bit_piece (bitsize); - if (*descr_tail == NULL) - return NULL; - descr_tail = &(*descr_tail)->dw_loc_next; - } - } - - /* If there were any non-empty expressions, add padding till the end of - the decl. */ - if (descr != NULL && decl_size != 0) - { - *descr_tail = new_loc_descr_op_bit_piece (decl_size); - if (*descr_tail == NULL) - return NULL; - } - return descr; -} - /* Return the dwarf representation of the location list LOC_LIST of DECL. WANT_ADDRESS has the same meaning as in loc_list_from_tree function. */ @@ -14508,48 +14175,45 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) secname = secname_for_decl (decl); - for (node = loc_list->first; node; node = node->next) - if (GET_CODE (node->loc) == EXPR_LIST - || NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX) + for (node = loc_list->first; node->next; node = node->next) + if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX) { - if (GET_CODE (node->loc) == EXPR_LIST) - { - /* This requires DW_OP_{,bit_}piece, which is not usable - inside DWARF expressions. */ - if (want_address != 2) - continue; - descr = dw_sra_loc_expr (decl, node->loc); - if (descr == NULL) - continue; - } - else - { - initialized = NOTE_VAR_LOCATION_STATUS (node->loc); - varloc = NOTE_VAR_LOCATION (node->loc); - descr = dw_loc_list_1 (decl, varloc, want_address, initialized); - } + /* The variable has a location between NODE->LABEL and + NODE->NEXT->LABEL. */ + initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note); + varloc = NOTE_VAR_LOCATION (node->var_loc_note); + descr = dw_loc_list_1 (decl, varloc, want_address, initialized); if (descr) { - /* The variable has a location between NODE->LABEL and - NODE->NEXT->LABEL. */ - if (node->next) - endname = node->next->label; - /* If the variable has a location at the last label - it keeps its location until the end of function. */ - else if (!current_function_decl) - endname = text_end_label; - else - { - ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL, - current_function_funcdef_no); - endname = ggc_strdup (label_id); - } - - *listp = new_loc_list (descr, node->label, endname, secname); + *listp = new_loc_list (descr, node->label, node->next->label, + secname); listp = &(*listp)->dw_loc_next; } } + /* If the variable has a location at the last label + it keeps its location until the end of function. */ + if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX) + { + initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note); + varloc = NOTE_VAR_LOCATION (node->var_loc_note); + descr = dw_loc_list_1 (decl, varloc, want_address, initialized); + if (descr) + { + if (!current_function_decl) + endname = text_end_label; + else + { + ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL, + current_function_funcdef_no); + endname = ggc_strdup (label_id); + } + + *listp = new_loc_list (descr, node->label, endname, secname); + listp = &(*listp)->dw_loc_next; + } + } + /* Try to avoid the overhead of a location list emitting a location expression instead, but only if we didn't have more than one location entry in the first place. If some entries were not @@ -15670,24 +15334,6 @@ extract_int (const unsigned char *src, unsigned int size) return val; } -/* Writes double_int values to dw_vec_const array. */ - -static void -insert_double (double_int val, unsigned char *dest) -{ - unsigned char *p0 = dest; - unsigned char *p1 = dest + sizeof (HOST_WIDE_INT); - - if (WORDS_BIG_ENDIAN) - { - p0 = p1; - p1 = dest; - } - - insert_int ((HOST_WIDE_INT) val.low, sizeof (HOST_WIDE_INT), p0); - insert_int ((HOST_WIDE_INT) val.high, sizeof (HOST_WIDE_INT), p1); -} - /* Writes floating point values to dw_vec_const array. */ static void @@ -15767,14 +15413,39 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) for (i = 0, p = array; i < length; i++, p += elt_size) { rtx elt = CONST_VECTOR_ELT (rtl, i); - double_int val = rtx_to_double_int (elt); + HOST_WIDE_INT lo, hi; + + switch (GET_CODE (elt)) + { + case CONST_INT: + lo = INTVAL (elt); + hi = -(lo < 0); + break; + + case CONST_DOUBLE: + lo = CONST_DOUBLE_LOW (elt); + hi = CONST_DOUBLE_HIGH (elt); + break; + + default: + gcc_unreachable (); + } if (elt_size <= sizeof (HOST_WIDE_INT)) - insert_int (double_int_to_shwi (val), elt_size, p); + insert_int (lo, elt_size, p); else { + unsigned char *p0 = p; + unsigned char *p1 = p + sizeof (HOST_WIDE_INT); + gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT)); - insert_double (val, p); + if (WORDS_BIG_ENDIAN) + { + p0 = p1; + p1 = p; + } + insert_int (lo, sizeof (HOST_WIDE_INT), p0); + insert_int (hi, sizeof (HOST_WIDE_INT), p1); } } break; @@ -16298,9 +15969,8 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl, if (loc_list && loc_list->first && loc_list->first->next == NULL - && NOTE_P (loc_list->first->loc) - && NOTE_VAR_LOCATION (loc_list->first->loc) - && NOTE_VAR_LOCATION_LOC (loc_list->first->loc)) + && NOTE_VAR_LOCATION (loc_list->first->var_loc_note) + && NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note)) { struct var_loc_node *node; @@ -17138,7 +16808,8 @@ 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))) + && !(TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl)) + && !is_fortran ()) { /* Defer until we have an assembler name set. */ if (!DECL_ASSEMBLER_NAME_SET_P (decl)) @@ -19110,20 +18781,6 @@ gen_compile_unit_die (const char *filename) } add_AT_unsigned (die, DW_AT_language, language); - - switch (language) - { - case DW_LANG_Fortran77: - case DW_LANG_Fortran90: - case DW_LANG_Fortran95: - /* Fortran has case insensitive identifiers and the front-end - lowercases everything. */ - add_AT_unsigned (die, DW_AT_identifier_case, DW_ID_down_case); - break; - default: - /* The default DW_ID_case_sensitive doesn't need to be specified. */ - break; - } return die; } @@ -19544,19 +19201,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, break; case LANG_TYPE: - /* Just use DW_TAG_unspecified_type. */ - { - dw_die_ref type_die = lookup_type_die (type); - if (type_die == NULL) - { - tree name = TYPE_NAME (type); - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - type_die = new_die (DW_TAG_unspecified_type, comp_unit_die, type); - add_name_attribute (type_die, IDENTIFIER_POINTER (name)); - equate_type_number_to_die (type, type_die); - } - } + /* No Dwarf representation currently defined. */ break; default: @@ -20178,7 +19823,10 @@ dwarf2out_imported_module_or_decl_1 (tree decl, if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL) { - at_import_die = force_type_die (TREE_TYPE (decl)); + if (is_base_type (TREE_TYPE (decl))) + at_import_die = base_type_die (TREE_TYPE (decl)); + else + at_import_die = force_type_die (TREE_TYPE (decl)); /* For namespace N { typedef void T; } using N::T; base_type_die returns NULL, but DW_TAG_imported_declaration requires the DW_AT_import tag. Force creation of DW_TAG_typedef. */ @@ -20807,6 +20455,8 @@ dwarf2out_var_location (rtx loc_note) loclabel_num++; last_label = ggc_strdup (loclabel); } + newloc->var_loc_note = loc_note; + newloc->next = NULL; if (!NOTE_DURING_CALL_P (loc_note)) newloc->label = last_label; @@ -21611,6 +21261,7 @@ resolve_one_addr (rtx *addr, void *data ATTRIBUTE_UNUSED) if (GET_CODE (rtl) == SYMBOL_REF && SYMBOL_REF_DECL (rtl) + && TREE_CODE (SYMBOL_REF_DECL (rtl)) == VAR_DECL && !TREE_ASM_WRITTEN (SYMBOL_REF_DECL (rtl))) return 1;