public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: "Potharla, Rupesh" <Rupesh.Potharla@amd.com>
Cc: "George, Jini Susan" <JiniSusan.George@amd.com>,
	"Parasuraman, Hariharan" <Hariharan.Parasuraman@amd.com>,
	"Sharma, Alok Kumar" <AlokKumar.Sharma@amd.com>,
	"gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [PATCH] Support for Fortran's ASSUMED RANK
Date: Wed, 23 Mar 2022 11:58:09 +0000	[thread overview]
Message-ID: <20220323115809.GT1212730@redhat.com> (raw)
In-Reply-To: <DM6PR12MB42190F21798466D70C4502D6E7119@DM6PR12MB4219.namprd12.prod.outlook.com>

* Potharla, Rupesh via Gdb-patches <gdb-patches@sourceware.org> [2022-03-16 11:54:18 +0000]:

> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> > I still think we should investigate a solution that makes use of the existing
> > push initial value mechanism, even if we end up needing to improve that
> > first.
> > 
> > It feels (to me) that just adding more random arguments for things we want
> > to push is going to make for a clunky API.
> 
> I had made code changes making use of push initial value mechanism. Request to review the attached patch file and let me know your suggestions?
>

Hi Rupesh,

Thanks for continuing to work on this feature.  I'm about to post an
alternative series that incorporates your work, but takes a slightly
different approach as to how to pass values to the dwarf expression
evaluator.  I'd be grateful if you could take a look at these patches,
and give your opinion.

Of particular interest, there are two places in the patch below where
I didn't understand your change, and in the end I just removed these
from my series.  The test case still passes, which tells me these
changes were not required for _this_ test case, but maybe these
changes are needed for some other test cases you've seen?  If this is
the case, maybe you could follow up with some extended test cases that
reveal why these two changes are needed?

Anyway, in the patch below I've mentioned the two changes I'm talking
about, so you know what to look for when reviewing my alternative
patches


> From ec5a5a05e82d8399c83add5a5ea42ff905031c41 Mon Sep 17 00:00:00 2001
> From: rupothar <rupesh.potharla@amd.com>
> Date: Wed, 16 Mar 2022 16:21:53 +0530
> Subject: [PATCH] Support for Fortran's ASSUMED RANK.
> 
> This patch reads assumed rank array rank value using rank attribute and
> stores the dimensions in a dynamic property list of main_type. Creates
> types based on the rank value stores and link them to the main_type.
> 
> The patch pushes array descriptor onto the stack and evaluates the generic
> subrange tag to get array dimensions.
> 
> The purpose of the patch is to print rank, type and values of assumed rank arrays.
> 
> Testcase used:
> 
> PROGRAM arank
> 
> REAL :: a1(10)
> 
> CALL sub1(a1)
> 
> CONTAINS
> SUBROUTINE sub1(a)
> REAL :: a(..)
> PRINT *, RANK(a)
> END
> END
> 
> 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) br sub1
> Breakpoint 1 at 0x4006ff: file assumedrank.f90, line 10.
> (gdb) r
> 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) p RANK(a)
> 'a' has unknown type; cast it to its declared type
> 
> With patch :
> gdb -q assumedrank
> Reading symbols from assumedrank...
> (gdb) br sub1
> Breakpoint 1 at 0x4006ff: file assumedrank.f90, line 10.
> (gdb) r
> Starting program: /home/rupesh/STAGING-BUILD-2787/bin/assumedrank
> 
> Breakpoint 1, arank::sub1 (a=...) at assumedrank.f90:10
> 10       PRINT *, RANK(a)
> (gdb) p RANK(a)
> $1 = 1
> (gdb) ptype a
> type = real(kind=4) (10)
> (gdb)
> ---
>  gdb/dwarf2/loc.c                          |  4 ++
>  gdb/dwarf2/read.c                         | 19 ++++-
>  gdb/f-typeprint.c                         |  4 +-
>  gdb/gdbtypes.c                            | 63 +++++++++++++++--
>  gdb/gdbtypes.h                            |  7 ++
>  gdb/testsuite/gdb.fortran/assumedrank.exp | 86 +++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/assumedrank.f90 | 41 +++++++++++
>  7 files changed, 215 insertions(+), 9 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.fortran/assumedrank.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/assumedrank.f90
> 
> diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c
> index badc7f89078..be47c41ddcb 100644
> --- a/gdb/dwarf2/loc.c
> +++ b/gdb/dwarf2/loc.c
> @@ -1562,7 +1562,11 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
>    if (push_initial_value)
>      {
>        if (addr_stack != nullptr)
> +      {
>  	ctx.push_address (addr_stack->addr, false);
> +	if (addr_stack->type->code() == TYPE_CODE_RANGE)
> +	  addr_stack = addr_stack->next;
> +      }
>        else
>  	ctx.push_address (0, false);
>      }
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 10550336063..96ab399546b 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.  */
> @@ -16652,7 +16655,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);
>  
> @@ -18974,6 +18978,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;
> @@ -19107,6 +19112,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)
> @@ -22037,6 +22043,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;
> @@ -22530,6 +22537,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;
> @@ -24813,6 +24821,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)
>      {
> diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
> index 3b26bf74b61..183686adc2c 100644
> --- a/gdb/f-typeprint.c
> +++ b/gdb/f-typeprint.c
> @@ -178,9 +178,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
>        else if ((TYPE_ASSOCIATED_PROP (type)
>  		&& PROP_CONST != TYPE_ASSOCIATED_PROP (type)->kind ())
>  	       || (TYPE_ALLOCATED_PROP (type)
> -		   && PROP_CONST != TYPE_ALLOCATED_PROP (type)->kind ())
> -	       || (TYPE_DATA_LOCATION (type)
> -		   && PROP_CONST != TYPE_DATA_LOCATION (type)->kind ()))
> +		   && PROP_CONST != TYPE_ALLOCATED_PROP (type)->kind ()))

You remove the data location handling here, and its not clear why.
This was certainly causing some test failures in gdb.fortran/*.exp
tests (or maybe gdb.ada/*.exp?), I don't recall exactly which tests
though.

I reverted this hunk in my patch, but maybe there's a reason why you
made this change?

>  	{
>  	  /* This case exist when we ptype a typename which has the dynamic
>  	     properties but cannot be resolved as there is no object.  */
> diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
> index f41d6bd960e..db106913f8e 100644
> --- a/gdb/gdbtypes.c
> +++ b/gdb/gdbtypes.c
> @@ -2199,7 +2199,7 @@ static struct type *resolve_dynamic_type_internal
>  static struct type *
>  resolve_dynamic_range (struct type *dyn_range_type,
>  		       struct property_addr_info *addr_stack,
> -		       bool resolve_p = true)
> +		       bool resolve_p = true, bool push_initial_value = false)
>  {
>    CORE_ADDR value;
>    struct type *static_range_type, *static_target_type;
> @@ -2208,13 +2208,15 @@ resolve_dynamic_range (struct type *dyn_range_type,
>    gdb_assert (dyn_range_type->code () == TYPE_CODE_RANGE);
>  
>    const struct dynamic_prop *prop = &dyn_range_type->bounds ()->low;
> -  if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
> +  if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value,
> +                                             push_initial_value))
>      low_bound.set_const_val (value);
>    else
>      low_bound.set_undefined ();
>  
>    prop = &dyn_range_type->bounds ()->high;
> -  if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
> +  if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value,
> +                                             push_initial_value))
>      {
>        high_bound.set_const_val (value);
>  
> @@ -2227,7 +2229,8 @@ resolve_dynamic_range (struct type *dyn_range_type,
>  
>    bool byte_stride_p = dyn_range_type->bounds ()->flag_is_byte_stride;
>    prop = &dyn_range_type->bounds ()->stride;
> -  if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
> +  if (resolve_p && dwarf2_evaluate_property (prop, NULL, addr_stack, &value,
> +                                             push_initial_value))
>      {
>        stride.set_const_val (value);
>  
> @@ -2275,8 +2278,12 @@ resolve_dynamic_array_or_string (struct type *type,
>    struct type *elt_type;
>    struct type *range_type;
>    struct type *ary_dim;
> +  struct type *tmp_type;
> +  struct type *element_type;
>    struct dynamic_prop *prop;
>    unsigned int bit_stride = 0;
> +  int i;
> +  static int rank = 0;

I removed this use of a static variable by spliting the containing
function into two parts, an outer core, and an inner worker.  Though
gdb itself is single threaded we don't encourage writing thread unsafe
code like this.

>  
>    /* For dynamic type resolution strings can be treated like arrays of
>       characters.  */
> @@ -2312,8 +2319,54 @@ resolve_dynamic_array_or_string (struct type *type,
>  	resolve_p = false;
>      }
>  
> +  /* Resolve the rank property to get rank value. If rank is zero or is of
> +     variable type remove the array type from the linked list. If the rank
> +     is greater than 1 add more array types to the list based on rank value
> +     to hold multi dimensional array information.   */
> +  prop = TYPE_RANK_PROP (type);
> +  if (!rank && prop != NULL && resolve_p
> +     &&  dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
> +    {
> +      prop->set_const_val (value);
> +      if (value == 0)
> +      {
> +	resolve_p = false;
> +	TYPE_DYN_PROP(TYPE_TARGET_TYPE(type)) = TYPE_DYN_PROP(type);
> +	type = TYPE_TARGET_TYPE(type);
> +	return type;

It wasn't clear to me when this case was expected to trigger, other
than if something goes wrong resolving the rank.  I ended up replacing
this code with something like:

  if (value <= 0)
    error (....);

Notice the change from '==' to '<=' as the latter seemed like a better
check, and I now just throw an error.  Do you have a test that
triggers this block?  And is your original code critical?


Thanks,
Andrew


> +      }
> +      else
> +      {
> +        rank = value;
> +        tmp_type = type;
> +        element_type = TYPE_TARGET_TYPE(tmp_type);
> +        for (i = 1; i < rank; i++)
> +        {
> +          TYPE_TARGET_TYPE(tmp_type) = copy_type(tmp_type);
> +          tmp_type = TYPE_TARGET_TYPE(tmp_type);
> +        }
> +        TYPE_TARGET_TYPE(tmp_type) = element_type;
> +      }
> +    }
> +
>    range_type = check_typedef (type->index_type ());
> -  range_type = resolve_dynamic_range (range_type, addr_stack, resolve_p);
> +
> +  if (!rank)
> +    range_type = resolve_dynamic_range (range_type, addr_stack, resolve_p);
> +  else
> +  {
> +   /* push array dimension onto the stack before evaluating
> +      expression to get array bounds. */
> +    struct property_addr_info pinfo;
> +    pinfo.type = range_type;
> +    pinfo.next = addr_stack;
> +    pinfo.addr = (CORE_ADDR)(rank-1);
> +    range_type = resolve_dynamic_range (range_type, &pinfo, resolve_p,
> +                                        /*push_initial_value*/ true);
> +  }
> +
> +  if (rank)
> +    rank--;
>  
>    ary_dim = check_typedef (TYPE_TARGET_TYPE (type));
>    if (ary_dim != NULL && ary_dim->code () == TYPE_CODE_ARRAY)
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index bd192da4b4b..2dab6c26651 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -570,6 +570,10 @@ enum dynamic_prop_node_kind
>    /* A property holding variant parts.  */
>    DYN_PROP_VARIANT_PARTS,
>  
> +  /* A property representing DW_AT_rank. The presence of this attribute
> +     indicates that the object is of assumed rank array type.  */
> +  DYN_PROP_RANK,
> +
>    /* A property holding the size of the type.  */
>    DYN_PROP_BYTE_SIZE,
>  };
> @@ -2049,6 +2053,7 @@ extern void allocate_gnat_aux_type (struct type *);
>  #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
>  #define TYPE_RVALUE_REFERENCE_TYPE(thistype) (thistype)->rvalue_reference_type
>  #define TYPE_CHAIN(thistype) (thistype)->chain
> +#define TYPE_DYN_PROP(thistype)  TYPE_MAIN_TYPE(thistype)->dyn_prop_list
>  /* * Note that if thistype is a TYPEDEF type, you have to call check_typedef.
>     But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
>     so you only have to call check_typedef once.  Since allocate_value
> @@ -2091,6 +2096,8 @@ extern bool set_type_align (struct type *, ULONGEST);
>    ((thistype)->dyn_prop (DYN_PROP_ALLOCATED))
>  #define TYPE_ASSOCIATED_PROP(thistype) \
>    ((thistype)->dyn_prop (DYN_PROP_ASSOCIATED))
> +#define TYPE_RANK_PROP(thistype) \
> +  ((thistype)->dyn_prop (DYN_PROP_RANK))
>  
>  /* C++ */
>  
> diff --git a/gdb/testsuite/gdb.fortran/assumedrank.exp b/gdb/testsuite/gdb.fortran/assumedrank.exp
> new file mode 100644
> index 00000000000..8601df82903
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/assumedrank.exp
> @@ -0,0 +1,86 @@
> +# Copyright 2021 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see <http://www.gnu.org/licenses/> .
> +
> +# Testing GDB's implementation of ASSUMED RANK.
> +
> +if {[skip_fortran_tests]} { return -1 }
> +
> +standard_testfile ".f90"
> +load_lib fortran.exp
> +
> +#only gcc version >=11 supports assumed rank
> +if { [test_compiler_info gcc*] &&
> +   ![test_compiler_info {gcc-1[1-9]-*}]} {
> +    untested "compiler do not support assumed rank"
> +    return -1
> +}
> +
> +if {[prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
> +	 {debug f90 additional_flags=-gdwarf-5}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] {
> +    untested "could not run to main"
> +    return -1
> +}
> +
> +gdb_breakpoint [gdb_get_line_number "Test Breakpoint"]
> +gdb_breakpoint [gdb_get_line_number "Final Breakpoint"]
> +
> +# We place a limit on the number of tests that can be run, just in
> +# case something goes wrong, and GDB gets stuck in an loop here.
> +set found_final_breakpoint false
> +set test_count 0
> +while { $test_count < 500 } {
> +    with_test_prefix "test $test_count" {
> +	incr test_count
> +
> +	gdb_test_multiple "continue" "continue" {
> +	    -re -wrap "! Test Breakpoint" {
> +		# We can run a test from here.
> +	    }
> +	    -re "! Final Breakpoint" {
> +		# We're done with the tests.
> +		set found_final_breakpoint true
> +	    }
> +	}
> +
> +	if ($found_final_breakpoint) {
> +	    break
> +	}
> +
> +	# First grab the expected answer.
> +	set answer [get_valueof "" "rank(answer)" "**unknown**"]
> +
> +	# Now move up a frame and figure out a command for us to run
> +	# as a test.
> +	set command ""
> +	gdb_test_multiple "up" "up" {
> +	-re -wrap "\r\n\[0-9\]+\[ \t\]+call test_rank (\[^\r\n\]+)" {
> +		set command $expect_out(1,string)
> +	    }
> +	}
> +
> +	gdb_assert { ![string equal $command ""] } "found a command to run"
> +
> +	gdb_test "p rank($command)" " = ($answer)"
> +    }
> +}
> +
> +# Ensure we reached the final breakpoint.  If more tests have been added
> +# to the test script, and this starts failing, then the safety 'while'
> +# loop above might need to be increased.
> +gdb_assert {$found_final_breakpoint} "ran all compiled in tests"
> diff --git a/gdb/testsuite/gdb.fortran/assumedrank.f90 b/gdb/testsuite/gdb.fortran/assumedrank.f90
> new file mode 100644
> index 00000000000..95584a35497
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/assumedrank.f90
> @@ -0,0 +1,41 @@
> +! Copyright 2021 Free Software Foundation, Inc.
> +!
> +! This program is free software; you can redistribute it and/or modify
> +! it under the terms of the GNU General Public License as published by
> +! the Free Software Foundation; either version 3 of the License, or
> +! (at your option) any later version.
> +!
> +! This program is distributed in the hope that it will be useful,
> +! but WITHOUT ANY WARRANTY; without even the implied warranty of
> +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +! GNU General Public License for more details.
> +!
> +! You should have received a copy of the GNU General Public License
> +! along with this program.  If not, see <http://www.gnu.org/licenses/>.
> +
> +!
> +! Start of test program.
> +!
> +
> +
> +PROGRAM  arank
> +
> +REAL :: array1(10)
> +REAL :: array2(1, 2)
> +REAL :: array3(3, 4, 5)
> +REAL :: array4(4, 5, 6, 7)
> +
> +call test_rank (array1)
> +call test_rank (array2)
> +call test_rank (array3)
> +call test_rank (array4)
> +
> +print *, "" ! Final Breakpoint
> +
> +CONTAINS
> +  SUBROUTINE test_rank(answer)
> +    REAL :: answer(..)
> +    print *, RANK(answer)     ! Test Breakpoint
> +  END
> +
> +END PROGRAM arank
> -- 
> 2.17.1
> 
> 


  reply	other threads:[~2022-03-23 11:58 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-19 17:57 Potharla, Rupesh
2022-01-21 19:07 ` Andrew Burgess
2022-01-22  7:17   ` Potharla, Rupesh
2022-01-28  7:49   ` Potharla, Rupesh
2022-02-06 13:39     ` Andrew Burgess
2022-03-16 11:54       ` Potharla, Rupesh
2022-03-23 11:58         ` Andrew Burgess [this message]
2022-03-23 11:59           ` [PATCH 0/3] Fortran assumed rank array support Andrew Burgess
2022-03-23 11:59             ` [PATCH 1/3] gdb: small simplification in dwarf2_locexpr_baton_eval Andrew Burgess
2022-04-01 19:11               ` Tom Tromey
2022-03-23 11:59             ` [PATCH 2/3] gdb/dwarf: pass an array of values to the dwarf evaluator Andrew Burgess
2022-04-01 19:16               ` Tom Tromey
2022-03-23 11:59             ` [PATCH 3/3] gdb: add support for Fortran's ASSUMED RANK arrays Andrew Burgess
2022-04-01 19:38               ` Tom Tromey
2022-04-03 16:21                 ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220323115809.GT1212730@redhat.com \
    --to=aburgess@redhat.com \
    --cc=AlokKumar.Sharma@amd.com \
    --cc=Hariharan.Parasuraman@amd.com \
    --cc=JiniSusan.George@amd.com \
    --cc=Rupesh.Potharla@amd.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).