static bool add_const_value_attribute (dw_die_ref, rtx);
static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
static void insert_wide_int (const wide_int &, unsigned char *, int);
-static void insert_float (const_rtx, unsigned char *);
+static unsigned 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, bool);
static bool tree_add_const_value_attribute (dw_die_ref, tree);
scalar_float_mode float_mode = as_a <scalar_float_mode> (mode);
unsigned int length = GET_MODE_SIZE (float_mode);
unsigned char *array = ggc_vec_alloc<unsigned char> (length);
+ unsigned int elt_size = insert_float (rtl, array);
- insert_float (rtl, array);
mem_loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec;
- mem_loc_result->dw_loc_oprnd2.v.val_vec.length = length / 4;
- mem_loc_result->dw_loc_oprnd2.v.val_vec.elt_size = 4;
+ mem_loc_result->dw_loc_oprnd2.v.val_vec.length
+ = length / elt_size;
+ mem_loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size;
mem_loc_result->dw_loc_oprnd2.v.val_vec.array = array;
}
}
{
unsigned int length = GET_MODE_SIZE (smode);
unsigned char *array = ggc_vec_alloc<unsigned char> (length);
+ unsigned int elt_size = insert_float (rtl, array);
- insert_float (rtl, array);
loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec;
- loc_result->dw_loc_oprnd2.v.val_vec.length = length / 4;
- loc_result->dw_loc_oprnd2.v.val_vec.elt_size = 4;
+ loc_result->dw_loc_oprnd2.v.val_vec.length = length / elt_size;
+ loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size;
loc_result->dw_loc_oprnd2.v.val_vec.array = array;
}
}
case FIX_TRUNC_EXPR:
return 0;
+ case COMPOUND_LITERAL_EXPR:
+ return loc_list_from_tree_1 (COMPOUND_LITERAL_EXPR_DECL (loc),
+ 0, context);
+
default:
/* Leave front-end specific codes as simply unknown. This comes
up, for instance, with the C STMT_EXPR. */
/* Writes floating point values to dw_vec_const array. */
-static void
+static unsigned
insert_float (const_rtx rtl, unsigned char *array)
{
long val[4];
real_to_target (val, CONST_DOUBLE_REAL_VALUE (rtl), mode);
/* real_to_target puts 32-bit pieces in each long. Pack them. */
+ if (GET_MODE_SIZE (mode) < 4)
+ {
+ gcc_assert (GET_MODE_SIZE (mode) == 2);
+ insert_int (val[0], 2, array);
+ return 2;
+ }
+
for (i = 0; i < GET_MODE_SIZE (mode) / 4; i++)
{
insert_int (val[i], 4, array);
array += 4;
}
+ return 4;
}
/* Attach a DW_AT_const_value attribute for a variable or a parameter which
scalar_float_mode mode = as_a <scalar_float_mode> (GET_MODE (rtl));
unsigned int length = GET_MODE_SIZE (mode);
unsigned char *array = ggc_vec_alloc<unsigned char> (length);
+ unsigned int elt_size = insert_float (rtl, array);
- insert_float (rtl, array);
- add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
+ add_AT_vec (die, DW_AT_const_value, length / elt_size, elt_size,
+ array);
}
return true;
else
add_AT_int (die, attr, TREE_INT_CST_LOW (value));
}
- else
+ else if (dwarf_version >= 5
+ && TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (value))) == 128)
/* Otherwise represent the bound as an unsigned value with
the precision of its type. The precision and signedness
of the type will be necessary to re-interpret it
unambiguously. */
add_AT_wide (die, attr, wi::to_wide (value));
+ else
+ {
+ rtx v = immed_wide_int_const (wi::to_wide (value),
+ TYPE_MODE (TREE_TYPE (value)));
+ dw_loc_descr_ref loc
+ = loc_descriptor (v, TYPE_MODE (TREE_TYPE (value)),
+ VAR_INIT_STATUS_INITIALIZED);
+ if (loc)
+ add_AT_loc (die, attr, loc);
+ }
return;
}
tree origin = decl_ultimate_origin (decl);
dw_die_ref subr_die;
dw_die_ref old_die = lookup_decl_die (decl);
+ bool old_die_had_no_children = false;
/* This function gets called multiple times for different stages of
the debug process. For example, for func() in this code:
if (old_die && declaration)
return;
+ if (in_lto_p && old_die && old_die->die_child == NULL)
+ old_die_had_no_children = true;
+
/* Now that the C++ front end lazily declares artificial member fns, we
might need to retrofit the declaration into its class. */
if (!declaration && !origin && !old_die
else if (DECL_INITIAL (decl) == NULL_TREE)
gen_unspecified_parameters_die (decl, subr_die);
}
+ else if ((subr_die != old_die || old_die_had_no_children)
+ && prototype_p (TREE_TYPE (decl))
+ && stdarg_p (TREE_TYPE (decl)))
+ gen_unspecified_parameters_die (decl, subr_die);
}
if (subr_die != old_die)
&& DECL_RTL_SET_P (decl_or_origin))))
{
if (early_dwarf)
- add_pubname (decl_or_origin, var_die);
+ {
+ add_pubname (decl_or_origin, var_die);
+ /* For global register variables, emit DW_AT_location if possible
+ already during early_dwarf, as late_global_decl won't be usually
+ called. */
+ if (DECL_HARD_REGISTER (decl_or_origin)
+ && TREE_STATIC (decl_or_origin)
+ && !decl_by_reference_p (decl_or_origin)
+ && !get_AT (var_die, DW_AT_location)
+ && !get_AT (var_die, DW_AT_const_value)
+ && DECL_RTL_SET_P (decl_or_origin)
+ && REG_P (DECL_RTL (decl_or_origin)))
+ {
+ dw_loc_descr_ref descr
+ = reg_loc_descriptor (DECL_RTL (decl_or_origin),
+ VAR_INIT_STATUS_INITIALIZED);
+ if (descr)
+ add_AT_loc (var_die, DW_AT_location, descr);
+ }
+ }
else
add_location_or_const_value_attribute (var_die, decl_or_origin,
decl == NULL);