diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-12-09 18:08:06 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-12-09 18:08:06 +0100 |
commit | fad0afd7d72cb63e47e70795baac30cb2880314a (patch) | |
tree | 1bc6c1fd7fb20cdc492bba828c7b8463fdbc4d6a /gcc/dwarf2out.c | |
parent | de80e4f820866d403b2bad4df3a59fc8b72f55f4 (diff) | |
download | gcc-fad0afd7d72cb63e47e70795baac30cb2880314a.zip gcc-fad0afd7d72cb63e47e70795baac30cb2880314a.tar.gz gcc-fad0afd7d72cb63e47e70795baac30cb2880314a.tar.bz2 |
re PR fortran/22244 (dimension information is lost for multi-dimension array)
PR fortran/22244
* langhooks-def.h (LANG_HOOKS_GET_ARRAY_DESCR_INFO): Define.
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add it.
* langhooks.h (struct array_descr_info): Forward declaration.
(struct lang_hooks_for_types): Add get_array_descr_info field.
* dwarf2.h (DW_AT_bit_stride, DW_AT_byte_stride): New.
(DW_AT_stride_size, DW_AT_stride): Keep around for Dwarf2
compatibility.
* dwarf2out.h (struct array_descr_info): New type.
* dwarf2out.c (dwarf_attr_name): Rename DW_AT_stride to
DW_AT_byte_stride and DW_AT_stride_size to DW_AT_bit_size.
(descr_info_loc, add_descr_info_field, gen_descr_array_type_die):
New functions.
(gen_type_die_with_usage): Call lang_hooks.types.get_array_descr_info
and gen_descr_array_type_die.
* trans.h (struct array_descr_info): Forward declaration.
(gfc_get_array_descr_info): New prototype.
(enum gfc_array_kind): New type.
(struct lang_type): Add akind field.
(GFC_TYPE_ARRAY_AKIND): Define.
* trans-types.c: Include dwarf2out.h.
(gfc_build_array_type): Add akind argument. Adjust
gfc_get_array_type_bounds call.
(gfc_get_nodesc_array_type): Include proper debug info even for
assumed-size arrays.
(gfc_get_array_type_bounds): Add akind argument, set
GFC_TYPE_ARRAY_AKIND to it.
(gfc_sym_type, gfc_get_derived_type): Adjust gfc_build_array_type
callers.
(gfc_get_array_descr_info): New function.
* trans-array.c (gfc_trans_create_temp_array,
gfc_conv_expr_descriptor): Adjust gfc_get_array_type_bounds
callers.
* trans-stmt.c (gfc_trans_pointer_assign_need_temp): Likewise.
* trans-types.h (gfc_get_array_type_bounds): Adjust prototype.
* Make-lang.in (fortran/trans-types.o): Depend on dwarf2out.h.
* f95-lang.c (LANG_HOOKS_GET_ARRAY_DESCR_INFO): Define.
From-SVN: r130724
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 177 |
1 files changed, 173 insertions, 4 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index f725a87..d818f0d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -4263,6 +4263,7 @@ static tree member_declared_type (const_tree); static const char *decl_start_label (tree); #endif static void gen_array_type_die (tree, dw_die_ref); +static void gen_descr_array_type_die (tree, struct array_descr_info *, dw_die_ref); #if 0 static void gen_entry_point_die (tree, dw_die_ref); #endif @@ -4669,8 +4670,8 @@ dwarf_attr_name (unsigned int attr) return "DW_AT_return_addr"; case DW_AT_start_scope: return "DW_AT_start_scope"; - case DW_AT_stride_size: - return "DW_AT_stride_size"; + case DW_AT_bit_stride: + return "DW_AT_bit_stride"; case DW_AT_upper_bound: return "DW_AT_upper_bound"; case DW_AT_abstract_origin: @@ -4738,8 +4739,8 @@ dwarf_attr_name (unsigned int attr) return "DW_AT_associated"; case DW_AT_data_location: return "DW_AT_data_location"; - case DW_AT_stride: - return "DW_AT_stride"; + case DW_AT_byte_stride: + return "DW_AT_byte_stride"; case DW_AT_entry_pc: return "DW_AT_entry_pc"; case DW_AT_use_UTF8: @@ -11675,6 +11676,163 @@ gen_array_type_die (tree type, dw_die_ref context_die) add_pubtype (type, array_die); } +static dw_loc_descr_ref +descr_info_loc (tree val, tree base_decl) +{ + HOST_WIDE_INT size; + dw_loc_descr_ref loc, loc2; + enum dwarf_location_atom op; + + if (val == base_decl) + return new_loc_descr (DW_OP_push_object_address, 0, 0); + + switch (TREE_CODE (val)) + { + case NOP_EXPR: + case CONVERT_EXPR: + return descr_info_loc (TREE_OPERAND (val, 0), base_decl); + case INTEGER_CST: + if (host_integerp (val, 0)) + return int_loc_descriptor (tree_low_cst (val, 0)); + break; + case INDIRECT_REF: + size = int_size_in_bytes (TREE_TYPE (val)); + if (size < 0) + break; + loc = descr_info_loc (TREE_OPERAND (val, 0), base_decl); + if (!loc) + break; + if (size == DWARF2_ADDR_SIZE) + add_loc_descr (&loc, new_loc_descr (DW_OP_deref, 0, 0)); + else + add_loc_descr (&loc, new_loc_descr (DW_OP_deref_size, size, 0)); + return loc; + case POINTER_PLUS_EXPR: + case PLUS_EXPR: + if (host_integerp (TREE_OPERAND (val, 1), 1) + && (unsigned HOST_WIDE_INT) tree_low_cst (TREE_OPERAND (val, 1), 1) + < 16384) + { + loc = descr_info_loc (TREE_OPERAND (val, 0), base_decl); + if (!loc) + break; + add_loc_descr (&loc, + new_loc_descr (DW_OP_plus_uconst, + tree_low_cst (TREE_OPERAND (val, 1), + 1), 0)); + } + else + { + op = DW_OP_plus; + do_binop: + loc = descr_info_loc (TREE_OPERAND (val, 0), base_decl); + if (!loc) + break; + loc2 = descr_info_loc (TREE_OPERAND (val, 1), base_decl); + if (!loc2) + break; + add_loc_descr (&loc, loc2); + add_loc_descr (&loc2, new_loc_descr (op, 0, 0)); + } + return loc; + case MINUS_EXPR: + op = DW_OP_minus; + goto do_binop; + case MULT_EXPR: + op = DW_OP_mul; + goto do_binop; + case EQ_EXPR: + op = DW_OP_eq; + goto do_binop; + case NE_EXPR: + op = DW_OP_ne; + goto do_binop; + default: + break; + } + return NULL; +} + +static void +add_descr_info_field (dw_die_ref die, enum dwarf_attribute attr, + tree val, tree base_decl) +{ + dw_loc_descr_ref loc; + + if (host_integerp (val, 0)) + { + add_AT_unsigned (die, attr, tree_low_cst (val, 0)); + return; + } + + loc = descr_info_loc (val, base_decl); + if (!loc) + return; + + add_AT_loc (die, attr, loc); +} + +/* This routine generates DIE for array with hidden descriptor, details + are filled into *info by a langhook. */ + +static void +gen_descr_array_type_die (tree type, struct array_descr_info *info, + dw_die_ref context_die) +{ + dw_die_ref scope_die = scope_die_for (type, context_die); + dw_die_ref array_die; + int dim; + + array_die = new_die (DW_TAG_array_type, scope_die, type); + add_name_attribute (array_die, type_tag (type)); + equate_type_number_to_die (type, array_die); + + if (info->data_location) + add_descr_info_field (array_die, DW_AT_data_location, info->data_location, + info->base_decl); + if (info->associated) + add_descr_info_field (array_die, DW_AT_associated, info->associated, + info->base_decl); + if (info->allocated) + add_descr_info_field (array_die, DW_AT_allocated, info->allocated, + info->base_decl); + + for (dim = 0; dim < info->ndimensions; dim++) + { + dw_die_ref subrange_die + = new_die (DW_TAG_subrange_type, array_die, NULL); + + if (info->dimen[dim].lower_bound) + { + /* If it is the default value, omit it. */ + if ((is_c_family () || is_java ()) + && integer_zerop (info->dimen[dim].lower_bound)) + ; + else if (is_fortran () + && integer_onep (info->dimen[dim].lower_bound)) + ; + else + add_descr_info_field (subrange_die, DW_AT_lower_bound, + info->dimen[dim].lower_bound, + info->base_decl); + } + if (info->dimen[dim].upper_bound) + add_descr_info_field (subrange_die, DW_AT_upper_bound, + info->dimen[dim].upper_bound, + info->base_decl); + if (info->dimen[dim].stride) + add_descr_info_field (subrange_die, DW_AT_byte_stride, + info->dimen[dim].stride, + info->base_decl); + } + + gen_type_die (info->element_type, context_die); + add_type_attribute (array_die, info->element_type, 0, 0, context_die); + + if (get_AT (array_die, DW_AT_name)) + add_pubtype (type, array_die); +} + #if 0 static void gen_entry_point_die (tree decl, dw_die_ref context_die) @@ -13051,6 +13209,7 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, enum debug_info_usage usage) { int need_pop; + struct array_descr_info info; if (type == NULL_TREE || type == error_mark_node) return; @@ -13069,6 +13228,16 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die, return; } + /* If this is an array type with hidden descriptor, handle it first. */ + if (!TREE_ASM_WRITTEN (type) + && lang_hooks.types.get_array_descr_info + && lang_hooks.types.get_array_descr_info (type, &info)) + { + gen_descr_array_type_die (type, &info, context_die); + TREE_ASM_WRITTEN (type) = 1; + return; + } + /* We are going to output a DIE to represent the unqualified version of this type (i.e. without any const or volatile qualifiers) so get the main variant (i.e. the unqualified version) of this type |