aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
diff options
context:
space:
mode:
authorrupothar <rupesh.potharla@amd.com>2022-03-17 18:56:23 +0000
committerAndrew Burgess <aburgess@redhat.com>2022-04-03 17:18:20 +0100
commitdf7a7bdd9766adebc6b117c31bc617d81c1efd43 (patch)
tree36cf2204ceffa9b267a615088ef7bf5ae51c634b /gdb/dwarf2
parent1fb43cf75982f17c27ee0c72328de41750213689 (diff)
downloadgdb-df7a7bdd9766adebc6b117c31bc617d81c1efd43.zip
gdb-df7a7bdd9766adebc6b117c31bc617d81c1efd43.tar.gz
gdb-df7a7bdd9766adebc6b117c31bc617d81c1efd43.tar.bz2
gdb: add support for Fortran's ASSUMED RANK arrays
This patch adds a new dynamic property DYN_PROP_RANK, this property is read from the DW_AT_rank attribute and stored within the type just like other dynamic properties. As arrays with dynamic ranks make use of a single DW_TAG_generic_subrange to represent all ranks of the array, support for this tag has been added to dwarf2/read.c. The final piece of this puzzle is to add support in gdbtypes.c so that we can resolve an array type with dynamic rank. To do this the existing resolve_dynamic_array_or_string function is split into two, there's a new resolve_dynamic_array_or_string_1 core that is responsible for resolving each rank of the array, while the now outer resolve_dynamic_array_or_string is responsible for figuring out the array rank (which might require resolving a dynamic property) and then calling the inner core. The resolve_dynamic_range function now takes a rank, which is passed on to the dwarf expression evaluator. This rank will only be used in the case where the array itself has dynamic rank, but we now pass the rank in all cases, this should be harmless if the rank is not needed. The only small nit is that resolve_dynamic_type_internal actually handles resolving dynamic ranges itself, which now obviously requires us to pass a rank value. But what rank value to use? In the end I just passed '1' through here as a sane default, my thinking is that if we are in resolve_dynamic_type_internal to resolve a range, then the range isn't part of an array with dynamic rank, and so the range should actually be using the rank value at all. An alternative approach would be to make the rank value a gdb::optional, however, this ends up adding a bunch of complexity to the code (e.g. having to conditionally build the array to pass to dwarf2_evaluate_property, and handling the 'rank - 1' in resolve_dynamic_array_or_string_1) so I haven't done that, but could, if people think that would be a better approach. Finally, support for assumed rank arrays was only fixed very recently in gcc, so you'll need the latest gcc in order to run the tests for this. Here's an example test program: PROGRAM arank REAL :: a1(10) CALL sub1(a1) CONTAINS SUBROUTINE sub1(a) REAL :: a(..) PRINT *, RANK(a) END SUBROUTINE sub1 END PROGRAM arank Compiler Version: gcc (GCC) 12.0.0 20211122 (experimental) Compilation command: gfortran assumedrank.f90 -gdwarf-5 -o assumedrank Without Patch: gdb -q assumedrank Reading symbols from assumedrank... (gdb) break sub1 Breakpoint 1 at 0x4006ff: file assumedrank.f90, line 10. (gdb) run Starting program: /home/rupesh/STAGING-BUILD-2787/bin/assumedrank Breakpoint 1, arank::sub1 (a=<unknown type in /home/rupesh/STAGING-BUILD-2787 /bin/assumedrank, CU 0x0, DIE 0xd5>) at assumedrank.f90:10 10 PRINT *, RANK(a) (gdb) print RANK(a) 'a' has unknown type; cast it to its declared type With patch: gdb -q assumedrank Reading symbols from assumedrank... (gdb) break sub1 Breakpoint 1 at 0x4006ff: file assumedrank.f90, line 10. (gdb) run Starting program: /home/rupesh/STAGING-BUILD-2787/bin/assumedrank Breakpoint 1, arank::sub1 (a=...) at assumedrank.f90:10 10 PRINT *, RANK(a) (gdb) print RANK(a) $1 = 1 (gdb) ptype a type = real(kind=4) (10) (gdb) Co-Authored-By: Andrew Burgess <aburgess@redhat.com>
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r--gdb/dwarf2/read.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 5c02d56..68c73c6 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -7694,6 +7694,7 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
add_partial_enumeration (pdi, cu);
break;
case DW_TAG_base_type:
+ case DW_TAG_generic_subrange:
case DW_TAG_subrange_type:
/* File scope base type definitions are added to the partial
symbol table. */
@@ -8020,6 +8021,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
case DW_TAG_typedef:
case DW_TAG_base_type:
case DW_TAG_subrange_type:
+ case DW_TAG_generic_subrange:
psymbol.domain = VAR_DOMAIN;
psymbol.aclass = LOC_TYPEDEF;
where = psymbol_placement::STATIC;
@@ -9722,6 +9724,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
/* FALLTHROUGH */
case DW_TAG_base_type:
case DW_TAG_subrange_type:
+ case DW_TAG_generic_subrange:
case DW_TAG_typedef:
/* Add a typedef symbol for the type definition, if it has a
DW_AT_name. */
@@ -16687,7 +16690,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
child_die = die->child;
while (child_die && child_die->tag)
{
- if (child_die->tag == DW_TAG_subrange_type)
+ if (child_die->tag == DW_TAG_subrange_type
+ || child_die->tag == DW_TAG_generic_subrange)
{
struct type *child_type = read_type_die (child_die, cu);
@@ -19009,6 +19013,7 @@ is_type_tag_for_partial (int tag, enum language lang)
case DW_TAG_enumeration_type:
case DW_TAG_structure_type:
case DW_TAG_subrange_type:
+ case DW_TAG_generic_subrange:
case DW_TAG_typedef:
case DW_TAG_union_type:
return 1;
@@ -19142,6 +19147,7 @@ load_partial_dies (const struct die_reader_specs *reader,
&& ((pdi.tag == DW_TAG_typedef && !pdi.has_children)
|| pdi.tag == DW_TAG_base_type
|| pdi.tag == DW_TAG_array_type
+ || pdi.tag == DW_TAG_generic_subrange
|| pdi.tag == DW_TAG_subrange_type))
{
if (building_psymtab && pdi.raw_name != NULL)
@@ -22072,6 +22078,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
case DW_TAG_array_type:
case DW_TAG_base_type:
case DW_TAG_subrange_type:
+ case DW_TAG_generic_subrange:
sym->set_aclass_index (LOC_TYPEDEF);
sym->set_domain (VAR_DOMAIN);
list_to_add = cu->list_in_scope;
@@ -22565,6 +22572,7 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_typedef:
this_type = read_typedef (die, cu);
break;
+ case DW_TAG_generic_subrange:
case DW_TAG_subrange_type:
this_type = read_subrange_type (die, cu);
break;
@@ -24848,6 +24856,15 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
type->add_dyn_prop (DYN_PROP_ASSOCIATED, prop);
}
+ /* Read DW_AT_rank and set in type. */
+ attr = dwarf2_attr (die, DW_AT_rank, cu);
+ if (attr != NULL)
+ {
+ struct type *prop_type = cu->addr_sized_int_type (false);
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
+ type->add_dyn_prop (DYN_PROP_RANK, prop);
+ }
+
/* Read DW_AT_data_location and set in type. */
if (!skip_data_location)
{