#include "dwarf2out.h"
#include "dwarf2asm.h"
#include "toplev.h"
+#include "varray.h"
#include "ggc.h"
#include "md5.h"
#include "tm_p.h"
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 <offset>" instruction, indicating
the CFA register did not change but the offset did. The data
#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 <register>" instruction,
indicating the CFA register has changed to <register> but the
}
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");
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. */
struct GTY (()) var_loc_list_def {
struct var_loc_node * GTY (()) first;
- /* 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. */
+ /* Do not mark the last element of the chained list because
+ it is marked through the chain. */
struct var_loc_node * GTY ((skip ("%h"))) last;
/* DECL_UID of the variable decl. */
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, const char *);
+static struct var_loc_node *add_var_loc_to_decl (tree, rtx);
static void print_spaces (FILE *);
static void print_die (dw_die_ref, FILE *);
static void print_dwarf_line_table (FILE *);
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,
#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.
/* 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)
+add_var_loc_to_decl (tree decl, rtx loc_note)
{
unsigned int decl_id = DECL_UID (decl);
var_loc_list *temp;
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 (last->var_loc_note),
+ if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
NOTE_VAR_LOCATION_LOC (loc_note)))
- || ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
+ || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
!= NOTE_VAR_LOCATION_STATUS (loc_note))
- && ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
+ && ((NOTE_VAR_LOCATION_STATUS (temp->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. 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;
+ /* Add LOC to the end of list and update LAST. */
+ loc = GGC_CNEW (struct var_loc_node);
+ temp->last->next = loc;
+ temp->last = loc;
}
- else if (unused)
- ggc_free (unused);
}
else
{
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))
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:
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)
{
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:
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;
case ENUMERAL_TYPE:
case FUNCTION_TYPE:
case METHOD_TYPE:
- case NULLPTR_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE:
case OFFSET_TYPE:
}
else if (code == REFERENCE_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);
+ 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);
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;
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;
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
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;
loc_list = lookup_decl_loc (decl);
if (loc_list
&& loc_list->first
- && loc_list->first->next == NULL
+ && loc_list->first == loc_list->last
&& NOTE_VAR_LOCATION (loc_list->first->var_loc_note)
&& NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note))
{
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:
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))
deferred_asm_name = asm_name;
}
else if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
- add_AT_string (die, AT_linkage_name,
+ add_AT_string (die, DW_AT_MIPS_linkage_name,
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
}
}
scope_die_for (type, context_die), type);
equate_type_number_to_die (type, type_die);
add_name_attribute (type_die, type_tag (type));
- if ((dwarf_version >= 4 || !dwarf_strict)
- && ENUM_IS_SCOPED (type))
- add_AT_flag (type_die, DW_AT_enum_class, 1);
}
else if (! TYPE_SIZE (type))
return type_die;
static void
gen_reference_type_die (tree type, dw_die_ref context_die)
{
- 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);
+ dw_die_ref ref_die
+ = new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type);
equate_type_number_to_die (type, ref_die);
add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die);
}
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;
}
when appropriate. */
return;
- case NULLPTR_TYPE:
- {
- dw_die_ref type_die = lookup_type_die (type);
- if (type_die == NULL)
- {
- type_die = new_die (DW_TAG_unspecified_type, comp_unit_die, type);
- add_name_attribute (type_die, "decltype(nullptr)");
- equate_type_number_to_die (type, type_die);
- }
- }
- return;
-
case VOID_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
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,
- NOTE_DURING_CALL_P (loc_note)
- ? last_postcall_label : last_label);
+ newloc = add_var_loc_to_decl (decl, loc_note);
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. Otherwise
- create a new label and emit it. */
- if (last_label == NULL)
+ 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)
{
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;
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:
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
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 == AT_linkage_name);
+ gcc_assert (linkage.dw_attr == DW_AT_MIPS_linkage_name);
while (--ix > 0)
{
tree decl = node->created_for;
if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
{
- add_AT_string (node->die, AT_linkage_name,
+ add_AT_string (node->die, DW_AT_MIPS_linkage_name,
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
move_linkage_attr (node->die);
}