Commit 5cea3ad6 by Jakub Jelinek Committed by Jakub Jelinek

dwarf2out.h (struct dw_loc_descr_node): Adjust comment for frame_offset_rel bit.

	* dwarf2out.h (struct dw_loc_descr_node): Adjust comment
	for frame_offset_rel bit.
	(struct array_descr_info): Add rank field.
	* dwarf2out.c (struct loc_descr_context): Add placeholder_arg
	and placeholder_seen fields.
	(resolve_args_picking_1): Handle also frame_offset_rel DW_OP_dup
	and DW_OP_over.  Optimize DW_OP_pick 0 into DW_OP_dup and
	DW_OP_pick 1 into DW_OP_over.
	(function_to_dwarf_procedure, type_byte_size, field_byte_offset,
	gen_variant_part): Clear placeholder_{arg,seen}.
	(loc_list_from_tree_1): Drop const from context argument.
	Handle integral PLACEHOLDER_EXPR if context->placeholder_arg.
	(loc_list_for_address_of_addr_expr_of_indirect_ref,
	loc_list_from_tree, loc_descriptor_from_tree): Drop const from
	context argument.
	(add_scalar_info): Drop const from context argument.  Handle
	context->placeholder_arg.
	(add_bound_info): Drop const from context argument.
	(gen_descr_array_type_die): Drop const from ctx variable.
	Initialize placeholder_arg and placeholder_seen.  Add DW_AT_rank
	attribute and use a single DW_TAG_generic_subrange instead of
	7 DW_TAG_subrange_type for assumed rank arrays.
fortran/
	* trans-types.c (gfc_get_array_descr_info): For -gdwarf-5 or
	-gno-strict-dwarf, handle assumed rank arrays the way dwarf2out
	expects.
ada/
	* gcc-interface/misc.c (gnat_get_array_descr_info): Clear rank
	field.

From-SVN: r241719
parent 2a3d56bf
2016-10-31 Jakub Jelinek <jakub@redhat.com> 2016-10-31 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.h (struct dw_loc_descr_node): Adjust comment
for frame_offset_rel bit.
(struct array_descr_info): Add rank field.
* dwarf2out.c (struct loc_descr_context): Add placeholder_arg
and placeholder_seen fields.
(resolve_args_picking_1): Handle also frame_offset_rel DW_OP_dup
and DW_OP_over. Optimize DW_OP_pick 0 into DW_OP_dup and
DW_OP_pick 1 into DW_OP_over.
(function_to_dwarf_procedure, type_byte_size, field_byte_offset,
gen_variant_part): Clear placeholder_{arg,seen}.
(loc_list_from_tree_1): Drop const from context argument.
Handle integral PLACEHOLDER_EXPR if context->placeholder_arg.
(loc_list_for_address_of_addr_expr_of_indirect_ref,
loc_list_from_tree, loc_descriptor_from_tree): Drop const from
context argument.
(add_scalar_info): Drop const from context argument. Handle
context->placeholder_arg.
(add_bound_info): Drop const from context argument.
(gen_descr_array_type_die): Drop const from ctx variable.
Initialize placeholder_arg and placeholder_seen. Add DW_AT_rank
attribute and use a single DW_TAG_generic_subrange instead of
7 DW_TAG_subrange_type for assumed rank arrays.
* dwarf2out.h (enum dw_val_class): Add dw_val_class_loclistsptr. * dwarf2out.h (enum dw_val_class): Add dw_val_class_loclistsptr.
* dwarf2out.c (struct dw_loc_list_struct): Change emitted field * dwarf2out.c (struct dw_loc_list_struct): Change emitted field
from bool to 1-bit uchar bitfield. Add num_assigned and from bool to 1-bit uchar bitfield. Add num_assigned and
2016-10-31 Jakub Jelinek <jakub@redhat.com>
* gcc-interface/misc.c (gnat_get_array_descr_info): Clear rank
field.
2016-10-24 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2016-10-24 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc-interface/Make-lang.in (lang_checks_parallelized): New target. * gcc-interface/Make-lang.in (lang_checks_parallelized): New target.
......
...@@ -898,6 +898,7 @@ gnat_get_array_descr_info (const_tree const_type, ...@@ -898,6 +898,7 @@ gnat_get_array_descr_info (const_tree const_type,
} }
info->ndimensions = i; info->ndimensions = i;
info->rank = NULL_TREE;
/* Too many dimensions? Give up generating proper description: yield instead /* Too many dimensions? Give up generating proper description: yield instead
nested arrays. Note that in this case, this hook is invoked once on each nested arrays. Note that in this case, this hook is invoked once on each
......
...@@ -3452,9 +3452,9 @@ struct loc_descr_context; ...@@ -3452,9 +3452,9 @@ struct loc_descr_context;
static void add_loc_descr_to_each (dw_loc_list_ref list, dw_loc_descr_ref ref); static void add_loc_descr_to_each (dw_loc_list_ref list, dw_loc_descr_ref ref);
static void add_loc_list (dw_loc_list_ref *ret, dw_loc_list_ref list); static void add_loc_list (dw_loc_list_ref *ret, dw_loc_list_ref list);
static dw_loc_list_ref loc_list_from_tree (tree, int, static dw_loc_list_ref loc_list_from_tree (tree, int,
const struct loc_descr_context *); struct loc_descr_context *);
static dw_loc_descr_ref loc_descriptor_from_tree (tree, int, static dw_loc_descr_ref loc_descriptor_from_tree (tree, int,
const struct loc_descr_context *); struct loc_descr_context *);
static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int); static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
static tree field_type (const_tree); static tree field_type (const_tree);
static unsigned int simple_type_align_in_bits (const_tree); static unsigned int simple_type_align_in_bits (const_tree);
...@@ -3479,9 +3479,9 @@ static void add_name_attribute (dw_die_ref, const char *); ...@@ -3479,9 +3479,9 @@ static void add_name_attribute (dw_die_ref, const char *);
static void add_gnat_descriptive_type_attribute (dw_die_ref, tree, dw_die_ref); static void add_gnat_descriptive_type_attribute (dw_die_ref, tree, dw_die_ref);
static void add_comp_dir_attribute (dw_die_ref); static void add_comp_dir_attribute (dw_die_ref);
static void add_scalar_info (dw_die_ref, enum dwarf_attribute, tree, int, static void add_scalar_info (dw_die_ref, enum dwarf_attribute, tree, int,
const struct loc_descr_context *); struct loc_descr_context *);
static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree, static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree,
const struct loc_descr_context *); struct loc_descr_context *);
static void add_subscript_info (dw_die_ref, tree, bool); static void add_subscript_info (dw_die_ref, tree, bool);
static void add_byte_size_attribute (dw_die_ref, tree); static void add_byte_size_attribute (dw_die_ref, tree);
static inline void add_bit_offset_attribute (dw_die_ref, tree, static inline void add_bit_offset_attribute (dw_die_ref, tree,
...@@ -15791,7 +15791,7 @@ cst_pool_loc_descr (tree loc) ...@@ -15791,7 +15791,7 @@ cst_pool_loc_descr (tree loc)
static dw_loc_list_ref static dw_loc_list_ref
loc_list_for_address_of_addr_expr_of_indirect_ref (tree loc, bool toplev, loc_list_for_address_of_addr_expr_of_indirect_ref (tree loc, bool toplev,
const loc_descr_context *context) loc_descr_context *context)
{ {
tree obj, offset; tree obj, offset;
HOST_WIDE_INT bitsize, bitpos, bytepos; HOST_WIDE_INT bitsize, bitpos, bytepos;
...@@ -15925,6 +15925,11 @@ struct loc_descr_context ...@@ -15925,6 +15925,11 @@ struct loc_descr_context
/* Information about the DWARF procedure we are currently generating. NULL if /* Information about the DWARF procedure we are currently generating. NULL if
we are not generating a DWARF procedure. */ we are not generating a DWARF procedure. */
struct dwarf_procedure_info *dpi; struct dwarf_procedure_info *dpi;
/* True if integral PLACEHOLDER_EXPR stands for the first argument passed
by consumer. Used for DW_TAG_generic_subrange attributes. */
bool placeholder_arg;
/* True if PLACEHOLDER_EXPR has been seen. */
bool placeholder_seen;
}; };
/* DWARF procedures generation /* DWARF procedures generation
...@@ -16034,8 +16039,23 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset, ...@@ -16034,8 +16039,23 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
/* If needed, relocate the picking offset with respect to the frame /* If needed, relocate the picking offset with respect to the frame
offset. */ offset. */
if (l->dw_loc_opc == DW_OP_pick && l->frame_offset_rel) if (l->frame_offset_rel)
{ {
unsigned HOST_WIDE_INT off;
switch (l->dw_loc_opc)
{
case DW_OP_pick:
off = l->dw_loc_oprnd1.v.val_unsigned;
break;
case DW_OP_dup:
off = 0;
break;
case DW_OP_over:
off = 1;
break;
default:
gcc_unreachable ();
}
/* frame_offset_ is the size of the current stack frame, including /* frame_offset_ is the size of the current stack frame, including
incoming arguments. Besides, the arguments are pushed incoming arguments. Besides, the arguments are pushed
right-to-left. Thus, in order to access the Nth argument from right-to-left. Thus, in order to access the Nth argument from
...@@ -16046,11 +16066,27 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset, ...@@ -16046,11 +16066,27 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
The targetted argument number (N) is already set as the operand, The targetted argument number (N) is already set as the operand,
and the number of temporaries can be computed with: and the number of temporaries can be computed with:
frame_offsets_ - dpi->args_count */ frame_offsets_ - dpi->args_count */
l->dw_loc_oprnd1.v.val_unsigned += frame_offset_ - dpi->args_count; off += frame_offset_ - dpi->args_count;
/* DW_OP_pick handles only offsets from 0 to 255 (inclusive)... */ /* DW_OP_pick handles only offsets from 0 to 255 (inclusive)... */
if (l->dw_loc_oprnd1.v.val_unsigned > 255) if (off > 255)
return false; return false;
if (off == 0)
{
l->dw_loc_opc = DW_OP_dup;
l->dw_loc_oprnd1.v.val_unsigned = 0;
}
else if (off == 1)
{
l->dw_loc_opc = DW_OP_over;
l->dw_loc_oprnd1.v.val_unsigned = 0;
}
else
{
l->dw_loc_opc = DW_OP_pick;
l->dw_loc_oprnd1.v.val_unsigned = off;
}
} }
/* Update frame_offset according to the effect the current operation has /* Update frame_offset according to the effect the current operation has
...@@ -16353,6 +16389,8 @@ function_to_dwarf_procedure (tree fndecl) ...@@ -16353,6 +16389,8 @@ function_to_dwarf_procedure (tree fndecl)
ctx.context_type = NULL_TREE; ctx.context_type = NULL_TREE;
ctx.base_decl = NULL_TREE; ctx.base_decl = NULL_TREE;
ctx.dpi = &dpi; ctx.dpi = &dpi;
ctx.placeholder_arg = false;
ctx.placeholder_seen = false;
dpi.fndecl = fndecl; dpi.fndecl = fndecl;
dpi.args_count = list_length (DECL_ARGUMENTS (fndecl)); dpi.args_count = list_length (DECL_ARGUMENTS (fndecl));
loc_body = loc_descriptor_from_tree (tree_body, 0, &ctx); loc_body = loc_descriptor_from_tree (tree_body, 0, &ctx);
...@@ -16415,7 +16453,7 @@ function_to_dwarf_procedure (tree fndecl) ...@@ -16415,7 +16453,7 @@ function_to_dwarf_procedure (tree fndecl)
static dw_loc_list_ref static dw_loc_list_ref
loc_list_from_tree_1 (tree loc, int want_address, loc_list_from_tree_1 (tree loc, int want_address,
const struct loc_descr_context *context) struct loc_descr_context *context)
{ {
dw_loc_descr_ref ret = NULL, ret1 = NULL; dw_loc_descr_ref ret = NULL, ret1 = NULL;
dw_loc_list_ref list_ret = NULL, list_ret1 = NULL; dw_loc_list_ref list_ret = NULL, list_ret1 = NULL;
...@@ -16461,6 +16499,18 @@ loc_list_from_tree_1 (tree loc, int want_address, ...@@ -16461,6 +16499,18 @@ loc_list_from_tree_1 (tree loc, int want_address,
else else
return NULL; return NULL;
} }
/* For DW_TAG_generic_subrange attributes, PLACEHOLDER_EXPR stands for
the single argument passed by consumer. */
else if (context != NULL
&& context->placeholder_arg
&& INTEGRAL_TYPE_P (TREE_TYPE (loc))
&& want_address == 0)
{
ret = new_loc_descr (DW_OP_pick, 0, 0);
ret->frame_offset_rel = 1;
context->placeholder_seen = true;
break;
}
else else
expansion_failed (loc, NULL_RTX, expansion_failed (loc, NULL_RTX,
"PLACEHOLDER_EXPR for an unexpected type"); "PLACEHOLDER_EXPR for an unexpected type");
...@@ -17214,7 +17264,7 @@ loc_list_from_tree_1 (tree loc, int want_address, ...@@ -17214,7 +17264,7 @@ loc_list_from_tree_1 (tree loc, int want_address,
static dw_loc_list_ref static dw_loc_list_ref
loc_list_from_tree (tree loc, int want_address, loc_list_from_tree (tree loc, int want_address,
const struct loc_descr_context *context) struct loc_descr_context *context)
{ {
dw_loc_list_ref result = loc_list_from_tree_1 (loc, want_address, context); dw_loc_list_ref result = loc_list_from_tree_1 (loc, want_address, context);
...@@ -17228,7 +17278,7 @@ loc_list_from_tree (tree loc, int want_address, ...@@ -17228,7 +17278,7 @@ loc_list_from_tree (tree loc, int want_address,
/* Same as above but return only single location expression. */ /* Same as above but return only single location expression. */
static dw_loc_descr_ref static dw_loc_descr_ref
loc_descriptor_from_tree (tree loc, int want_address, loc_descriptor_from_tree (tree loc, int want_address,
const struct loc_descr_context *context) struct loc_descr_context *context)
{ {
dw_loc_list_ref ret = loc_list_from_tree (loc, want_address, context); dw_loc_list_ref ret = loc_list_from_tree (loc, want_address, context);
if (!ret) if (!ret)
...@@ -17314,6 +17364,8 @@ type_byte_size (const_tree type, HOST_WIDE_INT *cst_size) ...@@ -17314,6 +17364,8 @@ type_byte_size (const_tree type, HOST_WIDE_INT *cst_size)
ctx.context_type = const_cast<tree> (type); ctx.context_type = const_cast<tree> (type);
ctx.base_decl = NULL_TREE; ctx.base_decl = NULL_TREE;
ctx.dpi = NULL; ctx.dpi = NULL;
ctx.placeholder_arg = false;
ctx.placeholder_seen = false;
type = TYPE_MAIN_VARIANT (type); type = TYPE_MAIN_VARIANT (type);
tree_size = TYPE_SIZE_UNIT (type); tree_size = TYPE_SIZE_UNIT (type);
...@@ -17493,7 +17545,9 @@ field_byte_offset (const_tree decl, struct vlr_context *ctx, ...@@ -17493,7 +17545,9 @@ field_byte_offset (const_tree decl, struct vlr_context *ctx,
struct loc_descr_context loc_ctx = { struct loc_descr_context loc_ctx = {
ctx->struct_type, /* context_type */ ctx->struct_type, /* context_type */
NULL_TREE, /* base_decl */ NULL_TREE, /* base_decl */
NULL /* dpi */ NULL, /* dpi */
false, /* placeholder_arg */
false /* placeholder_seen */
}; };
loc_result = loc_list_from_tree (tree_result, 0, &loc_ctx); loc_result = loc_list_from_tree (tree_result, 0, &loc_ctx);
...@@ -18886,12 +18940,12 @@ add_comp_dir_attribute (dw_die_ref die) ...@@ -18886,12 +18940,12 @@ add_comp_dir_attribute (dw_die_ref die)
static void static void
add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
int forms, const struct loc_descr_context *context) int forms, struct loc_descr_context *context)
{ {
dw_die_ref context_die, decl_die; dw_die_ref context_die, decl_die;
dw_loc_list_ref list; dw_loc_list_ref list;
bool strip_conversions = true; bool strip_conversions = true;
bool placeholder_seen = false;
while (strip_conversions) while (strip_conversions)
switch (TREE_CODE (value)) switch (TREE_CODE (value))
...@@ -18986,6 +19040,11 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, ...@@ -18986,6 +19040,11 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
return; return;
list = loc_list_from_tree (value, 2, context); list = loc_list_from_tree (value, 2, context);
if (context && context->placeholder_arg)
{
placeholder_seen = context->placeholder_seen;
context->placeholder_seen = false;
}
if (list == NULL || single_element_loc_list_p (list)) if (list == NULL || single_element_loc_list_p (list))
{ {
/* If this attribute is not a reference nor constant, it is /* If this attribute is not a reference nor constant, it is
...@@ -18994,6 +19053,14 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, ...@@ -18994,6 +19053,14 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
dw_loc_list_ref list2 = loc_list_from_tree (value, 0, context); dw_loc_list_ref list2 = loc_list_from_tree (value, 0, context);
if (list2 && single_element_loc_list_p (list2)) if (list2 && single_element_loc_list_p (list2))
{ {
if (placeholder_seen)
{
struct dwarf_procedure_info dpi;
dpi.fndecl = NULL_TREE;
dpi.args_count = 1;
if (!resolve_args_picking (list2->expr, 1, &dpi))
return;
}
add_AT_loc (die, attr, list2->expr); add_AT_loc (die, attr, list2->expr);
return; return;
} }
...@@ -19001,7 +19068,9 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value, ...@@ -19001,7 +19068,9 @@ add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
/* If that failed to give a single element location list, fall back to /* If that failed to give a single element location list, fall back to
outputting this as a reference... still if permitted. */ outputting this as a reference... still if permitted. */
if (list == NULL || (forms & dw_scalar_form_reference) == 0) if (list == NULL
|| (forms & dw_scalar_form_reference) == 0
|| placeholder_seen)
return; return;
if (current_function_decl == 0) if (current_function_decl == 0)
...@@ -19064,7 +19133,7 @@ lower_bound_default (void) ...@@ -19064,7 +19133,7 @@ lower_bound_default (void)
static void static void
add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr,
tree bound, const struct loc_descr_context *context) tree bound, struct loc_descr_context *context)
{ {
int dflt; int dflt;
...@@ -19095,7 +19164,8 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, ...@@ -19095,7 +19164,8 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr,
encodings, GDB isn't ready yet to handle proper DWARF description encodings, GDB isn't ready yet to handle proper DWARF description
for self-referencial subrange bounds: let GNAT encodings do the for self-referencial subrange bounds: let GNAT encodings do the
magic in such a case. */ magic in such a case. */
if (gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL if (is_ada ()
&& gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL
&& contains_placeholder_p (bound)) && contains_placeholder_p (bound))
return; return;
...@@ -20121,7 +20191,9 @@ gen_descr_array_type_die (tree type, struct array_descr_info *info, ...@@ -20121,7 +20191,9 @@ gen_descr_array_type_die (tree type, struct array_descr_info *info,
{ {
const dw_die_ref scope_die = scope_die_for (type, context_die); const dw_die_ref scope_die = scope_die_for (type, context_die);
const dw_die_ref array_die = new_die (DW_TAG_array_type, scope_die, type); const dw_die_ref array_die = new_die (DW_TAG_array_type, scope_die, type);
const struct loc_descr_context context = { type, info->base_decl, NULL }; struct loc_descr_context context = { type, info->base_decl, NULL,
false, false };
enum dwarf_tag subrange_tag = DW_TAG_subrange_type;
int dim; int dim;
add_name_attribute (array_die, type_tag (type)); add_name_attribute (array_die, type_tag (type));
...@@ -20169,13 +20241,23 @@ gen_descr_array_type_die (tree type, struct array_descr_info *info, ...@@ -20169,13 +20241,23 @@ gen_descr_array_type_die (tree type, struct array_descr_info *info,
add_scalar_info (array_die, attr, info->stride, forms, &context); add_scalar_info (array_die, attr, info->stride, forms, &context);
} }
} }
if (dwarf_version >= 5)
{
if (info->rank)
{
add_scalar_info (array_die, DW_AT_rank, info->rank,
dw_scalar_form_constant
| dw_scalar_form_exprloc, &context);
subrange_tag = DW_TAG_generic_subrange;
context.placeholder_arg = true;
}
}
add_gnat_descriptive_type_attribute (array_die, type, context_die); add_gnat_descriptive_type_attribute (array_die, type, context_die);
for (dim = 0; dim < info->ndimensions; dim++) for (dim = 0; dim < info->ndimensions; dim++)
{ {
dw_die_ref subrange_die dw_die_ref subrange_die = new_die (subrange_tag, array_die, NULL);
= new_die (DW_TAG_subrange_type, array_die, NULL);
if (info->dimen[dim].bounds_type) if (info->dimen[dim].bounds_type)
add_type_attribute (subrange_die, add_type_attribute (subrange_die,
...@@ -23104,7 +23186,9 @@ gen_variant_part (tree variant_part_decl, struct vlr_context *vlr_ctx, ...@@ -23104,7 +23186,9 @@ gen_variant_part (tree variant_part_decl, struct vlr_context *vlr_ctx,
struct loc_descr_context ctx = { struct loc_descr_context ctx = {
vlr_ctx->struct_type, /* context_type */ vlr_ctx->struct_type, /* context_type */
NULL_TREE, /* base_decl */ NULL_TREE, /* base_decl */
NULL /* dpi */ NULL, /* dpi */
false, /* placeholder_arg */
false /* placeholder_seen */
}; };
/* The FIELD_DECL node in STRUCT_TYPE that acts as the discriminant, or /* The FIELD_DECL node in STRUCT_TYPE that acts as the discriminant, or
......
...@@ -241,9 +241,9 @@ struct GTY((chain_next ("%h.dw_loc_next"))) dw_loc_descr_node { ...@@ -241,9 +241,9 @@ struct GTY((chain_next ("%h.dw_loc_next"))) dw_loc_descr_node {
/* Used to distinguish DW_OP_addr with a direct symbol relocation /* Used to distinguish DW_OP_addr with a direct symbol relocation
from DW_OP_addr with a dtp-relative symbol relocation. */ from DW_OP_addr with a dtp-relative symbol relocation. */
unsigned int dtprel : 1; unsigned int dtprel : 1;
/* For DW_OP_pick operations: true iff. it targets a DWARF prodecure /* For DW_OP_pick, DW_OP_dup and DW_OP_over operations: true iff.
argument. In this case, it needs to be relocated according to the current it targets a DWARF prodecure argument. In this case, it needs to be
frame offset. */ relocated according to the current frame offset. */
unsigned int frame_offset_rel : 1; unsigned int frame_offset_rel : 1;
int dw_loc_addr; int dw_loc_addr;
dw_val_node dw_loc_oprnd1; dw_val_node dw_loc_oprnd1;
...@@ -329,6 +329,7 @@ struct array_descr_info ...@@ -329,6 +329,7 @@ struct array_descr_info
tree allocated; tree allocated;
tree associated; tree associated;
tree stride; tree stride;
tree rank;
bool stride_in_bits; bool stride_in_bits;
struct array_descr_dimen struct array_descr_dimen
{ {
......
2016-10-31 Jakub Jelinek <jakub@redhat.com>
* trans-types.c (gfc_get_array_descr_info): For -gdwarf-5 or
-gno-strict-dwarf, handle assumed rank arrays the way dwarf2out
expects.
2016-10-30 Thomas Koenig <tkoenig@gcc.gnu.org> 2016-10-30 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/67219 PR fortran/67219
......
...@@ -3139,7 +3139,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) ...@@ -3139,7 +3139,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
int rank, dim; int rank, dim;
bool indirect = false; bool indirect = false;
tree etype, ptype, field, t, base_decl; tree etype, ptype, field, t, base_decl;
tree data_off, dim_off, dim_size, elem_size; tree data_off, dim_off, dtype_off, dim_size, elem_size;
tree lower_suboff, upper_suboff, stride_suboff; tree lower_suboff, upper_suboff, stride_suboff;
if (! GFC_DESCRIPTOR_TYPE_P (type)) if (! GFC_DESCRIPTOR_TYPE_P (type))
...@@ -3203,6 +3203,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) ...@@ -3203,6 +3203,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
data_off = byte_position (field); data_off = byte_position (field);
field = DECL_CHAIN (field); field = DECL_CHAIN (field);
field = DECL_CHAIN (field); field = DECL_CHAIN (field);
dtype_off = byte_position (field);
field = DECL_CHAIN (field); field = DECL_CHAIN (field);
dim_off = byte_position (field); dim_off = byte_position (field);
dim_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (field))); dim_size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (field)));
...@@ -3225,6 +3226,24 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) ...@@ -3225,6 +3226,24 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
|| GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT) || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)
info->associated = build2 (NE_EXPR, boolean_type_node, info->associated = build2 (NE_EXPR, boolean_type_node,
info->data_location, null_pointer_node); info->data_location, null_pointer_node);
if ((GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK
|| GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK_CONT)
&& dwarf_version >= 5)
{
rank = 1;
info->ndimensions = 1;
t = base_decl;
if (!integer_zerop (dtype_off))
t = fold_build_pointer_plus (t, dtype_off);
t = build1 (NOP_EXPR, build_pointer_type (gfc_array_index_type), t);
t = build1 (INDIRECT_REF, gfc_array_index_type, t);
info->rank = build2 (BIT_AND_EXPR, gfc_array_index_type, t,
build_int_cst (gfc_array_index_type,
GFC_DTYPE_RANK_MASK));
t = build0 (PLACEHOLDER_EXPR, TREE_TYPE (dim_off));
t = size_binop (MULT_EXPR, t, dim_size);
dim_off = build2 (PLUS_EXPR, TREE_TYPE (dim_off), t, dim_off);
}
for (dim = 0; dim < rank; dim++) for (dim = 0; dim < rank; dim++)
{ {
...@@ -3260,6 +3279,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) ...@@ -3260,6 +3279,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
t = build1 (INDIRECT_REF, gfc_array_index_type, t); t = build1 (INDIRECT_REF, gfc_array_index_type, t);
t = build2 (MULT_EXPR, gfc_array_index_type, t, elem_size); t = build2 (MULT_EXPR, gfc_array_index_type, t, elem_size);
info->dimen[dim].stride = t; info->dimen[dim].stride = t;
if (dim + 1 < rank)
dim_off = size_binop (PLUS_EXPR, dim_off, dim_size); dim_off = size_binop (PLUS_EXPR, dim_off, dim_size);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment