Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
@ 2021-08-24  9:16 Kumar N, Bhuvanendra via Gdb-patches
  2021-08-24  9:21 ` Kumar N, Bhuvanendra via Gdb-patches
  2021-09-20  9:41 ` Andrew Burgess
  0 siblings, 2 replies; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-08-24  9:16 UTC (permalink / raw)
  To: gdb-patches
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar, E,  Nagajyothi

[-- Attachment #1: Type: text/plain, Size: 13146 bytes --]

[AMD Official Use Only]

Hi all,

Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.

Problem description/summary:

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.

Fix details:

This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.

(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )

gdb/ChangeLog:

       * dwarf2/read.c (process_die): Add new case for namelist.
       (dwarf2_add_field): Process DW_TAG_namelist_item die.
       (read_structure_type, handle_struct_member_die, new_symbol)
       (dwarf2_name): Update.
       * f-valprint.c (f_language::value_print_inner): Add support for
      printing namelist items.
       * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
       (DW_AT_namelist_item): ... this. As per dwarf standard.

gdb/testsuite/ChangeLog:

       * gdb.fortran/namelist.exp: New file.
       * gdb.fortran/namelist.f90: New file.

NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://github.com/gcc-mirror/gcc) will be handled in separate PATCH. I will raise separate patch for this.

regards,
bhuvan

Patch inlined:

From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
Date: Mon, 24 Aug 2021 11:49:14 +0530
Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran
feature).

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
gdb/ChangeLog                          | 11 +++++++
gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
gdb/f-valprint.c                       | 10 ++++++
gdb/testsuite/ChangeLog                |  5 +++
gdb/testsuite/gdb.fortran/namelist.exp | 45 ++++++++++++++++++++++++++
gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
include/dwarf2.def                     |  2 +-
7 files changed, 134 insertions(+), 7 deletions(-)
create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 36cb4c9e7e9..ec01c2957e9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2021-08-23  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
+
+     * dwarf2/read.c (process_die): Add new case for namelist.
+     (dwarf2_add_field): Process DW_TAG_namelist_item die.
+     (read_structure_type, handle_struct_member_die, new_symbol)
+     (dwarf2_name): Update.
+     * f-valprint.c (f_language::value_print_inner): Add support for
+     printing namelist items.
+     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
+     (DW_AT_namelist_item): ... this. As per dwarf standard.
+
2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
      * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 96009f1418f..54528d67498 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
   fp = &new_field->field;
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
+            ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = NULL;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != NULL)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
       /* Get type of field.  */
@@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
   type = alloc_type (objfile);
   INIT_CPLUS_SPECIFIC (type);
+  if (die->tag == DW_TAG_namelist)
+    INIT_NONE_SPECIFIC (type);
   name = dwarf2_name (die, cu);
   if (name != NULL)
@@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
                  struct dwarf2_cu *cu)
{
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
      should be a DW_TAG_member that is a declaration, but
@@ -15728,7 +15744,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
}
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 static void
process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
     case DW_TAG_union_type:
     case DW_TAG_set_type:
     case DW_TAG_enumeration_type:
-       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+     case DW_TAG_namelist:
+       if (die->tag == DW_TAG_namelist)
+            {
+           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+         }
+       else
+            {
+           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
        {
         /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
      && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
@@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
      structures or unions.  These were of the form "._%d" in GCC 4.1,
      or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 240daaf34f9..8ed35e2fb1f 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
            fputs_filtered (" = ", stream);
          }
+           /* While printing namelist items, fetch the appropriate value
+              field before printing its value.  */
+           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
+             {
+               struct block_symbol symni = lookup_symbol(field_name,
+                get_selected_block (0), VAR_DOMAIN, nullptr);
+               if (symni.symbol != NULL)
+                 field = value_of_variable(symni.symbol, symni.block);
+             }
+
           common_val_print (field, stream, recurse + 1,
                     options, current_language);
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 87cf3e2a061..33f60c29b3c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2021-07-26  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
+
+     * gdb.fortran/namelist.exp: New file.
+     * gdb.fortran/namelist.f90: New file.
+
2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
      * gdb.fortran/ptype-on-functions.exp: Add type info of formal
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..e4df8c7debb
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,45 @@
+# Copyright 2020-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/.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 \\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
+} else {
+    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..00704eddf27
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright 2020-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/.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
DW_AT (DW_AT_friend, 0x41)
DW_AT (DW_AT_identifier_case, 0x42)
DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
DW_AT (DW_AT_priority, 0x45)
DW_AT (DW_AT_segment, 0x46)
DW_AT (DW_AT_specification, 0x47)
--
2.17.1




[-- Attachment #2: 0001-Fix-ptype-and-print-commands-for-namelist-variables-.patch --]
[-- Type: application/octet-stream, Size: 11061 bytes --]

From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Mon, 24 Aug 2021 11:49:14 +0530
Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran
 feature).

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/ChangeLog                          | 11 +++++++
 gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
 gdb/f-valprint.c                       | 10 ++++++
 gdb/testsuite/ChangeLog                |  5 +++
 gdb/testsuite/gdb.fortran/namelist.exp | 45 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 134 insertions(+), 7 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 36cb4c9e7e9..ec01c2957e9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
+
+	* dwarf2/read.c (process_die): Add new case for namelist.
+	(dwarf2_add_field): Process DW_TAG_namelist_item die.
+	(read_structure_type, handle_struct_member_die, new_symbol)
+	(dwarf2_name): Update.
+	* f-valprint.c (f_language::value_print_inner): Add support for
+	printing namelist items.
+	* include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
+	(DW_AT_namelist_item): ... this. As per dwarf standard.
+
 2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
 
 	* python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 96009f1418f..54528d67498 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
+            ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = NULL;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != NULL)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
 
   type = alloc_type (objfile);
   INIT_CPLUS_SPECIFIC (type);
+  if (die->tag == DW_TAG_namelist)
+    INIT_NONE_SPECIFIC (type);
 
   name = dwarf2_name (die, cu);
   if (name != NULL)
@@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15728,7 +15744,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+	    }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 240daaf34f9..8ed35e2fb1f 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
+	        {
+	          struct block_symbol symni = lookup_symbol(field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != NULL)
+	            field = value_of_variable(symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 87cf3e2a061..33f60c29b3c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
+
+	* gdb.fortran/namelist.exp: New file.
+	* gdb.fortran/namelist.f90: New file.
+
 2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
 
 	* gdb.fortran/ptype-on-functions.exp: Add type info of formal
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..e4df8c7debb
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,45 @@
+# Copyright 2020-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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..00704eddf27
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright 2020-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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-08-24  9:16 [PATCH] Fix ptype and print commands for namelist variables(a fortran feature) Kumar N, Bhuvanendra via Gdb-patches
@ 2021-08-24  9:21 ` Kumar N, Bhuvanendra via Gdb-patches
  2021-09-20  9:41 ` Andrew Burgess
  1 sibling, 0 replies; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-08-24  9:21 UTC (permalink / raw)
  To: gdb-patches
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar, E,  Nagajyothi

[AMD Official Use Only]

One additional information.


Testing:

- NO regressions found in GDB testsuite after the fix.

- New test case is added for this fix.



regards,

bhuvan

From: Kumar N, Bhuvanendra
Sent: Tuesday, August 24, 2021 2:46 PM
To: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>
Cc: George, Jini Susan <JiniSusan.George@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)


[AMD Official Use Only]

Hi all,

Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.

Problem description/summary:

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.

Fix details:

This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.

(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )

gdb/ChangeLog:

       * dwarf2/read.c (process_die): Add new case for namelist.
       (dwarf2_add_field): Process DW_TAG_namelist_item die.
       (read_structure_type, handle_struct_member_die, new_symbol)
       (dwarf2_name): Update.
       * f-valprint.c (f_language::value_print_inner): Add support for
      printing namelist items.
       * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
       (DW_AT_namelist_item): ... this. As per dwarf standard.

gdb/testsuite/ChangeLog:

       * gdb.fortran/namelist.exp: New file.
       * gdb.fortran/namelist.f90: New file.

NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://github.com/gcc-mirror/gcc) will be handled in separate PATCH. I will raise separate patch for this.

regards,
bhuvan

Patch inlined:

From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
Date: Mon, 24 Aug 2021 11:49:14 +0530
Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran
feature).

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
gdb/ChangeLog                          | 11 +++++++
gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
gdb/f-valprint.c                       | 10 ++++++
gdb/testsuite/ChangeLog                |  5 +++
gdb/testsuite/gdb.fortran/namelist.exp | 45 ++++++++++++++++++++++++++
gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
include/dwarf2.def                     |  2 +-
7 files changed, 134 insertions(+), 7 deletions(-)
create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 36cb4c9e7e9..ec01c2957e9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2021-08-23  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
+
+     * dwarf2/read.c (process_die): Add new case for namelist.
+     (dwarf2_add_field): Process DW_TAG_namelist_item die.
+     (read_structure_type, handle_struct_member_die, new_symbol)
+     (dwarf2_name): Update.
+     * f-valprint.c (f_language::value_print_inner): Add support for
+     printing namelist items.
+     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
+     (DW_AT_namelist_item): ... this. As per dwarf standard.
+
2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>

      * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 96009f1418f..54528d67498 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,

   fp = &new_field->field;

-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
+            ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = NULL;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != NULL)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */

       /* Get type of field.  */
@@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)

   type = alloc_type (objfile);
   INIT_CPLUS_SPECIFIC (type);
+  if (die->tag == DW_TAG_namelist)
+    INIT_NONE_SPECIFIC (type);

   name = dwarf2_name (die, cu);
   if (name != NULL)
@@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
                  struct dwarf2_cu *cu)
{
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
      should be a DW_TAG_member that is a declaration, but
@@ -15728,7 +15744,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
}

 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */

 static void
process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
     case DW_TAG_union_type:
     case DW_TAG_set_type:
     case DW_TAG_enumeration_type:
-       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+     case DW_TAG_namelist:
+       if (die->tag == DW_TAG_namelist)
+            {
+           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+         }
+       else
+            {
+           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }

        {
         /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
      && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;

@@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
      structures or unions.  These were of the form "._%d" in GCC 4.1,
      or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 240daaf34f9..8ed35e2fb1f 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
            fputs_filtered (" = ", stream);
          }

+           /* While printing namelist items, fetch the appropriate value
+              field before printing its value.  */
+           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
+             {
+               struct block_symbol symni = lookup_symbol(field_name,
+                get_selected_block (0), VAR_DOMAIN, nullptr);
+               if (symni.symbol != NULL)
+                 field = value_of_variable(symni.symbol, symni.block);
+             }
+
           common_val_print (field, stream, recurse + 1,
                     options, current_language);

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 87cf3e2a061..33f60c29b3c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2021-07-26  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
+
+     * gdb.fortran/namelist.exp: New file.
+     * gdb.fortran/namelist.f90: New file.
+
2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>

      * gdb.fortran/ptype-on-functions.exp: Add type info of formal
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..e4df8c7debb
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,45 @@
+# Copyright 2020-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/.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 \\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
+} else {
+    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..00704eddf27
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright 2020-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/.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
DW_AT (DW_AT_friend, 0x41)
DW_AT (DW_AT_identifier_case, 0x42)
DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
DW_AT (DW_AT_priority, 0x45)
DW_AT (DW_AT_segment, 0x46)
DW_AT (DW_AT_specification, 0x47)
--
2.17.1




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-08-24  9:16 [PATCH] Fix ptype and print commands for namelist variables(a fortran feature) Kumar N, Bhuvanendra via Gdb-patches
  2021-08-24  9:21 ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-09-20  9:41 ` Andrew Burgess
  2021-09-22 12:38   ` Kumar N, Bhuvanendra via Gdb-patches
  1 sibling, 1 reply; 21+ messages in thread
From: Andrew Burgess @ 2021-09-20  9:41 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	gdb-patches, E, Nagajyothi

* Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:

> [AMD Official Use Only]
> 
> Hi all,
> 
> Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> 
> Problem description/summary:
> 
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> 
> Fix details:
> 
> This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> 
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )

bhuvan,

Thanks for working on this.  I have some small style issues, but I
have a bigger question which you'll find inline.

Thanks,
Andrew


> 
> gdb/ChangeLog:
> 
>        * dwarf2/read.c (process_die): Add new case for namelist.
>        (dwarf2_add_field): Process DW_TAG_namelist_item die.
>        (read_structure_type, handle_struct_member_die, new_symbol)
>        (dwarf2_name): Update.
>        * f-valprint.c (f_language::value_print_inner): Add support for
>       printing namelist items.
>        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
>        (DW_AT_namelist_item): ... this. As per dwarf standard.
> 
> gdb/testsuite/ChangeLog:
> 
>        * gdb.fortran/namelist.exp: New file.
>        * gdb.fortran/namelist.f90: New file.
> 
> NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://github.com/gcc-mirror/gcc) will be handled in separate PATCH. I will raise separate patch for this.
> 
> regards,
> bhuvan
> 
> Patch inlined:
> 
> From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> Date: Mon, 24 Aug 2021 11:49:14 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran
> feature).
> 
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
> and DW_TAG_namelist_item dies. But gdb does not process these dies and
> support namelist variables during print and ptype commands. When tried to
> print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist
> variables and its items. Sample output of these commands is shared below,
> with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
> gdb/ChangeLog                          | 11 +++++++
> gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> gdb/f-valprint.c                       | 10 ++++++
> gdb/testsuite/ChangeLog                |  5 +++
> gdb/testsuite/gdb.fortran/namelist.exp | 45 ++++++++++++++++++++++++++
> gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> include/dwarf2.def                     |  2 +-
> 7 files changed, 134 insertions(+), 7 deletions(-)
> create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
> create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> 
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> +
> +     * dwarf2/read.c (process_die): Add new case for namelist.
> +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> +     (read_structure_type, handle_struct_member_die, new_symbol)
> +     (dwarf2_name): Update.
> +     * f-valprint.c (f_language::value_print_inner): Add support for
> +     printing namelist items.
> +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> +
> 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
>       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 96009f1418f..54528d67498 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
>    fp = &new_field->field;
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> +            ! die_is_declaration (die, cu))

The '&&' operator should start the line.

> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = NULL;

Throughout this patch, please use nullptr instead of NULL.

> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != NULL)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>        /* Get type of field.  */
> @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>    type = alloc_type (objfile);
>    INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    INIT_NONE_SPECIFIC (type);

I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in
the else block.

>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                   struct dwarf2_cu *cu)
> {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>       should be a DW_TAG_member that is a declaration, but
> @@ -15728,7 +15744,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> }
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>  static void
> process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
> @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>      case DW_TAG_union_type:
>      case DW_TAG_set_type:
>      case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +         }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>         {
>          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
> @@ -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>       && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
> @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>       structures or unions.  These were of the form "._%d" in GCC 4.1,
>       or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
> index 240daaf34f9..8ed35e2fb1f 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>             fputs_filtered (" = ", stream);
>           }
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)

I'm a little uncomfortable with this if condition.  This feels like a
bit of a hack.  Is there precedent anywhere else in GDB for using the
type specific field like this?

Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB
currently does things, though I understand this is likely to make the
patch slightly bigger.  Did you consider this approach?




> +             {
> +               struct block_symbol symni = lookup_symbol(field_name,
> +                get_selected_block (0), VAR_DOMAIN, nullptr);

There's a missing space before '(' here, and two lines below.

> +               if (symni.symbol != NULL)
> +                 field = value_of_variable(symni.symbol, symni.block);
> +             }
> +
>            common_val_print (field, stream, recurse + 1,
>                      options, current_language);
> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
> index 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> +
> +     * gdb.fortran/namelist.exp: New file.
> +     * gdb.fortran/namelist.f90: New file.
> +
> 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
>       * gdb.fortran/ptype-on-functions.exp: Add type info of formal
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..e4df8c7debb
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,45 @@
> +# Copyright 2020-2021 Free Software Foundation, Inc.

The '2020' date is only needed if the patch was original posted in
2020, or if this file is copied/based on some other in-tree file that
is copyright 2020+.

> +
> +# 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/.
> +
> +# This file is part of the gdb testsuite.  It contains tests for fortran
> +# namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"]
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 \\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>

The pattern should be wrapped onto the newline.

Thanks,
Andrew

> +} else {
> +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..00704eddf27
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright 2020-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/.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def
> index 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
> DW_AT (DW_AT_friend, 0x41)
> DW_AT (DW_AT_identifier_case, 0x42)
> DW_AT (DW_AT_macro_info, 0x43)
> -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
> DW_AT (DW_AT_priority, 0x45)
> DW_AT (DW_AT_segment, 0x46)
> DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
> 
> 
> 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-09-20  9:41 ` Andrew Burgess
@ 2021-09-22 12:38   ` Kumar N, Bhuvanendra via Gdb-patches
  2021-10-06 15:51     ` Andrew Burgess
  0 siblings, 1 reply; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-09-22 12:38 UTC (permalink / raw)
  To: Andrew Burgess
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	gdb-patches, E, Nagajyothi

[-- Attachment #1: Type: text/plain, Size: 29609 bytes --]

[AMD Official Use Only]

Hi Andrew,

Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email. 

>I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
>Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?

Regarding your major comment, I did considered introducing a new type specific field for namelist earlier, instead of using any of those existing. Reason I did not included in my earlier patch was, type_specific_kind is declared with 3 bits in struct main_type and already there were 8 values, hence deferred expanding type_specific_kind etc.... But now I have done that, thanks for the suggestion.

Regards,
bhuvan

PATH inlined: 

From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Wed, 22 Sep 2021 17:52:15 +0530
Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran
 feature).

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/ChangeLog                          | 11 ++++++
 gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
 gdb/f-valprint.c                       | 10 ++++++
 gdb/gdbtypes.h                         |  3 +-
 gdb/testsuite/ChangeLog                |  5 +++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 8 files changed, 142 insertions(+), 9 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 36cb4c9e7e9..ec01c2957e9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
+
+	* dwarf2/read.c (process_die): Add new case for namelist.
+	(dwarf2_add_field): Process DW_TAG_namelist_item die.
+	(read_structure_type, handle_struct_member_die, new_symbol)
+	(dwarf2_name): Update.
+	* f-valprint.c (f_language::value_print_inner): Add support for
+	printing namelist items.
+	* include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
+	(DW_AT_namelist_item): ... this. As per dwarf standard.
+
 2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
 
 	* python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 96009f1418f..88db06ec9e7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   type = alloc_type (objfile);
-  INIT_CPLUS_SPECIFIC (type);
+  if (die->tag == DW_TAG_namelist)
+    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;
+  else
+    INIT_CPLUS_SPECIFIC (type);
 
   name = dwarf2_name (die, cu);
   if (name != NULL)
@@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 240daaf34f9..aa86fbc901e 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 0cc00e74a20..124282c3d53 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -607,6 +607,7 @@ enum type_specific_kind
   TYPE_SPECIFIC_SELF_TYPE,
   TYPE_SPECIFIC_INT,
   TYPE_SPECIFIC_FIXED_POINT,
+  TYPE_SPECIFIC_NAMELIST,
 };
 
 union type_owner
@@ -833,7 +834,7 @@ struct main_type
   /* * A discriminant telling us which field of the type_specific
      union is being used for this type, if any.  */
 
-  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
+  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
 
   /* * Number of fields described for this type.  This field appears
      at this location because it packs nicely here.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 87cf3e2a061..33f60c29b3c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
+
+	* gdb.fortran/namelist.exp: New file.
+	* gdb.fortran/namelist.f90: New file.
+
 2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
 
 	* gdb.fortran/ptype-on-functions.exp: Add type info of formal
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


-----Original Message-----
From: Andrew Burgess <andrew.burgess@embecosm.com> 
Sent: Monday, September 20, 2021 3:11 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:

> [AMD Official Use Only]
>
> Hi all,
>
> Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
>
> Problem description/summary:
>
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
>
> Fix details:
>
> This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
>
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )

bhuvan,

Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.

Thanks,
Andrew


>
> gdb/ChangeLog:
>
>        * dwarf2/read.c (process_die): Add new case for namelist.
>        (dwarf2_add_field): Process DW_TAG_namelist_item die.
>        (read_structure_type, handle_struct_member_die, new_symbol)
>        (dwarf2_name): Update.
>        * f-valprint.c (f_language::value_print_inner): Add support for
>       printing namelist items.
>        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
>        (DW_AT_namelist_item): ... this. As per dwarf standard.
>
> gdb/testsuite/ChangeLog:
>
>        * gdb.fortran/namelist.exp: New file.
>        * gdb.fortran/namelist.f90: New file.
>
> NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7Cf615fb689a504a4c006508d97c1ad0b5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637677276883645649%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=yZro%2BZ5l9UWD0epPKzPI21qCx0KmAKZJslWb6bgkanE%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
>
> regards,
> bhuvan
>
> Patch inlined:
>
> From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= 
> Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> Date: Mon, 24 Aug 2021 11:49:14 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> fortran feature).
>
> GCC/gfortran support namelist(a fortran feature), it emits 
> DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> process these dies and support namelist variables during print and 
> ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist 
> variables and its items. Sample output of these commands is shared 
> below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
> gdb/ChangeLog                          | 11 +++++++
> gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> gdb/f-valprint.c                       | 10 ++++++
> gdb/testsuite/ChangeLog                |  5 +++
> gdb/testsuite/gdb.fortran/namelist.exp | 45 ++++++++++++++++++++++++++
> gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> include/dwarf2.def                     |  2 +-
> 7 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 
> gdb/testsuite/gdb.fortran/namelist.exp
> create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 
> 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  
> +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> +
> +     * dwarf2/read.c (process_die): Add new case for namelist.
> +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> +     (read_structure_type, handle_struct_member_die, new_symbol)
> +     (dwarf2_name): Update.
> +     * f-valprint.c (f_language::value_print_inner): Add support for
> +     printing namelist items.
> +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> +
> 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
>       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 
> 96009f1418f..54528d67498 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
>    fp = &new_field->field;
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> +            ! die_is_declaration (die, cu))

The '&&' operator should start the line.

> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = NULL;

Throughout this patch, please use nullptr instead of NULL.

> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != NULL)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>        /* Get type of field.  */
> @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>    type = alloc_type (objfile);
>    INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    INIT_NONE_SPECIFIC (type);

I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.

>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                   struct dwarf2_cu *cu) {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>       should be a DW_TAG_member that is a declaration, but @@ -15728,7 
> +15744,9 @@ handle_struct_member_die (struct die_info *child_die, 
> struct type *type, }
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>  static void
> process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>      case DW_TAG_union_type:
>      case DW_TAG_set_type:
>      case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +         }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>         {
>          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ 
> -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>       && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
> @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>       structures or unions.  These were of the form "._%d" in GCC 4.1,
>       or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> 240daaf34f9..8ed35e2fb1f 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>             fputs_filtered (" = ", stream);
>           }
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)

I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?

Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?




> +             {
> +               struct block_symbol symni = lookup_symbol(field_name,
> +                get_selected_block (0), VAR_DOMAIN, nullptr);

There's a missing space before '(' here, and two lines below.

> +               if (symni.symbol != NULL)
> +                 field = value_of_variable(symni.symbol, symni.block);
> +             }
> +
>            common_val_print (field, stream, recurse + 1,
>                      options, current_language); diff --git 
> a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  
> +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> +
> +     * gdb.fortran/namelist.exp: New file.
> +     * gdb.fortran/namelist.f90: New file.
> +
> 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
>       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp 
> b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..e4df8c7debb
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,45 @@
> +# Copyright 2020-2021 Free Software Foundation, Inc.

The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.

> +
> +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7Cf615fb689a504a4c006508d97c1ad0b5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637677276883645649%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=QG%2FRj3ZZSfOdcgEEhs5GUDAwOK5RCeBiSJdPVN1DfsY%3D&amp;reserved=0.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>

The pattern should be wrapped onto the newline.

Thanks,
Andrew

> +} else {
> +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 
> b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..00704eddf27
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7Cf615fb689a504a4c006508d97c1ad0b5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637677276883645649%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=QG%2FRj3ZZSfOdcgEEhs5GUDAwOK5RCeBiSJdPVN1DfsY%3D&amp;reserved=0.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 
> 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
> DW_AT (DW_AT_priority, 0x45)
> DW_AT (DW_AT_segment, 0x46)
> DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
>
>
>


[-- Attachment #2: 0001-Fix-ptype-and-print-commands-for-namelist-variables-.patch --]
[-- Type: application/octet-stream, Size: 11669 bytes --]

From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Wed, 22 Sep 2021 17:52:15 +0530
Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran
 feature).

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/ChangeLog                          | 11 ++++++
 gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
 gdb/f-valprint.c                       | 10 ++++++
 gdb/gdbtypes.h                         |  3 +-
 gdb/testsuite/ChangeLog                |  5 +++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 8 files changed, 142 insertions(+), 9 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 36cb4c9e7e9..ec01c2957e9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
+
+	* dwarf2/read.c (process_die): Add new case for namelist.
+	(dwarf2_add_field): Process DW_TAG_namelist_item die.
+	(read_structure_type, handle_struct_member_die, new_symbol)
+	(dwarf2_name): Update.
+	* f-valprint.c (f_language::value_print_inner): Add support for
+	printing namelist items.
+	* include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
+	(DW_AT_namelist_item): ... this. As per dwarf standard.
+
 2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
 
 	* python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 96009f1418f..88db06ec9e7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     }
 
   type = alloc_type (objfile);
-  INIT_CPLUS_SPECIFIC (type);
+  if (die->tag == DW_TAG_namelist)
+    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;
+  else
+    INIT_CPLUS_SPECIFIC (type);
 
   name = dwarf2_name (die, cu);
   if (name != NULL)
@@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 240daaf34f9..aa86fbc901e 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 0cc00e74a20..124282c3d53 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -607,6 +607,7 @@ enum type_specific_kind
   TYPE_SPECIFIC_SELF_TYPE,
   TYPE_SPECIFIC_INT,
   TYPE_SPECIFIC_FIXED_POINT,
+  TYPE_SPECIFIC_NAMELIST,
 };
 
 union type_owner
@@ -833,7 +834,7 @@ struct main_type
   /* * A discriminant telling us which field of the type_specific
      union is being used for this type, if any.  */
 
-  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
+  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
 
   /* * Number of fields described for this type.  This field appears
      at this location because it packs nicely here.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 87cf3e2a061..33f60c29b3c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
+
+	* gdb.fortran/namelist.exp: New file.
+	* gdb.fortran/namelist.f90: New file.
+
 2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
 
 	* gdb.fortran/ptype-on-functions.exp: Add type info of formal
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-09-22 12:38   ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-10-06 15:51     ` Andrew Burgess
  2021-10-07 21:05       ` Kumar N, Bhuvanendra via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Andrew Burgess @ 2021-10-06 15:51 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	gdb-patches, E, Nagajyothi

* Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:

> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email. 
> 
> >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> 
> Regarding your major comment, I did considered introducing a new
> type specific field for namelist earlier, instead of using any of
> those existing. Reason I did not included in my earlier patch was,
> type_specific_kind is declared with 3 bits in struct main_type and
> already there were 8 values, hence deferred expanding
> type_specific_kind etc.... But now I have done that, thanks for the
> suggestion.

Except that wasn't quite what I suggested; I actually asked whether
namelist's should become their own type altogether, notice I suggested
TYPE_CODE_NAMELIST.

Though what you have here is nice in its simplicity, but I can't shake
the feeling that its not the right solution.

I'll need to think about this some more - maybe others have an
opinion?

Thanks,
Andrew





> 
> Regards,
> bhuvan
> 
> PATH inlined: 
> 
> From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
> Date: Wed, 22 Sep 2021 17:52:15 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a fortran
>  feature).
> 
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
> and DW_TAG_namelist_item dies. But gdb does not process these dies and
> support namelist variables during print and ptype commands. When tried to
> print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist
> variables and its items. Sample output of these commands is shared below,
> with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/ChangeLog                          | 11 ++++++
>  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
>  gdb/f-valprint.c                       | 10 ++++++
>  gdb/gdbtypes.h                         |  3 +-
>  gdb/testsuite/ChangeLog                |  5 +++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  8 files changed, 142 insertions(+), 9 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> 
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +	* dwarf2/read.c (process_die): Add new case for namelist.
> +	(dwarf2_add_field): Process DW_TAG_namelist_item die.
> +	(read_structure_type, handle_struct_member_die, new_symbol)
> +	(dwarf2_name): Update.
> +	* f-valprint.c (f_language::value_print_inner): Add support for
> +	printing namelist items.
> +	* include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +	(DW_AT_namelist_item): ... this. As per dwarf standard.
> +
>  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
>  
>  	* python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index 96009f1418f..88db06ec9e7 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
>  
>    fp = &new_field->field;
>  
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>  
>        /* Get type of field.  */
> @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      }
>  
>    type = alloc_type (objfile);
> -  INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;
> +  else
> +    INIT_CPLUS_SPECIFIC (type);
>  
>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>  			  struct dwarf2_cu *cu)
>  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>  	 should be a DW_TAG_member that is a declaration, but
> @@ -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>  }
>  
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>  
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
> @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>  	case DW_TAG_union_type:
>  	case DW_TAG_set_type:
>  	case DW_TAG_enumeration_type:
> -	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +	case DW_TAG_namelist:
> +	  if (die->tag == DW_TAG_namelist)
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +	  else
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>  
>  	  {
>  	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
> @@ -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>  
> @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>  	 structures or unions.  These were of the form "._%d" in GCC 4.1,
>  	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
> index 240daaf34f9..aa86fbc901e 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>  		  fputs_filtered (" = ", stream);
>  		}
>  
> +	      /* While printing namelist items, fetch the appropriate value
> +	         field before printing its value.  */
> +	      if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> +	        {
> +	          struct block_symbol symni = lookup_symbol (field_name,
> +			get_selected_block (0), VAR_DOMAIN, nullptr);
> +	          if (symni.symbol != nullptr)
> +	            field = value_of_variable (symni.symbol, symni.block);
> +	        }
> +
>  	      common_val_print (field, stream, recurse + 1,
>  				options, current_language);
>  
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index 0cc00e74a20..124282c3d53 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -607,6 +607,7 @@ enum type_specific_kind
>    TYPE_SPECIFIC_SELF_TYPE,
>    TYPE_SPECIFIC_INT,
>    TYPE_SPECIFIC_FIXED_POINT,
> +  TYPE_SPECIFIC_NAMELIST,
>  };
>  
>  union type_owner
> @@ -833,7 +834,7 @@ struct main_type
>    /* * A discriminant telling us which field of the type_specific
>       union is being used for this type, if any.  */
>  
> -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
>  
>    /* * Number of fields described for this type.  This field appears
>       at this location because it packs nicely here.  */
> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
> index 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +	* gdb.fortran/namelist.exp: New file.
> +	* gdb.fortran/namelist.f90: New file.
> +
>  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
>  
>  	* gdb.fortran/ptype-on-functions.exp: Add type info of formal
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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/>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for fortran
> +# namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"]
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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/>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def
> index 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
>  DW_AT (DW_AT_friend, 0x41)
>  DW_AT (DW_AT_identifier_case, 0x42)
>  DW_AT (DW_AT_macro_info, 0x43)
> -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> -- 
> 2.17.1
> 
> 
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com> 
> Sent: Monday, September 20, 2021 3:11 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
> 
> [CAUTION: External Email]
> 
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
> 
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> >
> > Problem description/summary:
> >
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> >
> > Fix details:
> >
> > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> >
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> 
> bhuvan,
> 
> Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
> 
> Thanks,
> Andrew
> 
> 
> >
> > gdb/ChangeLog:
> >
> >        * dwarf2/read.c (process_die): Add new case for namelist.
> >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> >        (read_structure_type, handle_struct_member_die, new_symbol)
> >        (dwarf2_name): Update.
> >        * f-valprint.c (f_language::value_print_inner): Add support for
> >       printing namelist items.
> >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> >
> > gdb/testsuite/ChangeLog:
> >
> >        * gdb.fortran/namelist.exp: New file.
> >        * gdb.fortran/namelist.f90: New file.
> >
> > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7Cf615fb689a504a4c006508d97c1ad0b5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637677276883645649%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=yZro%2BZ5l9UWD0epPKzPI21qCx0KmAKZJslWb6bgkanE%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> >
> > regards,
> > bhuvan
> >
> > Patch inlined:
> >
> > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= 
> > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> > fortran feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for namelist 
> > variables and its items. Sample output of these commands is shared 
> > below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> > gdb/ChangeLog                          | 11 +++++++
> > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > gdb/f-valprint.c                       | 10 ++++++
> > gdb/testsuite/ChangeLog                |  5 +++
> > gdb/testsuite/gdb.fortran/namelist.exp | 45 ++++++++++++++++++++++++++
> > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > include/dwarf2.def                     |  2 +-
> > 7 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 
> > gdb/testsuite/gdb.fortran/namelist.exp
> > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N  
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 
> > 96009f1418f..54528d67498 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >    fp = &new_field->field;
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > +            ! die_is_declaration (die, cu))
> 
> The '&&' operator should start the line.
> 
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = NULL;
> 
> Throughout this patch, please use nullptr instead of NULL.
> 
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != NULL)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >        /* Get type of field.  */
> > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >    type = alloc_type (objfile);
> >    INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    INIT_NONE_SPECIFIC (type);
> 
> I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
> 
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                   struct dwarf2_cu *cu) {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >       should be a DW_TAG_member that is a declaration, but @@ -15728,7 
> > +15744,9 @@ handle_struct_member_die (struct die_info *child_die, 
> > struct type *type, }
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >  static void
> > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >      case DW_TAG_union_type:
> >      case DW_TAG_set_type:
> >      case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +         }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >         {
> >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ 
> > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >       && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> >       or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 
> > diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..8ed35e2fb1f 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >             fputs_filtered (" = ", stream);
> >           }
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
> 
> I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> 
> Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> 
> 
> 
> 
> > +             {
> > +               struct block_symbol symni = lookup_symbol(field_name,
> > +                get_selected_block (0), VAR_DOMAIN, nullptr);
> 
> There's a missing space before '(' here, and two lines below.
> 
> > +               if (symni.symbol != NULL)
> > +                 field = value_of_variable(symni.symbol, symni.block);
> > +             }
> > +
> >            common_val_print (field, stream, recurse + 1,
> >                      options, current_language); diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N  
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp 
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..e4df8c7debb
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,45 @@
> > +# Copyright 2020-2021 Free Software Foundation, Inc.
> 
> The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
> 
> > +
> > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7Cf615fb689a504a4c006508d97c1ad0b5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637677276883645649%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=QG%2FRj3ZZSfOdcgEEhs5GUDAwOK5RCeBiSJdPVN1DfsY%3D&amp;reserved=0.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
> 
> The pattern should be wrapped onto the newline.
> 
> Thanks,
> Andrew
> 
> > +} else {
> > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..00704eddf27
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7Cf615fb689a504a4c006508d97c1ad0b5%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637677276883645649%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=QG%2FRj3ZZSfOdcgEEhs5GUDAwOK5RCeBiSJdPVN1DfsY%3D&amp;reserved=0.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index 
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> > DW_AT (DW_AT_priority, 0x45)
> > DW_AT (DW_AT_segment, 0x46)
> > DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> >
> 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-10-06 15:51     ` Andrew Burgess
@ 2021-10-07 21:05       ` Kumar N, Bhuvanendra via Gdb-patches
  2021-10-18 17:02         ` Kumar N, Bhuvanendra via Gdb-patches
                           ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-10-07 21:05 UTC (permalink / raw)
  To: Andrew Burgess
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	gdb-patches, E, Nagajyothi

[-- Attachment #1: Type: text/plain, Size: 45451 bytes --]

[AMD Official Use Only]

Hi Andrew,

Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.

thanks,
bhuvan

PATCH inlined:

From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
 variables.

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         |  2 ++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 132 insertions(+), 8 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index cbd9a3012eb..e6cd8ed48f0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 27d9a730978..6f80b5a12ff 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index dc575c42996..ba8a61987db 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,8 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


-----Original Message-----
From: Andrew Burgess <andrew.burgess@embecosm.com> 
Sent: Wednesday, October 6, 2021 9:22 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:

> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
>
> >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
> Regarding your major comment, I did considered introducing a new type 
> specific field for namelist earlier, instead of using any of those 
> existing. Reason I did not included in my earlier patch was, 
> type_specific_kind is declared with 3 bits in struct main_type and 
> already there were 8 values, hence deferred expanding 
> type_specific_kind etc.... But now I have done that, thanks for the 
> suggestion.

Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.

Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.

I'll need to think about this some more - maybe others have an opinion?

Thanks,
Andrew





>
> Regards,
> bhuvan
>
> PATH inlined:
>
> From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= 
> <Bhuvanendra.KumarN@amd.com>
> Date: Wed, 22 Sep 2021 17:52:15 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> fortran  feature).
>
> GCC/gfortran support namelist(a fortran feature), it emits 
> DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> process these dies and support namelist variables during print and 
> ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist 
> variables and its items. Sample output of these commands is shared 
> below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/ChangeLog                          | 11 ++++++
>  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
>  gdb/f-valprint.c                       | 10 ++++++
>  gdb/gdbtypes.h                         |  3 +-
>  gdb/testsuite/ChangeLog                |  5 +++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49 
> ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  8 files changed, 142 insertions(+), 9 deletions(-)  create mode 
> 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 
> 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * dwarf2/read.c (process_die): Add new case for namelist.
> +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> +     (read_structure_type, handle_struct_member_die, new_symbol)
> +     (dwarf2_name): Update.
> +     * f-valprint.c (f_language::value_print_inner): Add support for
> +     printing namelist items.
> +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> +
>  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
>
>       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 
> 96009f1418f..88db06ec9e7 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, 
> struct die_info *die,
>
>    fp = &new_field->field;
>
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>
>        /* Get type of field.  */
> @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      }
>
>    type = alloc_type (objfile);
> -  INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> +    INIT_CPLUS_SPECIFIC (type);
>
>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                         struct dwarf2_cu *cu)  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>        should be a DW_TAG_member that is a declaration, but @@ 
> -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info 
> *child_die, struct type *type,  }
>
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>       case DW_TAG_union_type:
>       case DW_TAG_set_type:
>       case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>
>         {
>           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ 
> -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>
> @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>        structures or unions.  These were of the form "._%d" in GCC 4.1,
>        or simply "<anonymous struct>" or "<anonymous union>" in GCC 
> 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> 240daaf34f9..aa86fbc901e 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>                 fputs_filtered (" = ", stream);
>               }
>
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> +             {
> +               struct block_symbol symni = lookup_symbol (field_name,
> +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> +               if (symni.symbol != nullptr)
> +                 field = value_of_variable (symni.symbol, symni.block);
> +             }
> +
>             common_val_print (field, stream, recurse + 1,
>                               options, current_language);
>
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 
> 0cc00e74a20..124282c3d53 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -607,6 +607,7 @@ enum type_specific_kind
>    TYPE_SPECIFIC_SELF_TYPE,
>    TYPE_SPECIFIC_INT,
>    TYPE_SPECIFIC_FIXED_POINT,
> +  TYPE_SPECIFIC_NAMELIST,
>  };
>
>  union type_owner
> @@ -833,7 +834,7 @@ struct main_type
>    /* * A discriminant telling us which field of the type_specific
>       union is being used for this type, if any.  */
>
> -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
>
>    /* * Number of fields described for this type.  This field appears
>       at this location because it packs nicely here.  */ diff --git 
> a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * gdb.fortran/namelist.exp: New file.
> +     * gdb.fortran/namelist.f90: New file.
> +
>  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
>
>       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp 
> b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 
> b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 
> 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
>
>
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Sent: Monday, September 20, 2021 3:11 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan 
> <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi 
> <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> variables(a fortran feature)
>
> [CAUTION: External Email]
>
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
>
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> >
> > Problem description/summary:
> >
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> >
> > Fix details:
> >
> > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> >
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
>
> bhuvan,
>
> Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
>
> Thanks,
> Andrew
>
>
> >
> > gdb/ChangeLog:
> >
> >        * dwarf2/read.c (process_die): Add new case for namelist.
> >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> >        (read_structure_type, handle_struct_member_die, new_symbol)
> >        (dwarf2_name): Update.
> >        * f-valprint.c (f_language::value_print_inner): Add support for
> >       printing namelist items.
> >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> >
> > gdb/testsuite/ChangeLog:
> >
> >        * gdb.fortran/namelist.exp: New file.
> >        * gdb.fortran/namelist.f90: New file.
> >
> > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8mncjSuCt9BEaGJTnlJ9qp0%2FpFSVvfkVxbe%2FNFrej0%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> >
> > regards,
> > bhuvan
> >
> > Patch inlined:
> >
> > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 
> > 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist 
> > variables(a fortran feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for 
> > namelist variables and its items. Sample output of these commands is 
> > shared below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> > gdb/ChangeLog                          | 11 +++++++
> > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > gdb/f-valprint.c                       | 10 ++++++
> > gdb/testsuite/ChangeLog                |  5 +++
> > gdb/testsuite/gdb.fortran/namelist.exp | 45 
> > ++++++++++++++++++++++++++
> > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > include/dwarf2.def                     |  2 +-
> > 7 files changed, 134 insertions(+), 7 deletions(-) create mode 
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > 96009f1418f..54528d67498 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >    fp = &new_field->field;
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > +            ! die_is_declaration (die, cu))
>
> The '&&' operator should start the line.
>
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = NULL;
>
> Throughout this patch, please use nullptr instead of NULL.
>
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != NULL)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >        /* Get type of field.  */
> > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >    type = alloc_type (objfile);
> >    INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    INIT_NONE_SPECIFIC (type);
>
> I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
>
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                   struct dwarf2_cu *cu) {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >       should be a DW_TAG_member that is a declaration, but @@ 
> > -15728,7
> > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > struct type *type, }
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >  static void
> > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >      case DW_TAG_union_type:
> >      case DW_TAG_set_type:
> >      case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +         }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >         {
> >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >       && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> >       or simply "<anonymous struct>" or "<anonymous union>" in GCC 
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..8ed35e2fb1f 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >             fputs_filtered (" = ", stream);
> >           }
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
>
> I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
>
> Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
>
>
>
> > +             {
> > +               struct block_symbol symni = lookup_symbol(field_name,
> > +                get_selected_block (0), VAR_DOMAIN, nullptr);
>
> There's a missing space before '(' here, and two lines below.
>
> > +               if (symni.symbol != NULL)
> > +                 field = value_of_variable(symni.symbol, symni.block);
> > +             }
> > +
> >            common_val_print (field, stream, recurse + 1,
> >                      options, current_language); diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..e4df8c7debb
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,45 @@
> > +# Copyright 2020-2021 Free Software Foundation, Inc.
>
> The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
>
> > +
> > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
>
> The pattern should be wrapped onto the newline.
>
> Thanks,
> Andrew
>
> > +} else {
> > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..00704eddf27
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> > DW_AT (DW_AT_priority, 0x45)
> > DW_AT (DW_AT_segment, 0x46)
> > DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> >
>


[-- Attachment #2: 0001-gdb-fortran-Fix-ptype-and-print-commands-for-namelis.patch --]
[-- Type: application/octet-stream, Size: 11751 bytes --]

From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
 variables.

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         |  2 ++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 132 insertions(+), 8 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index cbd9a3012eb..e6cd8ed48f0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 27d9a730978..6f80b5a12ff 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index dc575c42996..ba8a61987db 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,8 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-10-07 21:05       ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-10-18 17:02         ` Kumar N, Bhuvanendra via Gdb-patches
  2021-11-04 15:50         ` Andrew Burgess via Gdb-patches
  2021-11-19 14:09         ` FW: " Kumar N, Bhuvanendra via Gdb-patches
  2 siblings, 0 replies; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-10-18 17:02 UTC (permalink / raw)
  To: Andrew Burgess
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	gdb-patches, E, Nagajyothi

[AMD Official Use Only]

Hi Andrew and all,

Gentle ping for the revised patch

regards,
Bhuvan

-----Original Message-----
From: Kumar N, Bhuvanendra
Sent: Friday, October 8, 2021 2:35 AM
To: Andrew Burgess <andrew.burgess@embecosm.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi Andrew,

Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.

thanks,
bhuvan

PATCH inlined:

From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         |  2 ++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,8 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for 
+fortran # namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"] 
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
--
2.17.1


-----Original Message-----
From: Andrew Burgess <andrew.burgess@embecosm.com>
Sent: Wednesday, October 6, 2021 9:22 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:

> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
>
> >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
> Regarding your major comment, I did considered introducing a new type 
> specific field for namelist earlier, instead of using any of those 
> existing. Reason I did not included in my earlier patch was, 
> type_specific_kind is declared with 3 bits in struct main_type and 
> already there were 8 values, hence deferred expanding 
> type_specific_kind etc.... But now I have done that, thanks for the 
> suggestion.

Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.

Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.

I'll need to think about this some more - maybe others have an opinion?

Thanks,
Andrew





>
> Regards,
> bhuvan
>
> PATH inlined:
>
> From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> <Bhuvanendra.KumarN@amd.com>
> Date: Wed, 22 Sep 2021 17:52:15 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> fortran  feature).
>
> GCC/gfortran support namelist(a fortran feature), it emits 
> DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> process these dies and support namelist variables during print and 
> ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist 
> variables and its items. Sample output of these commands is shared 
> below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/ChangeLog                          | 11 ++++++
>  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
>  gdb/f-valprint.c                       | 10 ++++++
>  gdb/gdbtypes.h                         |  3 +-
>  gdb/testsuite/ChangeLog                |  5 +++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49
> ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  8 files changed, 142 insertions(+), 9 deletions(-)  create mode
> 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * dwarf2/read.c (process_die): Add new case for namelist.
> +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> +     (read_structure_type, handle_struct_member_die, new_symbol)
> +     (dwarf2_name): Update.
> +     * f-valprint.c (f_language::value_print_inner): Add support for
> +     printing namelist items.
> +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> +
>  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
>
>       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> 96009f1418f..88db06ec9e7 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, 
> struct die_info *die,
>
>    fp = &new_field->field;
>
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>
>        /* Get type of field.  */
> @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      }
>
>    type = alloc_type (objfile);
> -  INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> +    INIT_CPLUS_SPECIFIC (type);
>
>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                         struct dwarf2_cu *cu)  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>        should be a DW_TAG_member that is a declaration, but @@
> -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info 
> *child_die, struct type *type,  }
>
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>       case DW_TAG_union_type:
>       case DW_TAG_set_type:
>       case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>
>         {
>           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>
> @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>        structures or unions.  These were of the form "._%d" in GCC 4.1,
>        or simply "<anonymous struct>" or "<anonymous union>" in GCC
> 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> 240daaf34f9..aa86fbc901e 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>                 fputs_filtered (" = ", stream);
>               }
>
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> +             {
> +               struct block_symbol symni = lookup_symbol (field_name,
> +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> +               if (symni.symbol != nullptr)
> +                 field = value_of_variable (symni.symbol, symni.block);
> +             }
> +
>             common_val_print (field, stream, recurse + 1,
>                               options, current_language);
>
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index
> 0cc00e74a20..124282c3d53 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -607,6 +607,7 @@ enum type_specific_kind
>    TYPE_SPECIFIC_SELF_TYPE,
>    TYPE_SPECIFIC_INT,
>    TYPE_SPECIFIC_FIXED_POINT,
> +  TYPE_SPECIFIC_NAMELIST,
>  };
>
>  union type_owner
> @@ -833,7 +834,7 @@ struct main_type
>    /* * A discriminant telling us which field of the type_specific
>       union is being used for this type, if any.  */
>
> -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
>
>    /* * Number of fields described for this type.  This field appears
>       at this location because it packs nicely here.  */ diff --git 
> a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * gdb.fortran/namelist.exp: New file.
> +     * gdb.fortran/namelist.f90: New file.
> +
>  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
>
>       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index
> 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
>
>
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Sent: Monday, September 20, 2021 3:11 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan 
> <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi 
> <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> variables(a fortran feature)
>
> [CAUTION: External Email]
>
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
>
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> >
> > Problem description/summary:
> >
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> >
> > Fix details:
> >
> > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> >
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
>
> bhuvan,
>
> Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
>
> Thanks,
> Andrew
>
>
> >
> > gdb/ChangeLog:
> >
> >        * dwarf2/read.c (process_die): Add new case for namelist.
> >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> >        (read_structure_type, handle_struct_member_die, new_symbol)
> >        (dwarf2_name): Update.
> >        * f-valprint.c (f_language::value_print_inner): Add support for
> >       printing namelist items.
> >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> >
> > gdb/testsuite/ChangeLog:
> >
> >        * gdb.fortran/namelist.exp: New file.
> >        * gdb.fortran/namelist.f90: New file.
> >
> > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8mncjSuCt9BEaGJTnlJ9qp0%2FpFSVvfkVxbe%2FNFrej0%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> >
> > regards,
> > bhuvan
> >
> > Patch inlined:
> >
> > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00
> > 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist 
> > variables(a fortran feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for 
> > namelist variables and its items. Sample output of these commands is 
> > shared below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> > gdb/ChangeLog                          | 11 +++++++
> > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > gdb/f-valprint.c                       | 10 ++++++
> > gdb/testsuite/ChangeLog                |  5 +++
> > gdb/testsuite/gdb.fortran/namelist.exp | 45
> > ++++++++++++++++++++++++++
> > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > include/dwarf2.def                     |  2 +-
> > 7 files changed, 134 insertions(+), 7 deletions(-) create mode
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > 96009f1418f..54528d67498 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >    fp = &new_field->field;
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > +            ! die_is_declaration (die, cu))
>
> The '&&' operator should start the line.
>
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = NULL;
>
> Throughout this patch, please use nullptr instead of NULL.
>
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != NULL)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >        /* Get type of field.  */
> > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >    type = alloc_type (objfile);
> >    INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    INIT_NONE_SPECIFIC (type);
>
> I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
>
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                   struct dwarf2_cu *cu) {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >       should be a DW_TAG_member that is a declaration, but @@
> > -15728,7
> > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > struct type *type, }
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >  static void
> > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >      case DW_TAG_union_type:
> >      case DW_TAG_set_type:
> >      case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +         }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >         {
> >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >       && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> >       or simply "<anonymous struct>" or "<anonymous union>" in GCC
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..8ed35e2fb1f 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >             fputs_filtered (" = ", stream);
> >           }
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
>
> I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
>
> Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
>
>
>
> > +             {
> > +               struct block_symbol symni = lookup_symbol(field_name,
> > +                get_selected_block (0), VAR_DOMAIN, nullptr);
>
> There's a missing space before '(' here, and two lines below.
>
> > +               if (symni.symbol != NULL)
> > +                 field = value_of_variable(symni.symbol, symni.block);
> > +             }
> > +
> >            common_val_print (field, stream, recurse + 1,
> >                      options, current_language); diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..e4df8c7debb
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,45 @@
> > +# Copyright 2020-2021 Free Software Foundation, Inc.
>
> The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
>
> > +
> > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
>
> The pattern should be wrapped onto the newline.
>
> Thanks,
> Andrew
>
> > +} else {
> > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..00704eddf27
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> > DW_AT (DW_AT_priority, 0x45)
> > DW_AT (DW_AT_segment, 0x46)
> > DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> >
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-10-07 21:05       ` Kumar N, Bhuvanendra via Gdb-patches
  2021-10-18 17:02         ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-11-04 15:50         ` Andrew Burgess via Gdb-patches
  2021-11-19 14:09         ` FW: " Kumar N, Bhuvanendra via Gdb-patches
  2 siblings, 0 replies; 21+ messages in thread
From: Andrew Burgess via Gdb-patches @ 2021-11-04 15:50 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: Achra, Nitika, E, Nagajyothi, George, Jini Susan, Sharma,
	Alok Kumar, Andrew Burgess, gdb-patches

Kumar,

Sorry for the massive delay in reviewing this.  I've been super busy
switching jobs, but hopefully I'm now going to have more time to
review stuff.

I had a look through you patch below, and it looks great.  I did
notice one odd behaviour which we probably should at least try to
understand:

If I debug the test binary for this feature:

  $ ./gdb/gdb -q --data-directory ./gdb/data-directory/ ./gdb/testsuite/outputs/gdb.fortran/namelist/namelist
  Reading symbols from ./gdb/testsuite/outputs/gdb.fortran/namelist/namelist...
  (gdb) b 25
  Breakpoint 1 at 0x40117f: file /home/andrew/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.fortran/namelist.f90, line 25.
  (gdb) r
  Starting program: /home/andrew/projects/binutils-gdb/build/gdb/testsuite/outputs/gdb.fortran/namelist/namelist 

  Breakpoint 1, MAIN__ () at /home/andrew/projects/binutils-gdb/build/gdb/testsuite/../../../src/gdb/testsuite/gdb.fortran/namelist.f90:25
  25	  Write(*,nml) ! Display namelist
  (gdb) p &nml
  $1 = (PTR TO -> ( Type nml )) 0x0
  (gdb)

The final result looks a little weird.  I would have expected either
an address as if nml was a struct, or possibly an error.

I started looking into this, but ran out of time today, I'll continue
looking at this tomorrow to see what might be going on.

Thanks,
Andrew


* Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-10-07 21:05:08 +0000]:

> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.
> 
> thanks,
> bhuvan
> 
> PATCH inlined:
> 
> From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
> Date: Fri, 8 Oct 2021 02:01:18 +0530
> Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
>  variables.
> 
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
> and DW_TAG_namelist_item dies. But gdb does not process these dies and
> support namelist variables during print and ptype commands. When tried to
> print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist
> variables and its items. Sample output of these commands is shared below,
> with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
>  gdb/f-typeprint.c                      |  6 +++-
>  gdb/f-valprint.c                       | 11 ++++++
>  gdb/gdbtypes.h                         |  2 ++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  7 files changed, 132 insertions(+), 8 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
> index cbd9a3012eb..e6cd8ed48f0 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
>  
>    fp = &new_field->field;
>  
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>  
>        /* Get type of field.  */
> @@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      {
>        type->set_code (TYPE_CODE_UNION);
>      }
> +  else if (die->tag == DW_TAG_namelist)
> +    {
> +      type->set_code (TYPE_CODE_NAMELIST);
> +    }
>    else
>      {
>        type->set_code (TYPE_CODE_STRUCT);
> @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>  			  struct dwarf2_cu *cu)
>  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>  	 should be a DW_TAG_member that is a declaration, but
> @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>  }
>  
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>  
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
> @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>  	case DW_TAG_union_type:
>  	case DW_TAG_set_type:
>  	case DW_TAG_enumeration_type:
> -	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +	case DW_TAG_namelist:
> +	  if (die->tag == DW_TAG_namelist)
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +	  else
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>  
>  	  {
>  	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
> @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>  
> @@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>  	 structures or unions.  These were of the form "._%d" in GCC 4.1,
>  	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
> diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
> index 1791cb29451..5b34622dacb 100644
> --- a/gdb/f-typeprint.c
> +++ b/gdb/f-typeprint.c
> @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>        const char *prefix = "";
>        if (type->code () == TYPE_CODE_UNION)
>  	prefix = "Type, C_Union :: ";
> -      else if (type->code () == TYPE_CODE_STRUCT)
> +      else if (type->code () == TYPE_CODE_STRUCT
> +               || type->code () == TYPE_CODE_NAMELIST)
>  	prefix = "Type ";
>        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
>        return;
> @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>  
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        if (type->code () == TYPE_CODE_UNION)
>  	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
>        else
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
> index 27d9a730978..6f80b5a12ff 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>  
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        /* Starting from the Fortran 90 standard, Fortran supports derived
>  	 types.  */
>        fprintf_filtered (stream, "( ");
> @@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>  		  fputs_filtered (" = ", stream);
>  		}
>  
> +	      /* While printing namelist items, fetch the appropriate value
> +	         field before printing its value.  */
> +	      if (type->code () == TYPE_CODE_NAMELIST)
> +	        {
> +	          struct block_symbol symni = lookup_symbol (field_name,
> +			get_selected_block (0), VAR_DOMAIN, nullptr);
> +	          if (symni.symbol != nullptr)
> +	            field = value_of_variable (symni.symbol, symni.block);
> +	        }
> +
>  	      common_val_print (field, stream, recurse + 1,
>  				options, current_language);
>  
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
> index dc575c42996..ba8a61987db 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -195,6 +195,8 @@ enum type_code
>  
>      /* * Fixed Point type.  */
>      TYPE_CODE_FIXED_POINT,
> +
> +    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
>    };
>  
>  /* * Some bits for the type's instance_flags word.  See the macros
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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/>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for fortran
> +# namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"]
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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/>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def
> index 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
>  DW_AT (DW_AT_friend, 0x41)
>  DW_AT (DW_AT_identifier_case, 0x42)
>  DW_AT (DW_AT_macro_info, 0x43)
> -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> -- 
> 2.17.1
> 
> 
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com> 
> Sent: Wednesday, October 6, 2021 9:22 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
> 
> [CAUTION: External Email]
> 
> * Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:
> 
> > [AMD Official Use Only]
> >
> > Hi Andrew,
> >
> > Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
> >
> > >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> > >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> >
> > Regarding your major comment, I did considered introducing a new type 
> > specific field for namelist earlier, instead of using any of those 
> > existing. Reason I did not included in my earlier patch was, 
> > type_specific_kind is declared with 3 bits in struct main_type and 
> > already there were 8 values, hence deferred expanding 
> > type_specific_kind etc.... But now I have done that, thanks for the 
> > suggestion.
> 
> Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.
> 
> Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.
> 
> I'll need to think about this some more - maybe others have an opinion?
> 
> Thanks,
> Andrew
> 
> 
> 
> 
> 
> >
> > Regards,
> > bhuvan
> >
> > PATH inlined:
> >
> > From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= 
> > <Bhuvanendra.KumarN@amd.com>
> > Date: Wed, 22 Sep 2021 17:52:15 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> > fortran  feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for namelist 
> > variables and its items. Sample output of these commands is shared 
> > below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> >  gdb/ChangeLog                          | 11 ++++++
> >  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
> >  gdb/f-valprint.c                       | 10 ++++++
> >  gdb/gdbtypes.h                         |  3 +-
> >  gdb/testsuite/ChangeLog                |  5 +++
> >  gdb/testsuite/gdb.fortran/namelist.exp | 49 
> > ++++++++++++++++++++++++++
> >  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
> >  include/dwarf2.def                     |  2 +-
> >  8 files changed, 142 insertions(+), 9 deletions(-)  create mode 
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> >  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> >  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
> >
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 
> > 96009f1418f..88db06ec9e7 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, 
> > struct die_info *die,
> >
> >    fp = &new_field->field;
> >
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> > +            && ! die_is_declaration (die, cu))
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = nullptr;
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != nullptr)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >
> >        /* Get type of field.  */
> > @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >      }
> >
> >    type = alloc_type (objfile);
> > -  INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> > +    INIT_CPLUS_SPECIFIC (type);
> >
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                         struct dwarf2_cu *cu)  {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >        should be a DW_TAG_member that is a declaration, but @@ 
> > -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info 
> > *child_die, struct type *type,  }
> >
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >
> >  static void
> >  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >       case DW_TAG_union_type:
> >       case DW_TAG_set_type:
> >       case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +            }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >
> >         {
> >           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ 
> > -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >        && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> >
> > @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >        structures or unions.  These were of the form "._%d" in GCC 4.1,
> >        or simply "<anonymous struct>" or "<anonymous union>" in GCC 
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..aa86fbc901e 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >                 fputs_filtered (" = ", stream);
> >               }
> >
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> > +             {
> > +               struct block_symbol symni = lookup_symbol (field_name,
> > +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> > +               if (symni.symbol != nullptr)
> > +                 field = value_of_variable (symni.symbol, symni.block);
> > +             }
> > +
> >             common_val_print (field, stream, recurse + 1,
> >                               options, current_language);
> >
> > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 
> > 0cc00e74a20..124282c3d53 100644
> > --- a/gdb/gdbtypes.h
> > +++ b/gdb/gdbtypes.h
> > @@ -607,6 +607,7 @@ enum type_specific_kind
> >    TYPE_SPECIFIC_SELF_TYPE,
> >    TYPE_SPECIFIC_INT,
> >    TYPE_SPECIFIC_FIXED_POINT,
> > +  TYPE_SPECIFIC_NAMELIST,
> >  };
> >
> >  union type_owner
> > @@ -833,7 +834,7 @@ struct main_type
> >    /* * A discriminant telling us which field of the type_specific
> >       union is being used for this type, if any.  */
> >
> > -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> > +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
> >
> >    /* * Number of fields described for this type.  This field appears
> >       at this location because it packs nicely here.  */ diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> >  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> >
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp 
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..90762928455
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,49 @@
> > +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" \
> > +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \
> > +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> > +} else {
> > +    gdb_test "ptype nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..fb36690d765
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index 
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> > (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> >  DW_AT (DW_AT_priority, 0x45)
> >  DW_AT (DW_AT_segment, 0x46)
> >  DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> > -----Original Message-----
> > From: Andrew Burgess <andrew.burgess@embecosm.com>
> > Sent: Monday, September 20, 2021 3:11 PM
> > To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> > Cc: gdb-patches@sourceware.org; George, Jini Susan 
> > <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> > Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi 
> > <Nagajyothi.E@amd.com>
> > Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> > variables(a fortran feature)
> >
> > [CAUTION: External Email]
> >
> > * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
> >
> > > [AMD Official Use Only]
> > >
> > > Hi all,
> > >
> > > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> > >
> > > Problem description/summary:
> > >
> > > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > > (gdb) print nml
> > > No symbol "nml" in current context.
> > >
> > > Fix details:
> > >
> > > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> > >
> > > (gdb) ptype nml
> > > type = Type nml
> > >     integer(kind=4) :: a
> > >     integer(kind=4) :: b
> > > End Type nml
> > > (gdb) print nml
> > > $1 = ( a = 10, b = 20 )
> >
> > bhuvan,
> >
> > Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
> >
> > Thanks,
> > Andrew
> >
> >
> > >
> > > gdb/ChangeLog:
> > >
> > >        * dwarf2/read.c (process_die): Add new case for namelist.
> > >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > >        (read_structure_type, handle_struct_member_die, new_symbol)
> > >        (dwarf2_name): Update.
> > >        * f-valprint.c (f_language::value_print_inner): Add support for
> > >       printing namelist items.
> > >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> > >
> > > gdb/testsuite/ChangeLog:
> > >
> > >        * gdb.fortran/namelist.exp: New file.
> > >        * gdb.fortran/namelist.f90: New file.
> > >
> > > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8mncjSuCt9BEaGJTnlJ9qp0%2FpFSVvfkVxbe%2FNFrej0%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> > >
> > > regards,
> > > bhuvan
> > >
> > > Patch inlined:
> > >
> > > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 
> > > 2001
> > > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > > Subject: [PATCH] Fix ptype and print commands for namelist 
> > > variables(a fortran feature).
> > >
> > > GCC/gfortran support namelist(a fortran feature), it emits 
> > > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > > process these dies and support namelist variables during print and 
> > > ptype commands. When tried to print, it bails out with the error message as shown below.
> > > (gdb) print nml
> > > No symbol "nml" in current context.
> > > This commit is to make the print and ptype commands work for 
> > > namelist variables and its items. Sample output of these commands is 
> > > shared below, with fixed gdb.
> > > (gdb) ptype nml
> > > type = Type nml
> > >     integer(kind=4) :: a
> > >     integer(kind=4) :: b
> > > End Type nml
> > > (gdb) print nml
> > > $1 = ( a = 10, b = 20 )
> > > ---
> > > gdb/ChangeLog                          | 11 +++++++
> > > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > > gdb/f-valprint.c                       | 10 ++++++
> > > gdb/testsuite/ChangeLog                |  5 +++
> > > gdb/testsuite/gdb.fortran/namelist.exp | 45 
> > > ++++++++++++++++++++++++++
> > > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > > include/dwarf2.def                     |  2 +-
> > > 7 files changed, 134 insertions(+), 7 deletions(-) create mode 
> > > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> > >
> > > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > > 36cb4c9e7e9..ec01c2957e9 100644
> > > --- a/gdb/ChangeLog
> > > +++ b/gdb/ChangeLog
> > > @@ -1,3 +1,14 @@
> > > +2021-08-23  Bhuvanendra Kumar N
> > > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > +
> > > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > > +     (dwarf2_name): Update.
> > > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > > +     printing namelist items.
> > > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > > +
> > > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> > >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > > 96009f1418f..54528d67498 100644
> > > --- a/gdb/dwarf2/read.c
> > > +++ b/gdb/dwarf2/read.c
> > > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> > >      case DW_TAG_interface_type:
> > >      case DW_TAG_structure_type:
> > >      case DW_TAG_union_type:
> > > +    case DW_TAG_namelist:
> > >        process_structure_scope (die, cu);
> > >        break;
> > >      case DW_TAG_enumeration_type:
> > > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> > >    fp = &new_field->field;
> > > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > > -    {
> > > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > > +            ! die_is_declaration (die, cu))
> >
> > The '&&' operator should start the line.
> >
> > > +    {
> > > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > > +      if (die->tag == DW_TAG_namelist_item)
> > > +        {
> > > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > > +          struct die_info *item_die = NULL;
> >
> > Throughout this patch, please use nullptr instead of NULL.
> >
> > > +          struct dwarf2_cu *item_cu = cu;
> > > +          if (attr1->form_is_ref ())
> > > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > > +          if (item_die != NULL)
> > > +            die = item_die;
> > > +        }
> > >        /* Data member other than a C++ static data member.  */
> > >        /* Get type of field.  */
> > > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> > >    type = alloc_type (objfile);
> > >    INIT_CPLUS_SPECIFIC (type);
> > > +  if (die->tag == DW_TAG_namelist)
> > > +    INIT_NONE_SPECIFIC (type);
> >
> > I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
> >
> > >    name = dwarf2_name (die, cu);
> > >    if (name != NULL)
> > > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> > >                   struct dwarf2_cu *cu) {
> > >    if (child_die->tag == DW_TAG_member
> > > -      || child_die->tag == DW_TAG_variable)
> > > +      || child_die->tag == DW_TAG_variable
> > > +      || child_die->tag == DW_TAG_namelist_item)
> > >      {
> > >        /* NOTE: carlton/2002-11-05: A C++ static data member
> > >       should be a DW_TAG_member that is a declaration, but @@ 
> > > -15728,7
> > > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > > struct type *type, }
> > >  /* Finish creating a structure or union type, including filling in
> > > -   its members and creating a symbol for it.  */
> > > +   its members and creating a symbol for it. This function also
> > > +   handles Fortran namelist variable, its items or members and
> > > +   creating a symbol for it.  */
> > >  static void
> > > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> > >      case DW_TAG_union_type:
> > >      case DW_TAG_set_type:
> > >      case DW_TAG_enumeration_type:
> > > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > > +     case DW_TAG_namelist:
> > > +       if (die->tag == DW_TAG_namelist)
> > > +            {
> > > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > > +         }
> > > +       else
> > > +            {
> > > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > > +            }
> > >         {
> > >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> > >        && die->tag != DW_TAG_class_type
> > >       && die->tag != DW_TAG_interface_type
> > >        && die->tag != DW_TAG_structure_type
> > > +      && die->tag != DW_TAG_namelist
> > >        && die->tag != DW_TAG_union_type)
> > >      return NULL;
> > > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> > >      case DW_TAG_interface_type:
> > >      case DW_TAG_structure_type:
> > >      case DW_TAG_union_type:
> > > +    case DW_TAG_namelist:
> > >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> > >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> > >       or simply "<anonymous struct>" or "<anonymous union>" in GCC 
> > > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > > 240daaf34f9..8ed35e2fb1f 100644
> > > --- a/gdb/f-valprint.c
> > > +++ b/gdb/f-valprint.c
> > > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> > >             fputs_filtered (" = ", stream);
> > >           }
> > > +           /* While printing namelist items, fetch the appropriate value
> > > +              field before printing its value.  */
> > > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
> >
> > I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >
> > Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> >
> >
> >
> >
> > > +             {
> > > +               struct block_symbol symni = lookup_symbol(field_name,
> > > +                get_selected_block (0), VAR_DOMAIN, nullptr);
> >
> > There's a missing space before '(' here, and two lines below.
> >
> > > +               if (symni.symbol != NULL)
> > > +                 field = value_of_variable(symni.symbol, symni.block);
> > > +             }
> > > +
> > >            common_val_print (field, stream, recurse + 1,
> > >                      options, current_language); diff --git 
> > > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > > 87cf3e2a061..33f60c29b3c 100644
> > > --- a/gdb/testsuite/ChangeLog
> > > +++ b/gdb/testsuite/ChangeLog
> > > @@ -1,3 +1,8 @@
> > > +2021-07-26  Bhuvanendra Kumar N
> > > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > +
> > > +     * gdb.fortran/namelist.exp: New file.
> > > +     * gdb.fortran/namelist.f90: New file.
> > > +
> > > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > > b/gdb/testsuite/gdb.fortran/namelist.exp
> > > new file mode 100644
> > > index 00000000000..e4df8c7debb
> > > --- /dev/null
> > > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > > @@ -0,0 +1,45 @@
> > > +# Copyright 2020-2021 Free Software Foundation, Inc.
> >
> > The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
> >
> > > +
> > > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > > +
> > > +# This file is part of the gdb testsuite.  It contains tests for 
> > > +fortran # namelist.
> > > +
> > > +if { [skip_fortran_tests] } { return -1 }
> > > +
> > > +standard_testfile .f90
> > > +load_lib "fortran.exp"
> > > +
> > > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > > +    return -1
> > > +}
> > > +
> > > +if ![fortran_runto_main] then {
> > > +    perror "couldn't run to main"
> > > +    continue
> > > +}
> > > +
> > > +# Depending on the compiler being used, the type names can be printed differently.
> > > +set int [fortran_int4]
> > > +
> > > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > > +gdb_continue_to_breakpoint "Display namelist"
> > > +
> > > +if {[test_compiler_info {gcc-*}]} {
> > > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
> >
> > The pattern should be wrapped onto the newline.
> >
> > Thanks,
> > Andrew
> >
> > > +} else {
> > > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > > +}
> > > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > > b/gdb/testsuite/gdb.fortran/namelist.f90
> > > new file mode 100644
> > > index 00000000000..00704eddf27
> > > --- /dev/null
> > > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > > @@ -0,0 +1,27 @@
> > > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > > +!
> > > +! This file is the Fortran source file for namelist.exp.
> > > +
> > > +program main
> > > +
> > > +  integer :: a, b
> > > +  namelist /nml/ a, b
> > > +
> > > +  a = 10
> > > +  b = 20
> > > +  Write(*,nml) ! Display namelist
> > > +
> > > +end program main
> > > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > > 1ae6e1df298..6b8be1f6a16 100644
> > > --- a/include/dwarf2.def
> > > +++ b/include/dwarf2.def
> > > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > > +DW_AT (DW_AT_namelist_item, 0x44)
> > > DW_AT (DW_AT_priority, 0x45)
> > > DW_AT (DW_AT_segment, 0x46)
> > > DW_AT (DW_AT_specification, 0x47)
> > > --
> > > 2.17.1
> > >
> > >
> > >
> >
> 



^ permalink raw reply	[flat|nested] 21+ messages in thread

* FW: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-10-07 21:05       ` Kumar N, Bhuvanendra via Gdb-patches
  2021-10-18 17:02         ` Kumar N, Bhuvanendra via Gdb-patches
  2021-11-04 15:50         ` Andrew Burgess via Gdb-patches
@ 2021-11-19 14:09         ` Kumar N, Bhuvanendra via Gdb-patches
  2021-11-19 14:32           ` Kumar N, Bhuvanendra via Gdb-patches
  2 siblings, 1 reply; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-11-19 14:09 UTC (permalink / raw)
  To: aburgess
  Cc: Achra, Nitika, Joseph, Ancel, E, Nagajyothi, George, Jini Susan,
	Sharma, Alok Kumar, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 46377 bytes --]

[AMD Official Use Only]

Hi Andrew,

Thanks again for the review. Could you please use this revised patch for the review, thanks

I am resending the revised patch now and details are shared just below in this email chain.
I am getting the proper outputs with "info local" as shown below.

Regards,
bhuvan

(gdb) i local
a = 10
b = 20
nml = ( a = 10, b = 20 )
(gdb) pt nml
type = Type nml
    integer :: a
    integer :: b
End Type nml
(gdb) whatis nml
type = Type nml

-----Original Message-----
From: Kumar N, Bhuvanendra 
Sent: Friday, October 8, 2021 2:35 AM
To: Andrew Burgess <andrew.burgess@embecosm.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi Andrew,

Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.

thanks,
bhuvan

PATCH inlined:

From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         |  2 ++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,8 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for 
+fortran # namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"] 
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
--
2.17.1


-----Original Message-----
From: Andrew Burgess <andrew.burgess@embecosm.com> 
Sent: Wednesday, October 6, 2021 9:22 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:

> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
>
> >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
> Regarding your major comment, I did considered introducing a new type 
> specific field for namelist earlier, instead of using any of those 
> existing. Reason I did not included in my earlier patch was, 
> type_specific_kind is declared with 3 bits in struct main_type and 
> already there were 8 values, hence deferred expanding 
> type_specific_kind etc.... But now I have done that, thanks for the 
> suggestion.

Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.

Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.

I'll need to think about this some more - maybe others have an opinion?

Thanks,
Andrew





>
> Regards,
> bhuvan
>
> PATH inlined:
>
> From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= 
> <Bhuvanendra.KumarN@amd.com>
> Date: Wed, 22 Sep 2021 17:52:15 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> fortran  feature).
>
> GCC/gfortran support namelist(a fortran feature), it emits 
> DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> process these dies and support namelist variables during print and 
> ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist 
> variables and its items. Sample output of these commands is shared 
> below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/ChangeLog                          | 11 ++++++
>  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
>  gdb/f-valprint.c                       | 10 ++++++
>  gdb/gdbtypes.h                         |  3 +-
>  gdb/testsuite/ChangeLog                |  5 +++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49 
> ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  8 files changed, 142 insertions(+), 9 deletions(-)  create mode 
> 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 
> 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * dwarf2/read.c (process_die): Add new case for namelist.
> +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> +     (read_structure_type, handle_struct_member_die, new_symbol)
> +     (dwarf2_name): Update.
> +     * f-valprint.c (f_language::value_print_inner): Add support for
> +     printing namelist items.
> +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> +
>  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
>
>       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 
> 96009f1418f..88db06ec9e7 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, 
> struct die_info *die,
>
>    fp = &new_field->field;
>
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>
>        /* Get type of field.  */
> @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      }
>
>    type = alloc_type (objfile);
> -  INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> +    INIT_CPLUS_SPECIFIC (type);
>
>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                         struct dwarf2_cu *cu)  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>        should be a DW_TAG_member that is a declaration, but @@ 
> -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info 
> *child_die, struct type *type,  }
>
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>       case DW_TAG_union_type:
>       case DW_TAG_set_type:
>       case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>
>         {
>           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ 
> -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>
> @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>        structures or unions.  These were of the form "._%d" in GCC 4.1,
>        or simply "<anonymous struct>" or "<anonymous union>" in GCC 
> 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> 240daaf34f9..aa86fbc901e 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>                 fputs_filtered (" = ", stream);
>               }
>
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> +             {
> +               struct block_symbol symni = lookup_symbol (field_name,
> +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> +               if (symni.symbol != nullptr)
> +                 field = value_of_variable (symni.symbol, symni.block);
> +             }
> +
>             common_val_print (field, stream, recurse + 1,
>                               options, current_language);
>
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 
> 0cc00e74a20..124282c3d53 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -607,6 +607,7 @@ enum type_specific_kind
>    TYPE_SPECIFIC_SELF_TYPE,
>    TYPE_SPECIFIC_INT,
>    TYPE_SPECIFIC_FIXED_POINT,
> +  TYPE_SPECIFIC_NAMELIST,
>  };
>
>  union type_owner
> @@ -833,7 +834,7 @@ struct main_type
>    /* * A discriminant telling us which field of the type_specific
>       union is being used for this type, if any.  */
>
> -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
>
>    /* * Number of fields described for this type.  This field appears
>       at this location because it packs nicely here.  */ diff --git 
> a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * gdb.fortran/namelist.exp: New file.
> +     * gdb.fortran/namelist.f90: New file.
> +
>  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
>
>       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp 
> b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 
> b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 
> 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
>
>
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Sent: Monday, September 20, 2021 3:11 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan 
> <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi 
> <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> variables(a fortran feature)
>
> [CAUTION: External Email]
>
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
>
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> >
> > Problem description/summary:
> >
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> >
> > Fix details:
> >
> > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> >
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
>
> bhuvan,
>
> Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
>
> Thanks,
> Andrew
>
>
> >
> > gdb/ChangeLog:
> >
> >        * dwarf2/read.c (process_die): Add new case for namelist.
> >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> >        (read_structure_type, handle_struct_member_die, new_symbol)
> >        (dwarf2_name): Update.
> >        * f-valprint.c (f_language::value_print_inner): Add support for
> >       printing namelist items.
> >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> >
> > gdb/testsuite/ChangeLog:
> >
> >        * gdb.fortran/namelist.exp: New file.
> >        * gdb.fortran/namelist.f90: New file.
> >
> > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8mncjSuCt9BEaGJTnlJ9qp0%2FpFSVvfkVxbe%2FNFrej0%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> >
> > regards,
> > bhuvan
> >
> > Patch inlined:
> >
> > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00 
> > 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist 
> > variables(a fortran feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for 
> > namelist variables and its items. Sample output of these commands is 
> > shared below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> > gdb/ChangeLog                          | 11 +++++++
> > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > gdb/f-valprint.c                       | 10 ++++++
> > gdb/testsuite/ChangeLog                |  5 +++
> > gdb/testsuite/gdb.fortran/namelist.exp | 45 
> > ++++++++++++++++++++++++++
> > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > include/dwarf2.def                     |  2 +-
> > 7 files changed, 134 insertions(+), 7 deletions(-) create mode 
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > 96009f1418f..54528d67498 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >    fp = &new_field->field;
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > +            ! die_is_declaration (die, cu))
>
> The '&&' operator should start the line.
>
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = NULL;
>
> Throughout this patch, please use nullptr instead of NULL.
>
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != NULL)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >        /* Get type of field.  */
> > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >    type = alloc_type (objfile);
> >    INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    INIT_NONE_SPECIFIC (type);
>
> I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
>
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                   struct dwarf2_cu *cu) {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >       should be a DW_TAG_member that is a declaration, but @@ 
> > -15728,7
> > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > struct type *type, }
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >  static void
> > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >      case DW_TAG_union_type:
> >      case DW_TAG_set_type:
> >      case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +         }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >         {
> >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >       && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> >       or simply "<anonymous struct>" or "<anonymous union>" in GCC 
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..8ed35e2fb1f 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >             fputs_filtered (" = ", stream);
> >           }
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
>
> I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
>
> Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
>
>
>
> > +             {
> > +               struct block_symbol symni = lookup_symbol(field_name,
> > +                get_selected_block (0), VAR_DOMAIN, nullptr);
>
> There's a missing space before '(' here, and two lines below.
>
> > +               if (symni.symbol != NULL)
> > +                 field = value_of_variable(symni.symbol, symni.block);
> > +             }
> > +
> >            common_val_print (field, stream, recurse + 1,
> >                      options, current_language); diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..e4df8c7debb
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,45 @@
> > +# Copyright 2020-2021 Free Software Foundation, Inc.
>
> The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
>
> > +
> > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
>
> The pattern should be wrapped onto the newline.
>
> Thanks,
> Andrew
>
> > +} else {
> > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..00704eddf27
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> > DW_AT (DW_AT_priority, 0x45)
> > DW_AT (DW_AT_segment, 0x46)
> > DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> >
>

[-- Attachment #2: 0001-gdb-fortran-Fix-ptype-and-print-commands-for-namelis.patch --]
[-- Type: application/octet-stream, Size: 11751 bytes --]

From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
 variables.

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist
and DW_TAG_namelist_item dies. But gdb does not process these dies and
support namelist variables during print and ptype commands. When tried to
print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist
variables and its items. Sample output of these commands is shared below,
with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         |  2 ++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 132 insertions(+), 8 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index cbd9a3012eb..e6cd8ed48f0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 27d9a730978..6f80b5a12ff 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index dc575c42996..ba8a61987db 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,8 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-11-19 14:09         ` FW: " Kumar N, Bhuvanendra via Gdb-patches
@ 2021-11-19 14:32           ` Kumar N, Bhuvanendra via Gdb-patches
  2021-12-03 18:56             ` Kumar N, Bhuvanendra via Gdb-patches
  2021-12-09 13:16             ` Andrew Burgess via Gdb-patches
  0 siblings, 2 replies; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-11-19 14:32 UTC (permalink / raw)
  To: aburgess
  Cc: Achra, Nitika, Joseph, Ancel, E, Nagajyothi, George, Jini Susan,
	Sharma, Alok Kumar, gdb-patches

[AMD Official Use Only]

Hi Andrew,

Looks like gfortran is emitting DW_TAG_namelist for "nml" twice, hence you are seeing it twice with "info local" command. But clang/flang emits only once, hence I am getting only once with "info local" command.

my GDB command outputs are with clang/flang compiler. Please let me know if you want to try with clang/flang, I can share the details, thanks a lot again

regards,
bhuvan

-----Original Message-----
From: Kumar N, Bhuvanendra 
Sent: Friday, November 19, 2021 7:39 PM
To: 'aburgess@redhat.com' <aburgess@redhat.com>
Cc: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Joseph, Ancel <Ancel.Joseph@amd.com>
Subject: FW: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi Andrew,

Thanks again for the review. Could you please use this revised patch for the review, thanks

I am resending the revised patch now and details are shared just below in this email chain.
I am getting the proper outputs with "info local" as shown below.

Regards,
bhuvan

(gdb) i local
a = 10
b = 20
nml = ( a = 10, b = 20 )
(gdb) pt nml
type = Type nml
    integer :: a
    integer :: b
End Type nml
(gdb) whatis nml
type = Type nml

-----Original Message-----
From: Kumar N, Bhuvanendra
Sent: Friday, October 8, 2021 2:35 AM
To: Andrew Burgess <andrew.burgess@embecosm.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi Andrew,

Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.

thanks,
bhuvan

PATCH inlined:

From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         |  2 ++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,8 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for 
+fortran # namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"] 
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
--
2.17.1


-----Original Message-----
From: Andrew Burgess <andrew.burgess@embecosm.com>
Sent: Wednesday, October 6, 2021 9:22 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:

> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
>
> >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
> Regarding your major comment, I did considered introducing a new type 
> specific field for namelist earlier, instead of using any of those 
> existing. Reason I did not included in my earlier patch was, 
> type_specific_kind is declared with 3 bits in struct main_type and 
> already there were 8 values, hence deferred expanding 
> type_specific_kind etc.... But now I have done that, thanks for the 
> suggestion.

Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.

Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.

I'll need to think about this some more - maybe others have an opinion?

Thanks,
Andrew





>
> Regards,
> bhuvan
>
> PATH inlined:
>
> From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> <Bhuvanendra.KumarN@amd.com>
> Date: Wed, 22 Sep 2021 17:52:15 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> fortran  feature).
>
> GCC/gfortran support namelist(a fortran feature), it emits 
> DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> process these dies and support namelist variables during print and 
> ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist 
> variables and its items. Sample output of these commands is shared 
> below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/ChangeLog                          | 11 ++++++
>  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
>  gdb/f-valprint.c                       | 10 ++++++
>  gdb/gdbtypes.h                         |  3 +-
>  gdb/testsuite/ChangeLog                |  5 +++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49
> ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  8 files changed, 142 insertions(+), 9 deletions(-)  create mode
> 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * dwarf2/read.c (process_die): Add new case for namelist.
> +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> +     (read_structure_type, handle_struct_member_die, new_symbol)
> +     (dwarf2_name): Update.
> +     * f-valprint.c (f_language::value_print_inner): Add support for
> +     printing namelist items.
> +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> +
>  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
>
>       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> 96009f1418f..88db06ec9e7 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, 
> struct die_info *die,
>
>    fp = &new_field->field;
>
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>
>        /* Get type of field.  */
> @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      }
>
>    type = alloc_type (objfile);
> -  INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> +    INIT_CPLUS_SPECIFIC (type);
>
>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                         struct dwarf2_cu *cu)  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>        should be a DW_TAG_member that is a declaration, but @@
> -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info 
> *child_die, struct type *type,  }
>
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>       case DW_TAG_union_type:
>       case DW_TAG_set_type:
>       case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>
>         {
>           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>
> @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>        structures or unions.  These were of the form "._%d" in GCC 4.1,
>        or simply "<anonymous struct>" or "<anonymous union>" in GCC
> 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> 240daaf34f9..aa86fbc901e 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>                 fputs_filtered (" = ", stream);
>               }
>
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> +             {
> +               struct block_symbol symni = lookup_symbol (field_name,
> +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> +               if (symni.symbol != nullptr)
> +                 field = value_of_variable (symni.symbol, symni.block);
> +             }
> +
>             common_val_print (field, stream, recurse + 1,
>                               options, current_language);
>
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index
> 0cc00e74a20..124282c3d53 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -607,6 +607,7 @@ enum type_specific_kind
>    TYPE_SPECIFIC_SELF_TYPE,
>    TYPE_SPECIFIC_INT,
>    TYPE_SPECIFIC_FIXED_POINT,
> +  TYPE_SPECIFIC_NAMELIST,
>  };
>
>  union type_owner
> @@ -833,7 +834,7 @@ struct main_type
>    /* * A discriminant telling us which field of the type_specific
>       union is being used for this type, if any.  */
>
> -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
>
>    /* * Number of fields described for this type.  This field appears
>       at this location because it packs nicely here.  */ diff --git 
> a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * gdb.fortran/namelist.exp: New file.
> +     * gdb.fortran/namelist.f90: New file.
> +
>  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
>
>       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index
> 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
>
>
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Sent: Monday, September 20, 2021 3:11 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan 
> <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi 
> <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> variables(a fortran feature)
>
> [CAUTION: External Email]
>
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
>
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> >
> > Problem description/summary:
> >
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> >
> > Fix details:
> >
> > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> >
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
>
> bhuvan,
>
> Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
>
> Thanks,
> Andrew
>
>
> >
> > gdb/ChangeLog:
> >
> >        * dwarf2/read.c (process_die): Add new case for namelist.
> >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> >        (read_structure_type, handle_struct_member_die, new_symbol)
> >        (dwarf2_name): Update.
> >        * f-valprint.c (f_language::value_print_inner): Add support for
> >       printing namelist items.
> >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> >
> > gdb/testsuite/ChangeLog:
> >
> >        * gdb.fortran/namelist.exp: New file.
> >        * gdb.fortran/namelist.f90: New file.
> >
> > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8mncjSuCt9BEaGJTnlJ9qp0%2FpFSVvfkVxbe%2FNFrej0%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> >
> > regards,
> > bhuvan
> >
> > Patch inlined:
> >
> > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00
> > 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist 
> > variables(a fortran feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for 
> > namelist variables and its items. Sample output of these commands is 
> > shared below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> > gdb/ChangeLog                          | 11 +++++++
> > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > gdb/f-valprint.c                       | 10 ++++++
> > gdb/testsuite/ChangeLog                |  5 +++
> > gdb/testsuite/gdb.fortran/namelist.exp | 45
> > ++++++++++++++++++++++++++
> > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > include/dwarf2.def                     |  2 +-
> > 7 files changed, 134 insertions(+), 7 deletions(-) create mode
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > 96009f1418f..54528d67498 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >    fp = &new_field->field;
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > +            ! die_is_declaration (die, cu))
>
> The '&&' operator should start the line.
>
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = NULL;
>
> Throughout this patch, please use nullptr instead of NULL.
>
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != NULL)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >        /* Get type of field.  */
> > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >    type = alloc_type (objfile);
> >    INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    INIT_NONE_SPECIFIC (type);
>
> I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
>
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                   struct dwarf2_cu *cu) {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >       should be a DW_TAG_member that is a declaration, but @@
> > -15728,7
> > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > struct type *type, }
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >  static void
> > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >      case DW_TAG_union_type:
> >      case DW_TAG_set_type:
> >      case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +         }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >         {
> >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >       && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> >       or simply "<anonymous struct>" or "<anonymous union>" in GCC
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..8ed35e2fb1f 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >             fputs_filtered (" = ", stream);
> >           }
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
>
> I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
>
> Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
>
>
>
> > +             {
> > +               struct block_symbol symni = lookup_symbol(field_name,
> > +                get_selected_block (0), VAR_DOMAIN, nullptr);
>
> There's a missing space before '(' here, and two lines below.
>
> > +               if (symni.symbol != NULL)
> > +                 field = value_of_variable(symni.symbol, symni.block);
> > +             }
> > +
> >            common_val_print (field, stream, recurse + 1,
> >                      options, current_language); diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..e4df8c7debb
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,45 @@
> > +# Copyright 2020-2021 Free Software Foundation, Inc.
>
> The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
>
> > +
> > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
>
> The pattern should be wrapped onto the newline.
>
> Thanks,
> Andrew
>
> > +} else {
> > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..00704eddf27
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> > DW_AT (DW_AT_priority, 0x45)
> > DW_AT (DW_AT_segment, 0x46)
> > DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> >
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-11-19 14:32           ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-12-03 18:56             ` Kumar N, Bhuvanendra via Gdb-patches
  2021-12-04 13:20               ` Joel Brobecker via Gdb-patches
  2021-12-09 13:16             ` Andrew Burgess via Gdb-patches
  1 sibling, 1 reply; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-12-03 18:56 UTC (permalink / raw)
  To: brobecker
  Cc: Achra, Nitika, Andrew Burgess, E, Nagajyothi, George, Jini Susan,
	Sharma, Alok Kumar, gdb-patches

[AMD Official Use Only]

Hi,

Thanks a lot for your reply on this thread. I have observed your reply in the below GDB patches email archive. I did not get any email in my email client(Microsoft outlook) for your email reply, hence I have copy and pasted your reply here and my replies are inlined below. Thanks a lot for your time.

My replies are inlined below with Bhuvan start> and Bhuvan end>. Please bear with me for following such notation only for this time, since I had to copy and paste your reply and reply on top of that, I could not find better method. Also majority of the indentation comments are mostly due to email client related, but I will address all of them. I tried to answer most of your queries and also giving brief introduction to namelist feature. Please let me know if you have more questions about these. 

https://sourceware.org/pipermail/gdb-patches/2021-November/183907.html

Joel Brobecker brobecker@adacore.com
Sat Nov 27 07:56:51 GMT 2021

Hi Bhuvan,

> Gentle PING*4 for the revised patch. Requesting some of you from the
> community to review the updated code patch please, i had addressed all
> the previous review comments.

I'm very sorry for the lack of feedback for this patch. I'll attempt
to help you push this patch through, knowing that I have no knowledge
of Fortran.

I only have time to do code reviews in the weekend, at the moment,
so hopefully others might be able to join in and help. But otherwise,
please bear with me.

> From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
> Date: Fri, 8 Oct 2021 02:01:18 +0530
> Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.
> 
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )

This is a small detail, but typically, for text which is not
a copy/paste of other things like GDB sessions, etc, we try
to keep the length of each line down to something that fits
within an 80-characters terminal. Adding the 4 characters that
commands like "git log" or "git show" indents the commit message
with, would you mind reformatting your explanations to fit within
those 76-characters per line, please?

Also, for those who are not familiar with Fortran, I think it would
be useful to have a small introduction to that feature that goes
beyond a bit of Fortran code in a testcase, and how GDB is proposed
to show it. I'd like to understand what they mean semantically,
how those are typically used, and how they are stored in memory
(to understand how they work). This will help me better review
this change.

Can you provide that kind of info?

Bhuvan start>

Sample program:
1       program main
2
3         integer :: a, b
4         namelist /nml/ a, b
5
6         a = 10
7         b = 20
8         Write(*,nml)
9
10      end program main

Output of this program:
$ ./out
 &NML
 A =           10,
 B =           20
 /

Namelist is a group of variables or arrays that can be read or written. 

Namelist syntax: NAMELIST / groupname / namelist_items  ...

NAMELIST statement assign a group name to a collection of variables. Here in this example namelist is a group of 2 integer variables a and b, these are called namelist items. The group name is nml. The namelist items can be of any data type and can be variables or arrays. More details are shared below.

dwarfdump of an gfortran emitted binary : compilers emit DW_TAG_namelist for group name and DW_TAG_namelist_item for namelist items as shown below for the above sample program. GDB needs to process these namelist dies and support namelist variables printing with print and ptype commands. 
. . .
0x000000b4:     DW_TAG_variable [10]
                  DW_AT_name [DW_FORM_string]   ("a")
                  DW_AT_decl_file [DW_FORM_data1]       ("/home/bhuvan/work/fortran/test/3180/n2.f90")
                  DW_AT_decl_line [DW_FORM_data1]       (20)
                  DW_AT_type [DW_FORM_ref4]     (cu + 0x006d => {0x0000006d} "integer(kind=4)")
                  DW_AT_declaration [DW_FORM_flag_present]      (true)
                  DW_AT_location [DW_FORM_exprloc]      (DW_OP_fbreg -20)
 
0x000000c0:     DW_TAG_variable [10]
                  DW_AT_name [DW_FORM_string]   ("b")
                  DW_AT_decl_file [DW_FORM_data1]       ("/home/bhuvan/work/fortran/test/3180/n2.f90")
                  DW_AT_decl_line [DW_FORM_data1]       (20)
                  DW_AT_type [DW_FORM_ref4]     (cu + 0x006d => {0x0000006d} "integer(kind=4)")
                  DW_AT_declaration [DW_FORM_flag_present]      (true)
                  DW_AT_location [DW_FORM_exprloc]      (DW_OP_fbreg -24)
. . .
0x000000dd:     DW_TAG_namelist [12] *
                  DW_AT_name [DW_FORM_string]   ("nml")
 
0x000000e2:       DW_TAG_namelist_item [9]
                    DW_AT_namelist_item [DW_FORM_ref4]  (cu + 0x00b4 => {0x000000b4})
 
0x000000e7:       DW_TAG_namelist_item [9]
                    DW_AT_namelist_item [DW_FORM_ref4]  (cu + 0x00c0 => {0x000000c0})
 
0x000000ec:       NULL

Bhuvan end>

> ---
>  gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
>  gdb/f-typeprint.c                      |  6 +++-
>  gdb/f-valprint.c                       | 11 ++++++
>  gdb/gdbtypes.h                         |  2 ++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
>  
>    fp = &new_field->field;
>  
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))

The indentation is incorrect. The "&&" opeator should line up
with the indentation of the condition expression. Thus:

> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +      && ! die_is_declaration (die, cu))

> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */

Can you explain why, and put that information in the comment?

Bhuvan start>
As shown in the above sample dwarf dump, DW_TAG_namelist_item points or refers to actual variable die thru DW_FORM_ref4, hence we need to use the referenced die.
Bhuvan end>

Also, this is only a minor comment that you don't have to agree with,
but FWIW, when I read your comment, I intuitively thought that
namelist items were always references. On the other hand, reading
the code itself, it doesn't appear to be so.

> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */

I think it would be better if you kept that comment at the start
of the if block, so above your special handling of DW_TAG_namelist_item.

>        /* Get type of field.  */
> @@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      {
>        type->set_code (TYPE_CODE_UNION);
>      }
> +  else if (die->tag == DW_TAG_namelist)
> +    {
> +      type->set_code (TYPE_CODE_NAMELIST);
> +    }
>    else
>      {
>        type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>  			  struct dwarf2_cu *cu)
>  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>  	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
>  
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>  
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>  	case DW_TAG_union_type:
>  	case DW_TAG_set_type:
>  	case DW_TAG_enumeration_type:
> -	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +	case DW_TAG_namelist:
> +	  if (die->tag == DW_TAG_namelist)
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +	  else
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }

I have to say, I'm a little uncomfortable with this part of
the change -- perhaps simply because I don't understand it.
Does it make sense to handle DW_TAG_namelist here? This second
handles a group of *types*, wheres the change suggests that
namelist are more like *variables*. Should the two be handled
at the same place? What made you pick this part of the code
to insert support for DW_TAG_namelist?  Or am I misunderstanding
the concept of namelists (which brings me back to the question
at the beginning)?

Bhuvan start>
DW_TAG_namelist are similar to DW_TAG_structure_type or DW_TAG_union_type, hence I have placed them here. Basically namelist variable nml (in the above sample program) is a group of items a and b. please note a and b are declared before only and storage is allocated as part of that. For namelist items (a and b), there is no separate storage gets created or allocated, same storage is used/referenced. DW_TAG_namelist_item points to the original variable die. Hence namelist is just a group of such items. Main advantage of these namelist is that they can be used for I/O and they cannot be categorized strictly as type only, hence namelists are handled at the same place as that of DW_TAG_structure_type, but since they can be used with I/O statements (which is the main advantage of using namelist in fortran), I have categorized them as VAR_DOMAIN, so that I can use it during print command as well inside GDB. 
Hence namelist cannot be categorized as type only feature, it's a combination of type and variable, if we want to put it this way. 
I have used a separate type (TYPE_CODE_NAMELIST) for namelist after Andrew suggestion.
Bhuvan end>

>  	  {
>  	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>  
> @@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>  	 structures or unions.  These were of the form "._%d" in GCC 4.1,
>  	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
> --- a/gdb/f-typeprint.c
> +++ b/gdb/f-typeprint.c
> @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>        const char *prefix = "";
>        if (type->code () == TYPE_CODE_UNION)
>  	prefix = "Type, C_Union :: ";
> -      else if (type->code () == TYPE_CODE_STRUCT)
> +      else if (type->code () == TYPE_CODE_STRUCT
> +               || type->code () == TYPE_CODE_NAMELIST)
>  	prefix = "Type ";
>        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
>        return;
> @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>  
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        if (type->code () == TYPE_CODE_UNION)
>  	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
>        else
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>  
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        /* Starting from the Fortran 90 standard, Fortran supports derived
>  	 types.  */
>        fprintf_filtered (stream, "( ");
> @@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>  		  fputs_filtered (" = ", stream);
>  		}
>  
> +	      /* While printing namelist items, fetch the appropriate value
> +	         field before printing its value.  */
> +	      if (type->code () == TYPE_CODE_NAMELIST)
> +	        {
> +	          struct block_symbol symni = lookup_symbol (field_name,
> +			get_selected_block (0), VAR_DOMAIN, nullptr);

Can you fix the indentation here, please? On the second line,
the start of the parameters should be aligned with the start
of the parameters on the lines above. Also, remember that indentation
is 2 characters, not 4. You could have...

  struct block_symbol symni = lookup_symbol (field_name,
                                             get_selected_block (0),
                                             VAR_DOMAIN, nullptr);

  ... or (one parameter per line) ...

  struct block_symbol symni = lookup_symbol (field_name,
                                             get_selected_block (0),
                                             VAR_DOMAIN,
                                             nullptr);

  ... or move all the parameters on the next line, with:

  struct block_symbol symni = lookup_symbol
    (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);

> +	          if (symni.symbol != nullptr)
> +	            field = value_of_variable (symni.symbol, symni.block);
> +	        }
> +
>  	      common_val_print (field, stream, recurse + 1,
>  				options, current_language);
>  
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -195,6 +195,8 @@ enum type_code
>  
>      /* * Fixed Point type.  */
>      TYPE_CODE_FIXED_POINT,
> +
> +    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */

In terms of documenting the enumerate, can you use the same style
as the other enums? This is actually important, because I believe
this is to allow us to use Doxygen to generate documentation (something
we may not have done for a while, but I'd rather we don't make it
worse).

>  
>  /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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/>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.

I think there are trailing spaces at the end of several lines above.
While at it, would you mind please removing them all?
Or, actually, given the above, I'm wondering if this wasn't caused
by your mailer making some reformatting changes..

> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.

Same request as in the commit message: It would be nice if we could
keep the code and comments without 80-characters whenever reasonable.

> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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/>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1

-----Original Message-----
From: Kumar N, Bhuvanendra 
Sent: Friday, November 19, 2021 8:03 PM
To: aburgess@redhat.com
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Joseph, Ancel <Ancel.Joseph@amd.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi Andrew,

Looks like gfortran is emitting DW_TAG_namelist for "nml" twice, hence you are seeing it twice with "info local" command. But clang/flang emits only once, hence I am getting only once with "info local" command.

my GDB command outputs are with clang/flang compiler. Please let me know if you want to try with clang/flang, I can share the details, thanks a lot again

regards,
bhuvan

-----Original Message-----
From: Kumar N, Bhuvanendra
Sent: Friday, November 19, 2021 7:39 PM
To: 'aburgess@redhat.com' <aburgess@redhat.com>
Cc: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Joseph, Ancel <Ancel.Joseph@amd.com>
Subject: FW: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi Andrew,

Thanks again for the review. Could you please use this revised patch for the review, thanks

I am resending the revised patch now and details are shared just below in this email chain.
I am getting the proper outputs with "info local" as shown below.

Regards,
bhuvan

(gdb) i local
a = 10
b = 20
nml = ( a = 10, b = 20 )
(gdb) pt nml
type = Type nml
    integer :: a
    integer :: b
End Type nml
(gdb) whatis nml
type = Type nml

-----Original Message-----
From: Kumar N, Bhuvanendra
Sent: Friday, October 8, 2021 2:35 AM
To: Andrew Burgess <andrew.burgess@embecosm.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi Andrew,

Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.

thanks,
bhuvan

PATCH inlined:

From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.

GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.
This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         |  2 ++
 gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+            && ! die_is_declaration (die, cu))
+    {
+      /* For the DW_TAG_namelist_item die, use the referenced die.  */
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol (field_name,
+			get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,8 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..90762928455
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,49 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for 
+fortran # namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"] 
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
--
2.17.1


-----Original Message-----
From: Andrew Burgess <andrew.burgess@embecosm.com>
Sent: Wednesday, October 6, 2021 9:22 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:

> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
>
> >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
> Regarding your major comment, I did considered introducing a new type 
> specific field for namelist earlier, instead of using any of those 
> existing. Reason I did not included in my earlier patch was, 
> type_specific_kind is declared with 3 bits in struct main_type and 
> already there were 8 values, hence deferred expanding 
> type_specific_kind etc.... But now I have done that, thanks for the 
> suggestion.

Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.

Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.

I'll need to think about this some more - maybe others have an opinion?

Thanks,
Andrew





>
> Regards,
> bhuvan
>
> PATH inlined:
>
> From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> <Bhuvanendra.KumarN@amd.com>
> Date: Wed, 22 Sep 2021 17:52:15 +0530
> Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> fortran  feature).
>
> GCC/gfortran support namelist(a fortran feature), it emits 
> DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> process these dies and support namelist variables during print and 
> ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist 
> variables and its items. Sample output of these commands is shared 
> below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/ChangeLog                          | 11 ++++++
>  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
>  gdb/f-valprint.c                       | 10 ++++++
>  gdb/gdbtypes.h                         |  3 +-
>  gdb/testsuite/ChangeLog                |  5 +++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49
> ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  8 files changed, 142 insertions(+), 9 deletions(-)  create mode
> 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> 36cb4c9e7e9..ec01c2957e9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,14 @@
> +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * dwarf2/read.c (process_die): Add new case for namelist.
> +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> +     (read_structure_type, handle_struct_member_die, new_symbol)
> +     (dwarf2_name): Update.
> +     * f-valprint.c (f_language::value_print_inner): Add support for
> +     printing namelist items.
> +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> +
>  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
>
>       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> 96009f1418f..88db06ec9e7 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, 
> struct die_info *die,
>
>    fp = &new_field->field;
>
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>
>        /* Get type of field.  */
> @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      }
>
>    type = alloc_type (objfile);
> -  INIT_CPLUS_SPECIFIC (type);
> +  if (die->tag == DW_TAG_namelist)
> +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> +    INIT_CPLUS_SPECIFIC (type);
>
>    name = dwarf2_name (die, cu);
>    if (name != NULL)
> @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                         struct dwarf2_cu *cu)  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>        should be a DW_TAG_member that is a declaration, but @@
> -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info 
> *child_die, struct type *type,  }
>
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>       case DW_TAG_union_type:
>       case DW_TAG_set_type:
>       case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>
>         {
>           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>
> @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>        structures or unions.  These were of the form "._%d" in GCC 4.1,
>        or simply "<anonymous struct>" or "<anonymous union>" in GCC
> 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> 240daaf34f9..aa86fbc901e 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>                 fputs_filtered (" = ", stream);
>               }
>
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> +             {
> +               struct block_symbol symni = lookup_symbol (field_name,
> +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> +               if (symni.symbol != nullptr)
> +                 field = value_of_variable (symni.symbol, symni.block);
> +             }
> +
>             common_val_print (field, stream, recurse + 1,
>                               options, current_language);
>
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index
> 0cc00e74a20..124282c3d53 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -607,6 +607,7 @@ enum type_specific_kind
>    TYPE_SPECIFIC_SELF_TYPE,
>    TYPE_SPECIFIC_INT,
>    TYPE_SPECIFIC_FIXED_POINT,
> +  TYPE_SPECIFIC_NAMELIST,
>  };
>
>  union type_owner
> @@ -833,7 +834,7 @@ struct main_type
>    /* * A discriminant telling us which field of the type_specific
>       union is being used for this type, if any.  */
>
> -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
>
>    /* * Number of fields described for this type.  This field appears
>       at this location because it packs nicely here.  */ diff --git 
> a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> 87cf3e2a061..33f60c29b3c 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> +
> +     * gdb.fortran/namelist.exp: New file.
> +     * gdb.fortran/namelist.f90: New file.
> +
>  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
>
>       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index
> 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
>
>
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Sent: Monday, September 20, 2021 3:11 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan 
> <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi 
> <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> variables(a fortran feature)
>
> [CAUTION: External Email]
>
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
>
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> >
> > Problem description/summary:
> >
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> >
> > Fix details:
> >
> > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> >
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
>
> bhuvan,
>
> Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
>
> Thanks,
> Andrew
>
>
> >
> > gdb/ChangeLog:
> >
> >        * dwarf2/read.c (process_die): Add new case for namelist.
> >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> >        (read_structure_type, handle_struct_member_die, new_symbol)
> >        (dwarf2_name): Update.
> >        * f-valprint.c (f_language::value_print_inner): Add support for
> >       printing namelist items.
> >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> >
> > gdb/testsuite/ChangeLog:
> >
> >        * gdb.fortran/namelist.exp: New file.
> >        * gdb.fortran/namelist.f90: New file.
> >
> > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8mncjSuCt9BEaGJTnlJ9qp0%2FpFSVvfkVxbe%2FNFrej0%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> >
> > regards,
> > bhuvan
> >
> > Patch inlined:
> >
> > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00
> > 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist 
> > variables(a fortran feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for 
> > namelist variables and its items. Sample output of these commands is 
> > shared below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> > gdb/ChangeLog                          | 11 +++++++
> > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > gdb/f-valprint.c                       | 10 ++++++
> > gdb/testsuite/ChangeLog                |  5 +++
> > gdb/testsuite/gdb.fortran/namelist.exp | 45
> > ++++++++++++++++++++++++++
> > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > include/dwarf2.def                     |  2 +-
> > 7 files changed, 134 insertions(+), 7 deletions(-) create mode
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > 96009f1418f..54528d67498 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >    fp = &new_field->field;
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > +            ! die_is_declaration (die, cu))
>
> The '&&' operator should start the line.
>
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = NULL;
>
> Throughout this patch, please use nullptr instead of NULL.
>
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != NULL)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >        /* Get type of field.  */
> > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >    type = alloc_type (objfile);
> >    INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    INIT_NONE_SPECIFIC (type);
>
> I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
>
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                   struct dwarf2_cu *cu) {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >       should be a DW_TAG_member that is a declaration, but @@
> > -15728,7
> > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > struct type *type, }
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >  static void
> > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >      case DW_TAG_union_type:
> >      case DW_TAG_set_type:
> >      case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +         }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >         {
> >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >       && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> >       or simply "<anonymous struct>" or "<anonymous union>" in GCC
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..8ed35e2fb1f 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >             fputs_filtered (" = ", stream);
> >           }
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
>
> I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
>
> Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
>
>
>
>
> > +             {
> > +               struct block_symbol symni = lookup_symbol(field_name,
> > +                get_selected_block (0), VAR_DOMAIN, nullptr);
>
> There's a missing space before '(' here, and two lines below.
>
> > +               if (symni.symbol != NULL)
> > +                 field = value_of_variable(symni.symbol, symni.block);
> > +             }
> > +
> >            common_val_print (field, stream, recurse + 1,
> >                      options, current_language); diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N
> > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..e4df8c7debb
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,45 @@
> > +# Copyright 2020-2021 Free Software Foundation, Inc.
>
> The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
>
> > +
> > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
>
> The pattern should be wrapped onto the newline.
>
> Thanks,
> Andrew
>
> > +} else {
> > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..00704eddf27
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> > DW_AT (DW_AT_priority, 0x45)
> > DW_AT (DW_AT_segment, 0x46)
> > DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> >
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-12-03 18:56             ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-12-04 13:20               ` Joel Brobecker via Gdb-patches
  2021-12-10 16:18                 ` Kumar N, Bhuvanendra via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Joel Brobecker via Gdb-patches @ 2021-12-04 13:20 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: Achra, Nitika, Andrew Burgess, E, Nagajyothi, brobecker, George,
	Jini Susan, Sharma, Alok Kumar, gdb-patches

> Thanks a lot for your reply on this thread. I have observed your reply
> in the below GDB patches email archive.

This is because the email as received on this mailing-list did not
have the From field set to your email address, but rather the
mailing-list's address. I don't know when this happens, and why
it does happen, but I've observed a number of such emails have
that "Name of contributor via gdb-patches <gdb-patches@xxx>"
sender email instead of the original sender's email. When that
happened, my reply-all did not include you.

I've added comments (see below).

I'll wait for a new version of this patch which hopefully address
all my comments.

> My replies are inlined below with Bhuvan start> and Bhuvan end>.
> Please bear with me for following such notation only for this time,
> since I had to copy and paste your reply and reply on top of that, I
> could not find better method. Also majority of the indentation
> comments are mostly due to email client related, but I will address
> all of them. I tried to answer most of your queries and also giving
> brief introduction to namelist feature. Please let me know if you have
> more questions about these. 
> 
> https://sourceware.org/pipermail/gdb-patches/2021-November/183907.html
> 
> Joel Brobecker brobecker@adacore.com
> Sat Nov 27 07:56:51 GMT 2021
> 
> Hi Bhuvan,
> 
> > Gentle PING*4 for the revised patch. Requesting some of you from the
> > community to review the updated code patch please, i had addressed all
> > the previous review comments.
> 
> I'm very sorry for the lack of feedback for this patch. I'll attempt
> to help you push this patch through, knowing that I have no knowledge
> of Fortran.
> 
> I only have time to do code reviews in the weekend, at the moment,
> so hopefully others might be able to join in and help. But otherwise,
> please bear with me.
> 
> > From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
> > Date: Fri, 8 Oct 2021 02:01:18 +0530
> > Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.
> > 
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> 
> This is a small detail, but typically, for text which is not
> a copy/paste of other things like GDB sessions, etc, we try
> to keep the length of each line down to something that fits
> within an 80-characters terminal. Adding the 4 characters that
> commands like "git log" or "git show" indents the commit message
> with, would you mind reformatting your explanations to fit within
> those 76-characters per line, please?
> 
> Also, for those who are not familiar with Fortran, I think it would
> be useful to have a small introduction to that feature that goes
> beyond a bit of Fortran code in a testcase, and how GDB is proposed
> to show it. I'd like to understand what they mean semantically,
> how those are typically used, and how they are stored in memory
> (to understand how they work). This will help me better review
> this change.
> 
> Can you provide that kind of info?
> 
> Bhuvan start>
Thanks, this is much clear for me, now. I think it might be useful
to have that information available as a comment in the code,
for those of us who aren't familiar with Fortran. I tried to think
of a place where we could add this information, and I propose we do
this at the location where we document the new TYPE_CODE_NAMELIST
enum. I would use the comment to provide the very quick introduction
to namelists you provides, and also a short summary of how they can
be described using DWARF (I wouldn't go as far as dumping the whole
DWARF debug info, as this is a bit over the top).


> Bhuvan end>
> 
> > ---
> >  gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
> >  gdb/f-typeprint.c                      |  6 +++-
> >  gdb/f-valprint.c                       | 11 ++++++
> >  gdb/gdbtypes.h                         |  2 ++
> >  gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
> >  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
> >  include/dwarf2.def                     |  2 +-
> >  7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
> >  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> > 
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >  
> >    fp = &new_field->field;
> >  
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> > +            && ! die_is_declaration (die, cu))
> 
> The indentation is incorrect. The "&&" opeator should line up
> with the indentation of the condition expression. Thus:
> 
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> > +      && ! die_is_declaration (die, cu))
> 
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> 
> Can you explain why, and put that information in the comment?
> 
> Bhuvan start>
> As shown in the above sample dwarf dump, DW_TAG_namelist_item points or refers to actual variable die thru DW_FORM_ref4, hence we need to use the referenced die.
> Bhuvan end>

Thank you for the explanation. Given your answer above, and the
associated comment below:
> 
> Also, this is only a minor comment that you don't have to agree with,
> but FWIW, when I read your comment, I intuitively thought that
> namelist items were always references. On the other hand, reading
> the code itself, it doesn't appear to be so.

... I propose you move the comment inside the the following
"if" block...

> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = nullptr;
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != nullptr)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */

... and make that comment a little more conditional, like so:

     if (die->tag == DW_TAG_namelist_item)
       {
         /* Typically, DW_TAG_namelist_item are references to XXX.
            If so, follow that reference.  */
         [...]
       }

Logically, I undesrtand now why items of your nameslists are references
to other entities, but perhaps this is not an absolute necessity?
Otherwise, why did you feel it was worth verifying this before following
the reference link?

This is a bit minor, but at the same time, I find that it's important to
provide good and clear comments, and they often impact heavily on how
quickly one can understand (or misunderstand) the code.

> 
> I think it would be better if you kept that comment at the start
> of the if block, so above your special handling of DW_TAG_namelist_item.
> 
> >        /* Get type of field.  */
> > @@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >      {
> >        type->set_code (TYPE_CODE_UNION);
> >      }
> > +  else if (die->tag == DW_TAG_namelist)
> > +    {
> > +      type->set_code (TYPE_CODE_NAMELIST);
> > +    }
> >    else
> >      {
> >        type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >  			  struct dwarf2_cu *cu)
> >  {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >  	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
> >  
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >  
> >  static void
> >  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >  	case DW_TAG_union_type:
> >  	case DW_TAG_set_type:
> >  	case DW_TAG_enumeration_type:
> > -	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +	case DW_TAG_namelist:
> > +	  if (die->tag == DW_TAG_namelist)
> > +            {
> > +	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +            }
> > +	  else
> > +            {
> > +	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> 
> I have to say, I'm a little uncomfortable with this part of
> the change -- perhaps simply because I don't understand it.
> Does it make sense to handle DW_TAG_namelist here? This second
> handles a group of *types*, wheres the change suggests that
> namelist are more like *variables*. Should the two be handled
> at the same place? What made you pick this part of the code
> to insert support for DW_TAG_namelist?  Or am I misunderstanding
> the concept of namelists (which brings me back to the question
> at the beginning)?
> 
> Bhuvan start>
> DW_TAG_namelist are similar to DW_TAG_structure_type or DW_TAG_union_type, hence I have placed them here. Basically namelist variable nml (in the above sample program) is a group of items a and b. please note a and b are declared before only and storage is allocated as part of that. For namelist items (a and b), there is no separate storage gets created or allocated, same storage is used/referenced. DW_TAG_namelist_item points to the original variable die. Hence namelist is just a group of such items. Main advantage of these namelist is that they can be used for I/O and they cannot be categorized strictly as type only, hence namelists are handled at the same place as that of DW_TAG_structure_type, but since they can be used with I/O statements (which is the main advantage of using namelist in fortran), I have categorized them as VAR_DOMAIN, so that I can use it during print command as well inside GDB. 
> Hence namelist cannot be categorized as type only feature, it's a combination of type and variable, if we want to put it this way. 
> I have used a separate type (TYPE_CODE_NAMELIST) for namelist after Andrew suggestion.
> Bhuvan end>

OK. Let's go with your approach.

> 
> >  	  {
> >  	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >        && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> >  
> > @@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >  	 structures or unions.  These were of the form "._%d" in GCC 4.1,
> >  	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
> > --- a/gdb/f-typeprint.c
> > +++ b/gdb/f-typeprint.c
> > @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
> >      case TYPE_CODE_UNDEF:
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >      case TYPE_CODE_ENUM:
> >      case TYPE_CODE_INT:
> >      case TYPE_CODE_FLT:
> > @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
> >      case TYPE_CODE_UNDEF:
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >      case TYPE_CODE_ENUM:
> >      case TYPE_CODE_INT:
> >      case TYPE_CODE_FLT:
> > @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
> >        const char *prefix = "";
> >        if (type->code () == TYPE_CODE_UNION)
> >  	prefix = "Type, C_Union :: ";
> > -      else if (type->code () == TYPE_CODE_STRUCT)
> > +      else if (type->code () == TYPE_CODE_STRUCT
> > +               || type->code () == TYPE_CODE_NAMELIST)
> >  	prefix = "Type ";
> >        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
> >        return;
> > @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
> >  
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >        if (type->code () == TYPE_CODE_UNION)
> >  	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
> >        else
> > diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >  
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >        /* Starting from the Fortran 90 standard, Fortran supports derived
> >  	 types.  */
> >        fprintf_filtered (stream, "( ");
> > @@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >  		  fputs_filtered (" = ", stream);
> >  		}
> >  
> > +	      /* While printing namelist items, fetch the appropriate value
> > +	         field before printing its value.  */
> > +	      if (type->code () == TYPE_CODE_NAMELIST)
> > +	        {
> > +	          struct block_symbol symni = lookup_symbol (field_name,
> > +			get_selected_block (0), VAR_DOMAIN, nullptr);
> 
> Can you fix the indentation here, please? On the second line,
> the start of the parameters should be aligned with the start
> of the parameters on the lines above. Also, remember that indentation
> is 2 characters, not 4. You could have...
> 
>   struct block_symbol symni = lookup_symbol (field_name,
>                                              get_selected_block (0),
>                                              VAR_DOMAIN, nullptr);
> 
>   ... or (one parameter per line) ...
> 
>   struct block_symbol symni = lookup_symbol (field_name,
>                                              get_selected_block (0),
>                                              VAR_DOMAIN,
>                                              nullptr);
> 
>   ... or move all the parameters on the next line, with:
> 
>   struct block_symbol symni = lookup_symbol
>     (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);
> 
> > +	          if (symni.symbol != nullptr)
> > +	            field = value_of_variable (symni.symbol, symni.block);
> > +	        }
> > +
> >  	      common_val_print (field, stream, recurse + 1,
> >  				options, current_language);
> >  
> > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
> > --- a/gdb/gdbtypes.h
> > +++ b/gdb/gdbtypes.h
> > @@ -195,6 +195,8 @@ enum type_code
> >  
> >      /* * Fixed Point type.  */
> >      TYPE_CODE_FIXED_POINT,
> > +
> > +    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
> 
> In terms of documenting the enumerate, can you use the same style
> as the other enums? This is actually important, because I believe
> this is to allow us to use Doxygen to generate documentation (something
> we may not have done for a while, but I'd rather we don't make it
> worse).
> 
> >  
> >  /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..90762928455
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,49 @@
> > +# Copyright (C) 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/>.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> 
> I think there are trailing spaces at the end of several lines above.
> While at it, would you mind please removing them all?
> Or, actually, given the above, I'm wondering if this wasn't caused
> by your mailer making some reformatting changes..
> 
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> 
> Same request as in the commit message: It would be nice if we could
> keep the code and comments without 80-characters whenever reasonable.
> 
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" \
> > +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \
> > +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> > +} else {
> > +    gdb_test "ptype nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..fb36690d765
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright (C) 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/>.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> >  DW_AT (DW_AT_priority, 0x45)
> >  DW_AT (DW_AT_segment, 0x46)
> >  DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> 
> -----Original Message-----
> From: Kumar N, Bhuvanendra 
> Sent: Friday, November 19, 2021 8:03 PM
> To: aburgess@redhat.com
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Joseph, Ancel <Ancel.Joseph@amd.com>
> Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
> 
> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> Looks like gfortran is emitting DW_TAG_namelist for "nml" twice, hence you are seeing it twice with "info local" command. But clang/flang emits only once, hence I am getting only once with "info local" command.
> 
> my GDB command outputs are with clang/flang compiler. Please let me know if you want to try with clang/flang, I can share the details, thanks a lot again
> 
> regards,
> bhuvan
> 
> -----Original Message-----
> From: Kumar N, Bhuvanendra
> Sent: Friday, November 19, 2021 7:39 PM
> To: 'aburgess@redhat.com' <aburgess@redhat.com>
> Cc: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Joseph, Ancel <Ancel.Joseph@amd.com>
> Subject: FW: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
> 
> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> Thanks again for the review. Could you please use this revised patch for the review, thanks
> 
> I am resending the revised patch now and details are shared just below in this email chain.
> I am getting the proper outputs with "info local" as shown below.
> 
> Regards,
> bhuvan
> 
> (gdb) i local
> a = 10
> b = 20
> nml = ( a = 10, b = 20 )
> (gdb) pt nml
> type = Type nml
>     integer :: a
>     integer :: b
> End Type nml
> (gdb) whatis nml
> type = Type nml
> 
> -----Original Message-----
> From: Kumar N, Bhuvanendra
> Sent: Friday, October 8, 2021 2:35 AM
> To: Andrew Burgess <andrew.burgess@embecosm.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
> 
> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.
> 
> thanks,
> bhuvan
> 
> PATCH inlined:
> 
> From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
> Date: Fri, 8 Oct 2021 02:01:18 +0530
> Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.
> 
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
>  gdb/f-typeprint.c                      |  6 +++-
>  gdb/f-valprint.c                       | 11 ++++++
>  gdb/gdbtypes.h                         |  2 ++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
>  
>    fp = &new_field->field;
>  
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>  
>        /* Get type of field.  */
> @@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      {
>        type->set_code (TYPE_CODE_UNION);
>      }
> +  else if (die->tag == DW_TAG_namelist)
> +    {
> +      type->set_code (TYPE_CODE_NAMELIST);
> +    }
>    else
>      {
>        type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>  			  struct dwarf2_cu *cu)
>  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>  	 should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
>  
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>  
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>  	case DW_TAG_union_type:
>  	case DW_TAG_set_type:
>  	case DW_TAG_enumeration_type:
> -	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +	case DW_TAG_namelist:
> +	  if (die->tag == DW_TAG_namelist)
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +	  else
> +            {
> +	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>  
>  	  {
>  	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>  
> @@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>  	 structures or unions.  These were of the form "._%d" in GCC 4.1,
>  	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
> --- a/gdb/f-typeprint.c
> +++ b/gdb/f-typeprint.c
> @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>        const char *prefix = "";
>        if (type->code () == TYPE_CODE_UNION)
>  	prefix = "Type, C_Union :: ";
> -      else if (type->code () == TYPE_CODE_STRUCT)
> +      else if (type->code () == TYPE_CODE_STRUCT
> +               || type->code () == TYPE_CODE_NAMELIST)
>  	prefix = "Type ";
>        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
>        return;
> @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>  
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        if (type->code () == TYPE_CODE_UNION)
>  	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
>        else
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>  
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        /* Starting from the Fortran 90 standard, Fortran supports derived
>  	 types.  */
>        fprintf_filtered (stream, "( ");
> @@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>  		  fputs_filtered (" = ", stream);
>  		}
>  
> +	      /* While printing namelist items, fetch the appropriate value
> +	         field before printing its value.  */
> +	      if (type->code () == TYPE_CODE_NAMELIST)
> +	        {
> +	          struct block_symbol symni = lookup_symbol (field_name,
> +			get_selected_block (0), VAR_DOMAIN, nullptr);
> +	          if (symni.symbol != nullptr)
> +	            field = value_of_variable (symni.symbol, symni.block);
> +	        }
> +
>  	      common_val_print (field, stream, recurse + 1,
>  				options, current_language);
>  
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -195,6 +195,8 @@ enum type_code
>  
>      /* * Fixed Point type.  */
>      TYPE_CODE_FIXED_POINT,
> +
> +    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
>    };
>  
>  /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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/>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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/>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
> 
> 
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Sent: Wednesday, October 6, 2021 9:22 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
> 
> [CAUTION: External Email]
> 
> * Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:
> 
> > [AMD Official Use Only]
> >
> > Hi Andrew,
> >
> > Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
> >
> > >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> > >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> >
> > Regarding your major comment, I did considered introducing a new type 
> > specific field for namelist earlier, instead of using any of those 
> > existing. Reason I did not included in my earlier patch was, 
> > type_specific_kind is declared with 3 bits in struct main_type and 
> > already there were 8 values, hence deferred expanding 
> > type_specific_kind etc.... But now I have done that, thanks for the 
> > suggestion.
> 
> Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.
> 
> Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.
> 
> I'll need to think about this some more - maybe others have an opinion?
> 
> Thanks,
> Andrew
> 
> 
> 
> 
> 
> >
> > Regards,
> > bhuvan
> >
> > PATH inlined:
> >
> > From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > <Bhuvanendra.KumarN@amd.com>
> > Date: Wed, 22 Sep 2021 17:52:15 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist variables(a 
> > fortran  feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits 
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > process these dies and support namelist variables during print and 
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for namelist 
> > variables and its items. Sample output of these commands is shared 
> > below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> >  gdb/ChangeLog                          | 11 ++++++
> >  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
> >  gdb/f-valprint.c                       | 10 ++++++
> >  gdb/gdbtypes.h                         |  3 +-
> >  gdb/testsuite/ChangeLog                |  5 +++
> >  gdb/testsuite/gdb.fortran/namelist.exp | 49
> > ++++++++++++++++++++++++++
> >  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
> >  include/dwarf2.def                     |  2 +-
> >  8 files changed, 142 insertions(+), 9 deletions(-)  create mode
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> >  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> >  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
> >
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > 96009f1418f..88db06ec9e7 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, 
> > struct die_info *die,
> >
> >    fp = &new_field->field;
> >
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> > +            && ! die_is_declaration (die, cu))
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = nullptr;
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != nullptr)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >
> >        /* Get type of field.  */
> > @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >      }
> >
> >    type = alloc_type (objfile);
> > -  INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> > +    INIT_CPLUS_SPECIFIC (type);
> >
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                         struct dwarf2_cu *cu)  {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >        should be a DW_TAG_member that is a declaration, but @@
> > -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info 
> > *child_die, struct type *type,  }
> >
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >
> >  static void
> >  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >       case DW_TAG_union_type:
> >       case DW_TAG_set_type:
> >       case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +            }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >
> >         {
> >           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >        && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> >
> > @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >        structures or unions.  These were of the form "._%d" in GCC 4.1,
> >        or simply "<anonymous struct>" or "<anonymous union>" in GCC
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > 240daaf34f9..aa86fbc901e 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >                 fputs_filtered (" = ", stream);
> >               }
> >
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> > +             {
> > +               struct block_symbol symni = lookup_symbol (field_name,
> > +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> > +               if (symni.symbol != nullptr)
> > +                 field = value_of_variable (symni.symbol, symni.block);
> > +             }
> > +
> >             common_val_print (field, stream, recurse + 1,
> >                               options, current_language);
> >
> > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index
> > 0cc00e74a20..124282c3d53 100644
> > --- a/gdb/gdbtypes.h
> > +++ b/gdb/gdbtypes.h
> > @@ -607,6 +607,7 @@ enum type_specific_kind
> >    TYPE_SPECIFIC_SELF_TYPE,
> >    TYPE_SPECIFIC_INT,
> >    TYPE_SPECIFIC_FIXED_POINT,
> > +  TYPE_SPECIFIC_NAMELIST,
> >  };
> >
> >  union type_owner
> > @@ -833,7 +834,7 @@ struct main_type
> >    /* * A discriminant telling us which field of the type_specific
> >       union is being used for this type, if any.  */
> >
> > -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> > +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
> >
> >    /* * Number of fields described for this type.  This field appears
> >       at this location because it packs nicely here.  */ diff --git 
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> >  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> >
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..90762928455
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,49 @@
> > +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for 
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" \
> > +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \
> > +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> > +} else {
> > +    gdb_test "ptype nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..fb36690d765
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=MOunn7GZCinobEL44IujJYFEaB83wh9TWkuufnnjbQ8%3D&amp;reserved=0>.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> > (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> >  DW_AT (DW_AT_priority, 0x45)
> >  DW_AT (DW_AT_segment, 0x46)
> >  DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> > -----Original Message-----
> > From: Andrew Burgess <andrew.burgess@embecosm.com>
> > Sent: Monday, September 20, 2021 3:11 PM
> > To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> > Cc: gdb-patches@sourceware.org; George, Jini Susan 
> > <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> > Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi 
> > <Nagajyothi.E@amd.com>
> > Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> > variables(a fortran feature)
> >
> > [CAUTION: External Email]
> >
> > * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
> >
> > > [AMD Official Use Only]
> > >
> > > Hi all,
> > >
> > > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> > >
> > > Problem description/summary:
> > >
> > > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > > (gdb) print nml
> > > No symbol "nml" in current context.
> > >
> > > Fix details:
> > >
> > > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> > >
> > > (gdb) ptype nml
> > > type = Type nml
> > >     integer(kind=4) :: a
> > >     integer(kind=4) :: b
> > > End Type nml
> > > (gdb) print nml
> > > $1 = ( a = 10, b = 20 )
> >
> > bhuvan,
> >
> > Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
> >
> > Thanks,
> > Andrew
> >
> >
> > >
> > > gdb/ChangeLog:
> > >
> > >        * dwarf2/read.c (process_die): Add new case for namelist.
> > >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > >        (read_structure_type, handle_struct_member_die, new_symbol)
> > >        (dwarf2_name): Update.
> > >        * f-valprint.c (f_language::value_print_inner): Add support for
> > >       printing namelist items.
> > >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> > >
> > > gdb/testsuite/ChangeLog:
> > >
> > >        * gdb.fortran/namelist.exp: New file.
> > >        * gdb.fortran/namelist.f90: New file.
> > >
> > > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019155507%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=K8mncjSuCt9BEaGJTnlJ9qp0%2FpFSVvfkVxbe%2FNFrej0%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> > >
> > > regards,
> > > bhuvan
> > >
> > > Patch inlined:
> > >
> > > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00
> > > 2001
> > > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > > Subject: [PATCH] Fix ptype and print commands for namelist 
> > > variables(a fortran feature).
> > >
> > > GCC/gfortran support namelist(a fortran feature), it emits 
> > > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not 
> > > process these dies and support namelist variables during print and 
> > > ptype commands. When tried to print, it bails out with the error message as shown below.
> > > (gdb) print nml
> > > No symbol "nml" in current context.
> > > This commit is to make the print and ptype commands work for 
> > > namelist variables and its items. Sample output of these commands is 
> > > shared below, with fixed gdb.
> > > (gdb) ptype nml
> > > type = Type nml
> > >     integer(kind=4) :: a
> > >     integer(kind=4) :: b
> > > End Type nml
> > > (gdb) print nml
> > > $1 = ( a = 10, b = 20 )
> > > ---
> > > gdb/ChangeLog                          | 11 +++++++
> > > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > > gdb/f-valprint.c                       | 10 ++++++
> > > gdb/testsuite/ChangeLog                |  5 +++
> > > gdb/testsuite/gdb.fortran/namelist.exp | 45
> > > ++++++++++++++++++++++++++
> > > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > > include/dwarf2.def                     |  2 +-
> > > 7 files changed, 134 insertions(+), 7 deletions(-) create mode
> > > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> > >
> > > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > > 36cb4c9e7e9..ec01c2957e9 100644
> > > --- a/gdb/ChangeLog
> > > +++ b/gdb/ChangeLog
> > > @@ -1,3 +1,14 @@
> > > +2021-08-23  Bhuvanendra Kumar N
> > > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > +
> > > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > > +     (dwarf2_name): Update.
> > > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > > +     printing namelist items.
> > > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > > +
> > > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> > >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > > 96009f1418f..54528d67498 100644
> > > --- a/gdb/dwarf2/read.c
> > > +++ b/gdb/dwarf2/read.c
> > > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> > >      case DW_TAG_interface_type:
> > >      case DW_TAG_structure_type:
> > >      case DW_TAG_union_type:
> > > +    case DW_TAG_namelist:
> > >        process_structure_scope (die, cu);
> > >        break;
> > >      case DW_TAG_enumeration_type:
> > > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> > >    fp = &new_field->field;
> > > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > > -    {
> > > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > > +            ! die_is_declaration (die, cu))
> >
> > The '&&' operator should start the line.
> >
> > > +    {
> > > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > > +      if (die->tag == DW_TAG_namelist_item)
> > > +        {
> > > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > > +          struct die_info *item_die = NULL;
> >
> > Throughout this patch, please use nullptr instead of NULL.
> >
> > > +          struct dwarf2_cu *item_cu = cu;
> > > +          if (attr1->form_is_ref ())
> > > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > > +          if (item_die != NULL)
> > > +            die = item_die;
> > > +        }
> > >        /* Data member other than a C++ static data member.  */
> > >        /* Get type of field.  */
> > > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> > >    type = alloc_type (objfile);
> > >    INIT_CPLUS_SPECIFIC (type);
> > > +  if (die->tag == DW_TAG_namelist)
> > > +    INIT_NONE_SPECIFIC (type);
> >
> > I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
> >
> > >    name = dwarf2_name (die, cu);
> > >    if (name != NULL)
> > > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> > >                   struct dwarf2_cu *cu) {
> > >    if (child_die->tag == DW_TAG_member
> > > -      || child_die->tag == DW_TAG_variable)
> > > +      || child_die->tag == DW_TAG_variable
> > > +      || child_die->tag == DW_TAG_namelist_item)
> > >      {
> > >        /* NOTE: carlton/2002-11-05: A C++ static data member
> > >       should be a DW_TAG_member that is a declaration, but @@
> > > -15728,7
> > > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > > struct type *type, }
> > >  /* Finish creating a structure or union type, including filling in
> > > -   its members and creating a symbol for it.  */
> > > +   its members and creating a symbol for it. This function also
> > > +   handles Fortran namelist variable, its items or members and
> > > +   creating a symbol for it.  */
> > >  static void
> > > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) 
> > > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> > >      case DW_TAG_union_type:
> > >      case DW_TAG_set_type:
> > >      case DW_TAG_enumeration_type:
> > > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > > +     case DW_TAG_namelist:
> > > +       if (die->tag == DW_TAG_namelist)
> > > +            {
> > > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > > +         }
> > > +       else
> > > +            {
> > > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > > +            }
> > >         {
> > >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> > >        && die->tag != DW_TAG_class_type
> > >       && die->tag != DW_TAG_interface_type
> > >        && die->tag != DW_TAG_structure_type
> > > +      && die->tag != DW_TAG_namelist
> > >        && die->tag != DW_TAG_union_type)
> > >      return NULL;
> > > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> > >      case DW_TAG_interface_type:
> > >      case DW_TAG_structure_type:
> > >      case DW_TAG_union_type:
> > > +    case DW_TAG_namelist:
> > >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> > >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> > >       or simply "<anonymous struct>" or "<anonymous union>" in GCC
> > > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> > > 240daaf34f9..8ed35e2fb1f 100644
> > > --- a/gdb/f-valprint.c
> > > +++ b/gdb/f-valprint.c
> > > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> > >             fputs_filtered (" = ", stream);
> > >           }
> > > +           /* While printing namelist items, fetch the appropriate value
> > > +              field before printing its value.  */
> > > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
> >
> > I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >
> > Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> >
> >
> >
> >
> > > +             {
> > > +               struct block_symbol symni = lookup_symbol(field_name,
> > > +                get_selected_block (0), VAR_DOMAIN, nullptr);
> >
> > There's a missing space before '(' here, and two lines below.
> >
> > > +               if (symni.symbol != NULL)
> > > +                 field = value_of_variable(symni.symbol, symni.block);
> > > +             }
> > > +
> > >            common_val_print (field, stream, recurse + 1,
> > >                      options, current_language); diff --git 
> > > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 
> > > 87cf3e2a061..33f60c29b3c 100644
> > > --- a/gdb/testsuite/ChangeLog
> > > +++ b/gdb/testsuite/ChangeLog
> > > @@ -1,3 +1,8 @@
> > > +2021-07-26  Bhuvanendra Kumar N
> > > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > +
> > > +     * gdb.fortran/namelist.exp: New file.
> > > +     * gdb.fortran/namelist.f90: New file.
> > > +
> > > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal 
> > > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > > b/gdb/testsuite/gdb.fortran/namelist.exp
> > > new file mode 100644
> > > index 00000000000..e4df8c7debb
> > > --- /dev/null
> > > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > > @@ -0,0 +1,45 @@
> > > +# Copyright 2020-2021 Free Software Foundation, Inc.
> >
> > The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
> >
> > > +
> > > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > > +
> > > +# This file is part of the gdb testsuite.  It contains tests for 
> > > +fortran # namelist.
> > > +
> > > +if { [skip_fortran_tests] } { return -1 }
> > > +
> > > +standard_testfile .f90
> > > +load_lib "fortran.exp"
> > > +
> > > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > > +    return -1
> > > +}
> > > +
> > > +if ![fortran_runto_main] then {
> > > +    perror "couldn't run to main"
> > > +    continue
> > > +}
> > > +
> > > +# Depending on the compiler being used, the type names can be printed differently.
> > > +set int [fortran_int4]
> > > +
> > > +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> > > +gdb_continue_to_breakpoint "Display namelist"
> > > +
> > > +if {[test_compiler_info {gcc-*}]} {
> > > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20 
> > > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
> >
> > The pattern should be wrapped onto the newline.
> >
> > Thanks,
> > Andrew
> >
> > > +} else {
> > > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > > +}
> > > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > > b/gdb/testsuite/gdb.fortran/namelist.f90
> > > new file mode 100644
> > > index 00000000000..00704eddf27
> > > --- /dev/null
> > > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > > @@ -0,0 +1,27 @@
> > > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C1b602ae2197248e5a9a008d988e12ef7%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637691323019160499%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=KoXo6%2BRQEYSwRQ6VV%2Batjx0FoVfnufps0RJnK88k2y0%3D&amp;reserved=0.
> > > +!
> > > +! This file is the Fortran source file for namelist.exp.
> > > +
> > > +program main
> > > +
> > > +  integer :: a, b
> > > +  namelist /nml/ a, b
> > > +
> > > +  a = 10
> > > +  b = 20
> > > +  Write(*,nml) ! Display namelist
> > > +
> > > +end program main
> > > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > > 1ae6e1df298..6b8be1f6a16 100644
> > > --- a/include/dwarf2.def
> > > +++ b/include/dwarf2.def
> > > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT 
> > > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT 
> > > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > > +DW_AT (DW_AT_namelist_item, 0x44)
> > > DW_AT (DW_AT_priority, 0x45)
> > > DW_AT (DW_AT_segment, 0x46)
> > > DW_AT (DW_AT_specification, 0x47)
> > > --
> > > 2.17.1
> > >
> > >
> > >
> >

-- 
Joel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-11-19 14:32           ` Kumar N, Bhuvanendra via Gdb-patches
  2021-12-03 18:56             ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-12-09 13:16             ` Andrew Burgess via Gdb-patches
  1 sibling, 0 replies; 21+ messages in thread
From: Andrew Burgess via Gdb-patches @ 2021-12-09 13:16 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: Achra, Nitika, Joseph, Ancel, E, Nagajyothi, George, Jini Susan,
	Sharma, Alok Kumar, gdb-patches

* Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-11-19 14:32:35 +0000]:

> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> Looks like gfortran is emitting DW_TAG_namelist for "nml" twice,
> hence you are seeing it twice with "info local" command. But
> clang/flang emits only once, hence I am getting only once with "info
> local" command.

Ahh, that explains it.

I tried rebasing your patch onto the current upstream/master, and I'm
hitting this assert:

  gdbsupport/array-view.h:190: internal-error: slice: Assertion `start + size <= m_size' failed.

I do compile GDB with `_GLIBCXX_DEBUG` defined in order to see that
assert.  I haven't looked into what might be going on here yet, but
thought I'd give you a heads up.

( Please let me know if you can't reproduce this issue, it is possible
  that I've managed to break something when merging/rebasing your
  patch. )

Thanks,
Andrew


^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-12-04 13:20               ` Joel Brobecker via Gdb-patches
@ 2021-12-10 16:18                 ` Kumar N, Bhuvanendra via Gdb-patches
  2021-12-20  5:13                   ` Joel Brobecker via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-12-10 16:18 UTC (permalink / raw)
  To: Joel Brobecker
  Cc: Achra, Nitika, Andrew Burgess, E, Nagajyothi, George, Jini Susan,
	Sharma, Alok Kumar, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 87600 bytes --]

[AMD Official Use Only]

Hi,

Thanks a lot for your comments. I have tried to address all your previous comments. I have attached the revised patch and also inlined. Not sure if you see some trailing spaces or indentation issues still, mostly they are due to my email client(MS outlook). Please let me know if you have any comments. Thanks again.

Regards,
bhuvan

PATCH inlined:

From a0e67a82709c8753778c02d5438decc7dae33172 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
 variables.

GCC/gfortran support namelist(a fortran feature), it emits
DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does
not process these dies and support namelist variables during
print and ptype commands. When tried to print, it bails out
with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.

This commit is to make the print and ptype commands work for
namelist variables and its items. Sample output of these
commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         | 13 +++++++
 gdb/testsuite/gdb.fortran/namelist.exp | 50 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 145 insertions(+), 8 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index cbd9a3012eb..2629a0ff432 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && ! die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          /* Typically, DW_TAG_namelist_item are references to namelist items.
+             If so, follow that reference.  */
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15635,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15823,7 +15841,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15867,7 +15886,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21971,8 +21992,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22909,6 +22939,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22964,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 27d9a730978..0491bff42aa 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol
+	            (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index dc575c42996..8da362bddec 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,19 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    /* * Fortran namelist is a group of variables or arrays that can be
+       read or written.
+
+       Namelist syntax: NAMELIST / groupname / namelist_items ...
+       NAMELIST statement assign a group name to a collection of variables
+       called as namelist items. The namelist items can be of any data type
+       and can be variables or arrays.
+
+       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
+       for each of the namelist items. GDB process these namelist dies
+       and print namelist variables during print and ptype commands.  */
+    TYPE_CODE_NAMELIST,
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..2e8325c0b1d
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed
+# differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


-----Original Message-----
From: Joel Brobecker <brobecker@adacore.com> 
Sent: Saturday, December 4, 2021 6:51 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: brobecker@adacore.com; gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Andrew Burgess <aburgess@redhat.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

> Thanks a lot for your reply on this thread. I have observed your reply
> in the below GDB patches email archive.

This is because the email as received on this mailing-list did not
have the From field set to your email address, but rather the
mailing-list's address. I don't know when this happens, and why
it does happen, but I've observed a number of such emails have
that "Name of contributor via gdb-patches <gdb-patches@xxx>"
sender email instead of the original sender's email. When that
happened, my reply-all did not include you.

I've added comments (see below).

I'll wait for a new version of this patch which hopefully address
all my comments.

> My replies are inlined below with Bhuvan start> and Bhuvan end>.
> Please bear with me for following such notation only for this time,
> since I had to copy and paste your reply and reply on top of that, I
> could not find better method. Also majority of the indentation
> comments are mostly due to email client related, but I will address
> all of them. I tried to answer most of your queries and also giving
> brief introduction to namelist feature. Please let me know if you have
> more questions about these.
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceware.org%2Fpipermail%2Fgdb-patches%2F2021-November%2F183907.html&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605796849%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=CkjxqJa5ySO4KQ%2BE%2FYnk52SijHcp2u1LFXKPHkdl1zo%3D&amp;reserved=0
>
> Joel Brobecker brobecker@adacore.com
> Sat Nov 27 07:56:51 GMT 2021
>
> Hi Bhuvan,
>
> > Gentle PING*4 for the revised patch. Requesting some of you from the
> > community to review the updated code patch please, i had addressed all
> > the previous review comments.
>
> I'm very sorry for the lack of feedback for this patch. I'll attempt
> to help you push this patch through, knowing that I have no knowledge
> of Fortran.
>
> I only have time to do code reviews in the weekend, at the moment,
> so hopefully others might be able to join in and help. But otherwise,
> please bear with me.
>
> > From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
> > Date: Fri, 8 Oct 2021 02:01:18 +0530
> > Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.
> >
> > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
>
> This is a small detail, but typically, for text which is not
> a copy/paste of other things like GDB sessions, etc, we try
> to keep the length of each line down to something that fits
> within an 80-characters terminal. Adding the 4 characters that
> commands like "git log" or "git show" indents the commit message
> with, would you mind reformatting your explanations to fit within
> those 76-characters per line, please?
>
> Also, for those who are not familiar with Fortran, I think it would
> be useful to have a small introduction to that feature that goes
> beyond a bit of Fortran code in a testcase, and how GDB is proposed
> to show it. I'd like to understand what they mean semantically,
> how those are typically used, and how they are stored in memory
> (to understand how they work). This will help me better review
> this change.
>
> Can you provide that kind of info?
>
> Bhuvan start>
Thanks, this is much clear for me, now. I think it might be useful
to have that information available as a comment in the code,
for those of us who aren't familiar with Fortran. I tried to think
of a place where we could add this information, and I propose we do
this at the location where we document the new TYPE_CODE_NAMELIST
enum. I would use the comment to provide the very quick introduction
to namelists you provides, and also a short summary of how they can
be described using DWARF (I wouldn't go as far as dumping the whole
DWARF debug info, as this is a bit over the top).


> Bhuvan end>
>
> > ---
> >  gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
> >  gdb/f-typeprint.c                      |  6 +++-
> >  gdb/f-valprint.c                       | 11 ++++++
> >  gdb/gdbtypes.h                         |  2 ++
> >  gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
> >  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
> >  include/dwarf2.def                     |  2 +-
> >  7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
> >  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> >
> >    fp = &new_field->field;
> >
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> > +            && ! die_is_declaration (die, cu))
>
> The indentation is incorrect. The "&&" opeator should line up
> with the indentation of the condition expression. Thus:
>
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> > +      && ! die_is_declaration (die, cu))
>
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
>
> Can you explain why, and put that information in the comment?
>
> Bhuvan start>
> As shown in the above sample dwarf dump, DW_TAG_namelist_item points or refers to actual variable die thru DW_FORM_ref4, hence we need to use the referenced die.
> Bhuvan end>

Thank you for the explanation. Given your answer above, and the
associated comment below:
>
> Also, this is only a minor comment that you don't have to agree with,
> but FWIW, when I read your comment, I intuitively thought that
> namelist items were always references. On the other hand, reading
> the code itself, it doesn't appear to be so.

... I propose you move the comment inside the the following
"if" block...

> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = nullptr;
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != nullptr)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */

... and make that comment a little more conditional, like so:

     if (die->tag == DW_TAG_namelist_item)
       {
         /* Typically, DW_TAG_namelist_item are references to XXX.
            If so, follow that reference.  */
         [...]
       }

Logically, I undesrtand now why items of your nameslists are references
to other entities, but perhaps this is not an absolute necessity?
Otherwise, why did you feel it was worth verifying this before following
the reference link?

This is a bit minor, but at the same time, I find that it's important to
provide good and clear comments, and they often impact heavily on how
quickly one can understand (or misunderstand) the code.

>
> I think it would be better if you kept that comment at the start
> of the if block, so above your special handling of DW_TAG_namelist_item.
>
> >        /* Get type of field.  */
> > @@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >      {
> >        type->set_code (TYPE_CODE_UNION);
> >      }
> > +  else if (die->tag == DW_TAG_namelist)
> > +    {
> > +      type->set_code (TYPE_CODE_NAMELIST);
> > +    }
> >    else
> >      {
> >        type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                       struct dwarf2_cu *cu)
> >  {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >      should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
> >
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >
> >  static void
> >  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >     case DW_TAG_union_type:
> >     case DW_TAG_set_type:
> >     case DW_TAG_enumeration_type:
> > -     SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -     SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +   case DW_TAG_namelist:
> > +     if (die->tag == DW_TAG_namelist)
> > +            {
> > +         SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +         SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +            }
> > +     else
> > +            {
> > +         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +         SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
>
> I have to say, I'm a little uncomfortable with this part of
> the change -- perhaps simply because I don't understand it.
> Does it make sense to handle DW_TAG_namelist here? This second
> handles a group of *types*, wheres the change suggests that
> namelist are more like *variables*. Should the two be handled
> at the same place? What made you pick this part of the code
> to insert support for DW_TAG_namelist?  Or am I misunderstanding
> the concept of namelists (which brings me back to the question
> at the beginning)?
>
> Bhuvan start>
> DW_TAG_namelist are similar to DW_TAG_structure_type or DW_TAG_union_type, hence I have placed them here. Basically namelist variable nml (in the above sample program) is a group of items a and b. please note a and b are declared before only and storage is allocated as part of that. For namelist items (a and b), there is no separate storage gets created or allocated, same storage is used/referenced. DW_TAG_namelist_item points to the original variable die. Hence namelist is just a group of such items. Main advantage of these namelist is that they can be used for I/O and they cannot be categorized strictly as type only, hence namelists are handled at the same place as that of DW_TAG_structure_type, but since they can be used with I/O statements (which is the main advantage of using namelist in fortran), I have categorized them as VAR_DOMAIN, so that I can use it during print command as well inside GDB.
> Hence namelist cannot be categorized as type only feature, it's a combination of type and variable, if we want to put it this way.
> I have used a separate type (TYPE_CODE_NAMELIST) for namelist after Andrew suggestion.
> Bhuvan end>

OK. Let's go with your approach.

>
> >       {
> >         /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >        && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> >
> > @@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >      structures or unions.  These were of the form "._%d" in GCC 4.1,
> >      or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
> > --- a/gdb/f-typeprint.c
> > +++ b/gdb/f-typeprint.c
> > @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
> >      case TYPE_CODE_UNDEF:
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >      case TYPE_CODE_ENUM:
> >      case TYPE_CODE_INT:
> >      case TYPE_CODE_FLT:
> > @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
> >      case TYPE_CODE_UNDEF:
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >      case TYPE_CODE_ENUM:
> >      case TYPE_CODE_INT:
> >      case TYPE_CODE_FLT:
> > @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
> >        const char *prefix = "";
> >        if (type->code () == TYPE_CODE_UNION)
> >     prefix = "Type, C_Union :: ";
> > -      else if (type->code () == TYPE_CODE_STRUCT)
> > +      else if (type->code () == TYPE_CODE_STRUCT
> > +               || type->code () == TYPE_CODE_NAMELIST)
> >     prefix = "Type ";
> >        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
> >        return;
> > @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
> >
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >        if (type->code () == TYPE_CODE_UNION)
> >     fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
> >        else
> > diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >
> >      case TYPE_CODE_STRUCT:
> >      case TYPE_CODE_UNION:
> > +    case TYPE_CODE_NAMELIST:
> >        /* Starting from the Fortran 90 standard, Fortran supports derived
> >      types.  */
> >        fprintf_filtered (stream, "( ");
> > @@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >               fputs_filtered (" = ", stream);
> >             }
> >
> > +         /* While printing namelist items, fetch the appropriate value
> > +            field before printing its value.  */
> > +         if (type->code () == TYPE_CODE_NAMELIST)
> > +           {
> > +             struct block_symbol symni = lookup_symbol (field_name,
> > +                   get_selected_block (0), VAR_DOMAIN, nullptr);
>
> Can you fix the indentation here, please? On the second line,
> the start of the parameters should be aligned with the start
> of the parameters on the lines above. Also, remember that indentation
> is 2 characters, not 4. You could have...
>
>   struct block_symbol symni = lookup_symbol (field_name,
>                                              get_selected_block (0),
>                                              VAR_DOMAIN, nullptr);
>
>   ... or (one parameter per line) ...
>
>   struct block_symbol symni = lookup_symbol (field_name,
>                                              get_selected_block (0),
>                                              VAR_DOMAIN,
>                                              nullptr);
>
>   ... or move all the parameters on the next line, with:
>
>   struct block_symbol symni = lookup_symbol
>     (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);
>
> > +             if (symni.symbol != nullptr)
> > +               field = value_of_variable (symni.symbol, symni.block);
> > +           }
> > +
> >           common_val_print (field, stream, recurse + 1,
> >                             options, current_language);
> >
> > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
> > --- a/gdb/gdbtypes.h
> > +++ b/gdb/gdbtypes.h
> > @@ -195,6 +195,8 @@ enum type_code
> >
> >      /* * Fixed Point type.  */
> >      TYPE_CODE_FIXED_POINT,
> > +
> > +    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
>
> In terms of documenting the enumerate, can you use the same style
> as the other enums? This is actually important, because I believe
> this is to allow us to use Doxygen to generate documentation (something
> we may not have done for a while, but I'd rather we don't make it
> worse).
>
> >
> >  /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..90762928455
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,49 @@
> > +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605796849%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=wOzbjNiPDwPjw%2BRorLNwmfcXv%2BnvsJ6wpqozzlTp7VM%3D&amp;reserved=0>.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for
> > +fortran # namelist.
>
> I think there are trailing spaces at the end of several lines above.
> While at it, would you mind please removing them all?
> Or, actually, given the above, I'm wondering if this wasn't caused
> by your mailer making some reformatting changes..
>
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
>
> Same request as in the commit message: It would be nice if we could
> keep the code and comments without 80-characters whenever reasonable.
>
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"]
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" \
> > +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \
> > +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> > +} else {
> > +    gdb_test "ptype nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..fb36690d765
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605796849%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=wOzbjNiPDwPjw%2BRorLNwmfcXv%2BnvsJ6wpqozzlTp7VM%3D&amp;reserved=0>.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> >  DW_AT (DW_AT_priority, 0x45)
> >  DW_AT (DW_AT_segment, 0x46)
> >  DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
>
> -----Original Message-----
> From: Kumar N, Bhuvanendra
> Sent: Friday, November 19, 2021 8:03 PM
> To: aburgess@redhat.com
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Joseph, Ancel <Ancel.Joseph@amd.com>
> Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
>
> [AMD Official Use Only]
>
> Hi Andrew,
>
> Looks like gfortran is emitting DW_TAG_namelist for "nml" twice, hence you are seeing it twice with "info local" command. But clang/flang emits only once, hence I am getting only once with "info local" command.
>
> my GDB command outputs are with clang/flang compiler. Please let me know if you want to try with clang/flang, I can share the details, thanks a lot again
>
> regards,
> bhuvan
>
> -----Original Message-----
> From: Kumar N, Bhuvanendra
> Sent: Friday, November 19, 2021 7:39 PM
> To: 'aburgess@redhat.com' <aburgess@redhat.com>
> Cc: 'gdb-patches@sourceware.org' <gdb-patches@sourceware.org>; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Joseph, Ancel <Ancel.Joseph@amd.com>
> Subject: FW: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
>
> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks again for the review. Could you please use this revised patch for the review, thanks
>
> I am resending the revised patch now and details are shared just below in this email chain.
> I am getting the proper outputs with "info local" as shown below.
>
> Regards,
> bhuvan
>
> (gdb) i local
> a = 10
> b = 20
> nml = ( a = 10, b = 20 )
> (gdb) pt nml
> type = Type nml
>     integer :: a
>     integer :: b
> End Type nml
> (gdb) whatis nml
> type = Type nml
>
> -----Original Message-----
> From: Kumar N, Bhuvanendra
> Sent: Friday, October 8, 2021 2:35 AM
> To: Andrew Burgess <andrew.burgess@embecosm.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
>
> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks again for your review comments. I have now introduced a new type(TYPE_CODE_NAMELIST) for namelist type as you suggested, could you please review the revised changes. Updated patch is attached and also inlined with this email. There are no regressions found during testing.
>
> thanks,
> bhuvan
>
> PATCH inlined:
>
> From 89b7f847042ccea44633f714db07400fa6dd3617 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
> Date: Fri, 8 Oct 2021 02:01:18 +0530
> Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist  variables.
>
> GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> (gdb) print nml
> No symbol "nml" in current context.
> This commit is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> (gdb) ptype nml
> type = Type nml
>     integer(kind=4) :: a
>     integer(kind=4) :: b
> End Type nml
> (gdb) print nml
> $1 = ( a = 10, b = 20 )
> ---
>  gdb/dwarf2/read.c                      | 43 ++++++++++++++++++----
>  gdb/f-typeprint.c                      |  6 +++-
>  gdb/f-valprint.c                       | 11 ++++++
>  gdb/gdbtypes.h                         |  2 ++
>  gdb/testsuite/gdb.fortran/namelist.exp | 49 ++++++++++++++++++++++++++
>  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
>  include/dwarf2.def                     |  2 +-
>  7 files changed, 132 insertions(+), 8 deletions(-)  create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
>  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
>
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index cbd9a3012eb..e6cd8ed48f0 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14562,8 +14563,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
>
>    fp = &new_field->field;
>
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +            && ! die_is_declaration (die, cu))
> +    {
> +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +          struct die_info *item_die = nullptr;
> +          struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +            item_die = follow_die_ref (die, attr1, &item_cu);
> +          if (item_die != nullptr)
> +            die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>
>        /* Get type of field.  */
> @@ -15621,6 +15634,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      {
>        type->set_code (TYPE_CODE_UNION);
>      }
> +  else if (die->tag == DW_TAG_namelist)
> +    {
> +      type->set_code (TYPE_CODE_NAMELIST);
> +    }
>    else
>      {
>        type->set_code (TYPE_CODE_STRUCT); @@ -15823,7 +15840,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                         struct dwarf2_cu *cu)
>  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>        should be a DW_TAG_member that is a declaration, but @@ -15867,7 +15885,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,  }
>
>  /* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +   its members and creating a symbol for it. This function also
> +   handles Fortran namelist variable, its items or members and
> +   creating a symbol for it.  */
>
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21971,8 +21991,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>       case DW_TAG_union_type:
>       case DW_TAG_set_type:
>       case DW_TAG_enumeration_type:
> -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +     case DW_TAG_namelist:
> +       if (die->tag == DW_TAG_namelist)
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +            }
> +       else
> +            {
> +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +            }
>
>         {
>           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@ -22909,6 +22938,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>
> @@ -22933,6 +22963,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>        structures or unions.  These were of the form "._%d" in GCC 4.1,
>        or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 1791cb29451..5b34622dacb 100644
> --- a/gdb/f-typeprint.c
> +++ b/gdb/f-typeprint.c
> @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>        const char *prefix = "";
>        if (type->code () == TYPE_CODE_UNION)
>       prefix = "Type, C_Union :: ";
> -      else if (type->code () == TYPE_CODE_STRUCT)
> +      else if (type->code () == TYPE_CODE_STRUCT
> +               || type->code () == TYPE_CODE_NAMELIST)
>       prefix = "Type ";
>        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
>        return;
> @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        if (type->code () == TYPE_CODE_UNION)
>       fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
>        else
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 27d9a730978..6f80b5a12ff 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        /* Starting from the Fortran 90 standard, Fortran supports derived
>        types.  */
>        fprintf_filtered (stream, "( ");
> @@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
>                 fputs_filtered (" = ", stream);
>               }
>
> +           /* While printing namelist items, fetch the appropriate value
> +              field before printing its value.  */
> +           if (type->code () == TYPE_CODE_NAMELIST)
> +             {
> +               struct block_symbol symni = lookup_symbol (field_name,
> +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> +               if (symni.symbol != nullptr)
> +                 field = value_of_variable (symni.symbol, symni.block);
> +             }
> +
>             common_val_print (field, stream, recurse + 1,
>                               options, current_language);
>
> diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index dc575c42996..ba8a61987db 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -195,6 +195,8 @@ enum type_code
>
>      /* * Fixed Point type.  */
>      TYPE_CODE_FIXED_POINT,
> +
> +    TYPE_CODE_NAMELIST,         /**< Fortran namelist.  */
>    };
>
>  /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..90762928455
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,49 @@
> +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605796849%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=wOzbjNiPDwPjw%2BRorLNwmfcXv%2BnvsJ6wpqozzlTp7VM%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"]
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..fb36690d765
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605796849%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=wOzbjNiPDwPjw%2BRorLNwmfcXv%2BnvsJ6wpqozzlTp7VM%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 1ae6e1df298..6b8be1f6a16 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)
> --
> 2.17.1
>
>
> -----Original Message-----
> From: Andrew Burgess <andrew.burgess@embecosm.com>
> Sent: Wednesday, October 6, 2021 9:22 PM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
>
> [CAUTION: External Email]
>
> * Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com> [2021-09-22 12:38:20 +0000]:
>
> > [AMD Official Use Only]
> >
> > Hi Andrew,
> >
> > Thanks a lot for your review comments, I have addressed all the review comments and tested. Updated patch is attached and also inlined with this email.
> >
> > >I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> > >Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> >
> > Regarding your major comment, I did considered introducing a new type
> > specific field for namelist earlier, instead of using any of those
> > existing. Reason I did not included in my earlier patch was,
> > type_specific_kind is declared with 3 bits in struct main_type and
> > already there were 8 values, hence deferred expanding
> > type_specific_kind etc.... But now I have done that, thanks for the
> > suggestion.
>
> Except that wasn't quite what I suggested; I actually asked whether namelist's should become their own type altogether, notice I suggested TYPE_CODE_NAMELIST.
>
> Though what you have here is nice in its simplicity, but I can't shake the feeling that its not the right solution.
>
> I'll need to think about this some more - maybe others have an opinion?
>
> Thanks,
> Andrew
>
>
>
>
>
> >
> > Regards,
> > bhuvan
> >
> > PATH inlined:
> >
> > From 59053daf1018c3e4bcae8cd342d46b00f4f03648 Mon Sep 17 00:00:00 2001
> > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > <Bhuvanendra.KumarN@amd.com>
> > Date: Wed, 22 Sep 2021 17:52:15 +0530
> > Subject: [PATCH] Fix ptype and print commands for namelist variables(a
> > fortran  feature).
> >
> > GCC/gfortran support namelist(a fortran feature), it emits
> > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
> > process these dies and support namelist variables during print and
> > ptype commands. When tried to print, it bails out with the error message as shown below.
> > (gdb) print nml
> > No symbol "nml" in current context.
> > This commit is to make the print and ptype commands work for namelist
> > variables and its items. Sample output of these commands is shared
> > below, with fixed gdb.
> > (gdb) ptype nml
> > type = Type nml
> >     integer(kind=4) :: a
> >     integer(kind=4) :: b
> > End Type nml
> > (gdb) print nml
> > $1 = ( a = 10, b = 20 )
> > ---
> >  gdb/ChangeLog                          | 11 ++++++
> >  gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
> >  gdb/f-valprint.c                       | 10 ++++++
> >  gdb/gdbtypes.h                         |  3 +-
> >  gdb/testsuite/ChangeLog                |  5 +++
> >  gdb/testsuite/gdb.fortran/namelist.exp | 49
> > ++++++++++++++++++++++++++
> >  gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
> >  include/dwarf2.def                     |  2 +-
> >  8 files changed, 142 insertions(+), 9 deletions(-)  create mode
> > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> >  create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> >
> > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > 36cb4c9e7e9..ec01c2957e9 100644
> > --- a/gdb/ChangeLog
> > +++ b/gdb/ChangeLog
> > @@ -1,3 +1,14 @@
> > +2021-08-23  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> > +
> > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > +     (dwarf2_name): Update.
> > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > +     printing namelist items.
> > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > +
> >  2021-06-08  Lancelot Six  <lsix@lancelotsix.com>
> >
> >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > 96009f1418f..88db06ec9e7 100644
> > --- a/gdb/dwarf2/read.c
> > +++ b/gdb/dwarf2/read.c
> > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        process_structure_scope (die, cu);
> >        break;
> >      case DW_TAG_enumeration_type:
> > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip,
> > struct die_info *die,
> >
> >    fp = &new_field->field;
> >
> > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > -    {
> > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> > +            && ! die_is_declaration (die, cu))
> > +    {
> > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > +      if (die->tag == DW_TAG_namelist_item)
> > +        {
> > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > +          struct die_info *item_die = nullptr;
> > +          struct dwarf2_cu *item_cu = cu;
> > +          if (attr1->form_is_ref ())
> > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > +          if (item_die != nullptr)
> > +            die = item_die;
> > +        }
> >        /* Data member other than a C++ static data member.  */
> >
> >        /* Get type of field.  */
> > @@ -15448,7 +15461,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> >      }
> >
> >    type = alloc_type (objfile);
> > -  INIT_CPLUS_SPECIFIC (type);
> > +  if (die->tag == DW_TAG_namelist)
> > +    TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_NAMELIST;  else
> > +    INIT_CPLUS_SPECIFIC (type);
> >
> >    name = dwarf2_name (die, cu);
> >    if (name != NULL)
> > @@ -15684,7 +15700,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> >                         struct dwarf2_cu *cu)  {
> >    if (child_die->tag == DW_TAG_member
> > -      || child_die->tag == DW_TAG_variable)
> > +      || child_die->tag == DW_TAG_variable
> > +      || child_die->tag == DW_TAG_namelist_item)
> >      {
> >        /* NOTE: carlton/2002-11-05: A C++ static data member
> >        should be a DW_TAG_member that is a declaration, but @@
> > -15728,7 +15745,9 @@ handle_struct_member_die (struct die_info
> > *child_die, struct type *type,  }
> >
> >  /* Finish creating a structure or union type, including filling in
> > -   its members and creating a symbol for it.  */
> > +   its members and creating a symbol for it. This function also
> > +   handles Fortran namelist variable, its items or members and
> > +   creating a symbol for it.  */
> >
> >  static void
> >  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
> > @@ -21807,8 +21826,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> >       case DW_TAG_union_type:
> >       case DW_TAG_set_type:
> >       case DW_TAG_enumeration_type:
> > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +     case DW_TAG_namelist:
> > +       if (die->tag == DW_TAG_namelist)
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > +            }
> > +       else
> > +            {
> > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > +            }
> >
> >         {
> >           /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > -22744,6 +22772,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >        && die->tag != DW_TAG_class_type
> >        && die->tag != DW_TAG_interface_type
> >        && die->tag != DW_TAG_structure_type
> > +      && die->tag != DW_TAG_namelist
> >        && die->tag != DW_TAG_union_type)
> >      return NULL;
> >
> > @@ -22768,6 +22797,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> >      case DW_TAG_interface_type:
> >      case DW_TAG_structure_type:
> >      case DW_TAG_union_type:
> > +    case DW_TAG_namelist:
> >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> >        structures or unions.  These were of the form "._%d" in GCC 4.1,
> >        or simply "<anonymous struct>" or "<anonymous union>" in GCC
> > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index
> > 240daaf34f9..aa86fbc901e 100644
> > --- a/gdb/f-valprint.c
> > +++ b/gdb/f-valprint.c
> > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> >                 fputs_filtered (" = ", stream);
> >               }
> >
> > +           /* While printing namelist items, fetch the appropriate value
> > +              field before printing its value.  */
> > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NAMELIST)
> > +             {
> > +               struct block_symbol symni = lookup_symbol (field_name,
> > +                     get_selected_block (0), VAR_DOMAIN, nullptr);
> > +               if (symni.symbol != nullptr)
> > +                 field = value_of_variable (symni.symbol, symni.block);
> > +             }
> > +
> >             common_val_print (field, stream, recurse + 1,
> >                               options, current_language);
> >
> > diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index
> > 0cc00e74a20..124282c3d53 100644
> > --- a/gdb/gdbtypes.h
> > +++ b/gdb/gdbtypes.h
> > @@ -607,6 +607,7 @@ enum type_specific_kind
> >    TYPE_SPECIFIC_SELF_TYPE,
> >    TYPE_SPECIFIC_INT,
> >    TYPE_SPECIFIC_FIXED_POINT,
> > +  TYPE_SPECIFIC_NAMELIST,
> >  };
> >
> >  union type_owner
> > @@ -833,7 +834,7 @@ struct main_type
> >    /* * A discriminant telling us which field of the type_specific
> >       union is being used for this type, if any.  */
> >
> > -  ENUM_BITFIELD(type_specific_kind) type_specific_field : 3;
> > +  ENUM_BITFIELD(type_specific_kind) type_specific_field : 4;
> >
> >    /* * Number of fields described for this type.  This field appears
> >       at this location because it packs nicely here.  */ diff --git
> > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index
> > 87cf3e2a061..33f60c29b3c 100644
> > --- a/gdb/testsuite/ChangeLog
> > +++ b/gdb/testsuite/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2021-07-26  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> > +
> > +     * gdb.fortran/namelist.exp: New file.
> > +     * gdb.fortran/namelist.f90: New file.
> > +
> >  2021-06-10  Bhuvanendra Kumar N  <Bhuvanendra.KumarN@amd.com>
> >
> >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > b/gdb/testsuite/gdb.fortran/namelist.exp
> > new file mode 100644
> > index 00000000000..90762928455
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > @@ -0,0 +1,49 @@
> > +# Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605806843%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=6EG9MK9nar3SvQCQ14n85uC3sVhIxMx8P5wfRSeLYTk%3D&amp;reserved=0>.
> > +
> > +# This file is part of the gdb testsuite.  It contains tests for
> > +fortran # namelist.
> > +
> > +if { [skip_fortran_tests] } { return -1 }
> > +
> > +standard_testfile .f90
> > +load_lib "fortran.exp"
> > +
> > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > +    return -1
> > +}
> > +
> > +if ![fortran_runto_main] then {
> > +    perror "couldn't run to main"
> > +    continue
> > +}
> > +
> > +# Depending on the compiler being used, the type names can be printed differently.
> > +set int [fortran_int4]
> > +
> > +gdb_breakpoint [gdb_get_line_number "Display namelist"]
> > +gdb_continue_to_breakpoint "Display namelist"
> > +
> > +if {[test_compiler_info {gcc-*}]} {
> > +    gdb_test "ptype nml" \
> > +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > +    gdb_test "print nml" \
> > +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> > +} else {
> > +    gdb_test "ptype nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +    gdb_test "print nml" \
> > +        "No symbol \"nml\" in current context\\."
> > +}
> > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > b/gdb/testsuite/gdb.fortran/namelist.f90
> > new file mode 100644
> > index 00000000000..fb36690d765
> > --- /dev/null
> > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > @@ -0,0 +1,27 @@
> > +! Copyright (C) 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605806843%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=6EG9MK9nar3SvQCQ14n85uC3sVhIxMx8P5wfRSeLYTk%3D&amp;reserved=0>.
> > +!
> > +! This file is the Fortran source file for namelist.exp.
> > +
> > +program main
> > +
> > +  integer :: a, b
> > +  namelist /nml/ a, b
> > +
> > +  a = 10
> > +  b = 20
> > +  Write(*,nml) ! Display namelist
> > +
> > +end program main
> > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > 1ae6e1df298..6b8be1f6a16 100644
> > --- a/include/dwarf2.def
> > +++ b/include/dwarf2.def
> > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT
> > (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT
> > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > +DW_AT (DW_AT_namelist_item, 0x44)
> >  DW_AT (DW_AT_priority, 0x45)
> >  DW_AT (DW_AT_segment, 0x46)
> >  DW_AT (DW_AT_specification, 0x47)
> > --
> > 2.17.1
> >
> >
> > -----Original Message-----
> > From: Andrew Burgess <andrew.burgess@embecosm.com>
> > Sent: Monday, September 20, 2021 3:11 PM
> > To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> > Cc: gdb-patches@sourceware.org; George, Jini Susan
> > <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>;
> > Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi
> > <Nagajyothi.E@amd.com>
> > Subject: Re: [PATCH] Fix ptype and print commands for namelist
> > variables(a fortran feature)
> >
> > [CAUTION: External Email]
> >
> > * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2021-08-24 09:16:19 +0000]:
> >
> > > [AMD Official Use Only]
> > >
> > > Hi all,
> > >
> > > Requesting code review for this GDB patch. Required patch is attached and also inlined below with this email.
> > >
> > > Problem description/summary:
> > >
> > > GCC/gfortran support namelist(a fortran feature), it emits DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not process these dies and support namelist variables during print and ptype commands. When tried to print, it bails out with the error message as shown below.
> > > (gdb) print nml
> > > No symbol "nml" in current context.
> > >
> > > Fix details:
> > >
> > > This fix is to make the print and ptype commands work for namelist variables and its items. Sample output of these commands is shared below, with fixed gdb.
> > >
> > > (gdb) ptype nml
> > > type = Type nml
> > >     integer(kind=4) :: a
> > >     integer(kind=4) :: b
> > > End Type nml
> > > (gdb) print nml
> > > $1 = ( a = 10, b = 20 )
> >
> > bhuvan,
> >
> > Thanks for working on this.  I have some small style issues, but I have a bigger question which you'll find inline.
> >
> > Thanks,
> > Andrew
> >
> >
> > >
> > > gdb/ChangeLog:
> > >
> > >        * dwarf2/read.c (process_die): Add new case for namelist.
> > >        (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > >        (read_structure_type, handle_struct_member_die, new_symbol)
> > >        (dwarf2_name): Update.
> > >        * f-valprint.c (f_language::value_print_inner): Add support for
> > >       printing namelist items.
> > >        * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > >        (DW_AT_namelist_item): ... this. As per dwarf standard.
> > >
> > > gdb/testsuite/ChangeLog:
> > >
> > >        * gdb.fortran/namelist.exp: New file.
> > >        * gdb.fortran/namelist.f90: New file.
> > >
> > > NOTE: Similarly renaming DW_AT_namelist_items to DW_AT_namelist_item as per DWARF standard naming convention in GCC/gfortran repo (https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgcc-mirror%2Fgcc&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605806843%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=Wt7zD2zRCOU%2Flds18hQFQotlDjD6GpzUh0Hntq4pGFo%3D&amp;reserved=0) will be handled in separate PATCH. I will raise separate patch for this.
> > >
> > > regards,
> > > bhuvan
> > >
> > > Patch inlined:
> > >
> > > From 0775cbf3716bae9480c3f1f1d9d8860ac561929e Mon Sep 17 00:00:00
> > > 2001
> > > From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?=
> > > Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > Date: Mon, 24 Aug 2021 11:49:14 +0530
> > > Subject: [PATCH] Fix ptype and print commands for namelist
> > > variables(a fortran feature).
> > >
> > > GCC/gfortran support namelist(a fortran feature), it emits
> > > DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
> > > process these dies and support namelist variables during print and
> > > ptype commands. When tried to print, it bails out with the error message as shown below.
> > > (gdb) print nml
> > > No symbol "nml" in current context.
> > > This commit is to make the print and ptype commands work for
> > > namelist variables and its items. Sample output of these commands is
> > > shared below, with fixed gdb.
> > > (gdb) ptype nml
> > > type = Type nml
> > >     integer(kind=4) :: a
> > >     integer(kind=4) :: b
> > > End Type nml
> > > (gdb) print nml
> > > $1 = ( a = 10, b = 20 )
> > > ---
> > > gdb/ChangeLog                          | 11 +++++++
> > > gdb/dwarf2/read.c                      | 41 +++++++++++++++++++----
> > > gdb/f-valprint.c                       | 10 ++++++
> > > gdb/testsuite/ChangeLog                |  5 +++
> > > gdb/testsuite/gdb.fortran/namelist.exp | 45
> > > ++++++++++++++++++++++++++
> > > gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++++
> > > include/dwarf2.def                     |  2 +-
> > > 7 files changed, 134 insertions(+), 7 deletions(-) create mode
> > > 100644 gdb/testsuite/gdb.fortran/namelist.exp
> > > create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90
> > >
> > > diff --git a/gdb/ChangeLog b/gdb/ChangeLog index
> > > 36cb4c9e7e9..ec01c2957e9 100644
> > > --- a/gdb/ChangeLog
> > > +++ b/gdb/ChangeLog
> > > @@ -1,3 +1,14 @@
> > > +2021-08-23  Bhuvanendra Kumar N
> > > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > +
> > > +     * dwarf2/read.c (process_die): Add new case for namelist.
> > > +     (dwarf2_add_field): Process DW_TAG_namelist_item die.
> > > +     (read_structure_type, handle_struct_member_die, new_symbol)
> > > +     (dwarf2_name): Update.
> > > +     * f-valprint.c (f_language::value_print_inner): Add support for
> > > +     printing namelist items.
> > > +     * include/dwarf2.def: (DW_AT_namelist_items): Renamed to ...
> > > +     (DW_AT_namelist_item): ... this. As per dwarf standard.
> > > +
> > > 2021-06-08  Lancelot Six  lsix@lancelotsix.com<mailto:lsix@lancelotsix.com>
> > >       * python/lib/gdb/FrameDecorator.py (FrameDecorator): Use 'is None'
> > > diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index
> > > 96009f1418f..54528d67498 100644
> > > --- a/gdb/dwarf2/read.c
> > > +++ b/gdb/dwarf2/read.c
> > > @@ -9570,6 +9570,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
> > >      case DW_TAG_interface_type:
> > >      case DW_TAG_structure_type:
> > >      case DW_TAG_union_type:
> > > +    case DW_TAG_namelist:
> > >        process_structure_scope (die, cu);
> > >        break;
> > >      case DW_TAG_enumeration_type:
> > > @@ -14417,8 +14418,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> > >    fp = &new_field->field;
> > > -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> > > -    {
> > > +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item) &&
> > > +            ! die_is_declaration (die, cu))
> >
> > The '&&' operator should start the line.
> >
> > > +    {
> > > +      /* For the DW_TAG_namelist_item die, use the referenced die.  */
> > > +      if (die->tag == DW_TAG_namelist_item)
> > > +        {
> > > +          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> > > +          struct die_info *item_die = NULL;
> >
> > Throughout this patch, please use nullptr instead of NULL.
> >
> > > +          struct dwarf2_cu *item_cu = cu;
> > > +          if (attr1->form_is_ref ())
> > > +            item_die = follow_die_ref (die, attr1, &item_cu);
> > > +          if (item_die != NULL)
> > > +            die = item_die;
> > > +        }
> > >        /* Data member other than a C++ static data member.  */
> > >        /* Get type of field.  */
> > > @@ -15449,6 +15462,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
> > >    type = alloc_type (objfile);
> > >    INIT_CPLUS_SPECIFIC (type);
> > > +  if (die->tag == DW_TAG_namelist)
> > > +    INIT_NONE_SPECIFIC (type);
> >
> > I think you should use if/then/else and place INIT_CPLUS_SPECIFIC in the else block.
> >
> > >    name = dwarf2_name (die, cu);
> > >    if (name != NULL)
> > > @@ -15684,7 +15699,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
> > >                   struct dwarf2_cu *cu) {
> > >    if (child_die->tag == DW_TAG_member
> > > -      || child_die->tag == DW_TAG_variable)
> > > +      || child_die->tag == DW_TAG_variable
> > > +      || child_die->tag == DW_TAG_namelist_item)
> > >      {
> > >        /* NOTE: carlton/2002-11-05: A C++ static data member
> > >       should be a DW_TAG_member that is a declaration, but @@
> > > -15728,7
> > > +15744,9 @@ handle_struct_member_die (struct die_info *child_die,
> > > struct type *type, }
> > >  /* Finish creating a structure or union type, including filling in
> > > -   its members and creating a symbol for it.  */
> > > +   its members and creating a symbol for it. This function also
> > > +   handles Fortran namelist variable, its items or members and
> > > +   creating a symbol for it.  */
> > >  static void
> > > process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
> > > @@ -21807,8 +21825,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
> > >      case DW_TAG_union_type:
> > >      case DW_TAG_set_type:
> > >      case DW_TAG_enumeration_type:
> > > -       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > > -       SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > > +     case DW_TAG_namelist:
> > > +       if (die->tag == DW_TAG_namelist)
> > > +            {
> > > +           SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> > > +           SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> > > +         }
> > > +       else
> > > +            {
> > > +           SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> > > +           SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> > > +            }
> > >         {
> > >          /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't @@
> > > -22744,6 +22771,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> > >        && die->tag != DW_TAG_class_type
> > >       && die->tag != DW_TAG_interface_type
> > >        && die->tag != DW_TAG_structure_type
> > > +      && die->tag != DW_TAG_namelist
> > >        && die->tag != DW_TAG_union_type)
> > >      return NULL;
> > > @@ -22768,6 +22796,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
> > >      case DW_TAG_interface_type:
> > >      case DW_TAG_structure_type:
> > >      case DW_TAG_union_type:
> > > +    case DW_TAG_namelist:
> > >        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
> > >       structures or unions.  These were of the form "._%d" in GCC 4.1,
> > >       or simply "<anonymous struct>" or "<anonymous union>" in GCC
> > > 4.3 diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index
> > > 240daaf34f9..8ed35e2fb1f 100644
> > > --- a/gdb/f-valprint.c
> > > +++ b/gdb/f-valprint.c
> > > @@ -320,6 +320,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> > >             fputs_filtered (" = ", stream);
> > >           }
> > > +           /* While printing namelist items, fetch the appropriate value
> > > +              field before printing its value.  */
> > > +           if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_NONE)
> >
> > I'm a little uncomfortable with this if condition.  This feels like a bit of a hack.  Is there precedent anywhere else in GDB for using the type specific field like this?
> >
> > Wouldn't adding a TYPE_CODE_NAMELIST be more in keeping with how GDB currently does things, though I understand this is likely to make the patch slightly bigger.  Did you consider this approach?
> >
> >
> >
> >
> > > +             {
> > > +               struct block_symbol symni = lookup_symbol(field_name,
> > > +                get_selected_block (0), VAR_DOMAIN, nullptr);
> >
> > There's a missing space before '(' here, and two lines below.
> >
> > > +               if (symni.symbol != NULL)
> > > +                 field = value_of_variable(symni.symbol, symni.block);
> > > +             }
> > > +
> > >            common_val_print (field, stream, recurse + 1,
> > >                      options, current_language); diff --git
> > > a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index
> > > 87cf3e2a061..33f60c29b3c 100644
> > > --- a/gdb/testsuite/ChangeLog
> > > +++ b/gdb/testsuite/ChangeLog
> > > @@ -1,3 +1,8 @@
> > > +2021-07-26  Bhuvanendra Kumar N
> > > +Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > > +
> > > +     * gdb.fortran/namelist.exp: New file.
> > > +     * gdb.fortran/namelist.f90: New file.
> > > +
> > > 2021-06-10  Bhuvanendra Kumar N  Bhuvanendra.KumarN@amd.com<mailto:Bhuvanendra.KumarN@amd.com>
> > >       * gdb.fortran/ptype-on-functions.exp: Add type info of formal
> > > diff --git a/gdb/testsuite/gdb.fortran/namelist.exp
> > > b/gdb/testsuite/gdb.fortran/namelist.exp
> > > new file mode 100644
> > > index 00000000000..e4df8c7debb
> > > --- /dev/null
> > > +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> > > @@ -0,0 +1,45 @@
> > > +# Copyright 2020-2021 Free Software Foundation, Inc.
> >
> > The '2020' date is only needed if the patch was original posted in 2020, or if this file is copied/based on some other in-tree file that is copyright 2020+.
> >
> > > +
> > > +# 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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605806843%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=6EG9MK9nar3SvQCQ14n85uC3sVhIxMx8P5wfRSeLYTk%3D&amp;reserved=0.
> > > +
> > > +# This file is part of the gdb testsuite.  It contains tests for
> > > +fortran # namelist.
> > > +
> > > +if { [skip_fortran_tests] } { return -1 }
> > > +
> > > +standard_testfile .f90
> > > +load_lib "fortran.exp"
> > > +
> > > +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> > > +    return -1
> > > +}
> > > +
> > > +if ![fortran_runto_main] then {
> > > +    perror "couldn't run to main"
> > > +    continue
> > > +}
> > > +
> > > +# Depending on the compiler being used, the type names can be printed differently.
> > > +set int [fortran_int4]
> > > +
> > > +gdb_breakpoint [gdb_get_line_number "Display namelist"]
> > > +gdb_continue_to_breakpoint "Display namelist"
> > > +
> > > +if {[test_compiler_info {gcc-*}]} {
> > > +    gdb_test "ptype nml" "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> > > +    gdb_test "print nml" \\$\[0-9\]+ = \\( a = 10, b = 20
> > > +\\)<file://$/%5b0-9/%5d+%20=%20/(%20a%20=%2010,%20b%20=%2020%20/)>
> >
> > The pattern should be wrapped onto the newline.
> >
> > Thanks,
> > Andrew
> >
> > > +} else {
> > > +    gdb_test "ptype nml" "No symbol \"nml\" in current context\\."
> > > +    gdb_test "print nml" "No symbol \"nml\" in current context\\."
> > > +}
> > > diff --git a/gdb/testsuite/gdb.fortran/namelist.f90
> > > b/gdb/testsuite/gdb.fortran/namelist.f90
> > > new file mode 100644
> > > index 00000000000..00704eddf27
> > > --- /dev/null
> > > +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> > > @@ -0,0 +1,27 @@
> > > +! Copyright 2020-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 https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C6ae3b002df6f4f99442808d9b728e775%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637742208605806843%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=6EG9MK9nar3SvQCQ14n85uC3sVhIxMx8P5wfRSeLYTk%3D&amp;reserved=0.
> > > +!
> > > +! This file is the Fortran source file for namelist.exp.
> > > +
> > > +program main
> > > +
> > > +  integer :: a, b
> > > +  namelist /nml/ a, b
> > > +
> > > +  a = 10
> > > +  b = 20
> > > +  Write(*,nml) ! Display namelist
> > > +
> > > +end program main
> > > diff --git a/include/dwarf2.def b/include/dwarf2.def index
> > > 1ae6e1df298..6b8be1f6a16 100644
> > > --- a/include/dwarf2.def
> > > +++ b/include/dwarf2.def
> > > @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40) DW_AT
> > > (DW_AT_friend, 0x41) DW_AT (DW_AT_identifier_case, 0x42) DW_AT
> > > (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> > > +DW_AT (DW_AT_namelist_item, 0x44)
> > > DW_AT (DW_AT_priority, 0x45)
> > > DW_AT (DW_AT_segment, 0x46)
> > > DW_AT (DW_AT_specification, 0x47)
> > > --
> > > 2.17.1
> > >
> > >
> > >
> >

--
Joel

[-- Attachment #2: 0001-gdb-fortran-Fix-ptype-and-print-commands-for-namelis.patch --]
[-- Type: application/octet-stream, Size: 12373 bytes --]

From a0e67a82709c8753778c02d5438decc7dae33172 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Fri, 8 Oct 2021 02:01:18 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
 variables.

GCC/gfortran support namelist(a fortran feature), it emits
DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does
not process these dies and support namelist variables during
print and ptype commands. When tried to print, it bails out
with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.

This commit is to make the print and ptype commands work for
namelist variables and its items. Sample output of these
commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 11 ++++++
 gdb/gdbtypes.h                         | 13 +++++++
 gdb/testsuite/gdb.fortran/namelist.exp | 50 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 include/dwarf2.def                     |  2 +-
 7 files changed, 145 insertions(+), 8 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index cbd9a3012eb..2629a0ff432 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && ! die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          /* Typically, DW_TAG_namelist_item are references to namelist items.
+             If so, follow that reference.  */
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15635,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15823,7 +15841,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15867,7 +15886,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21971,8 +21992,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22909,6 +22939,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22964,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 27d9a730978..0491bff42aa 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,6 +295,7 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
@@ -320,6 +321,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol
+	            (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index dc575c42996..8da362bddec 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,19 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    /* * Fortran namelist is a group of variables or arrays that can be
+       read or written.
+
+       Namelist syntax: NAMELIST / groupname / namelist_items ...
+       NAMELIST statement assign a group name to a collection of variables
+       called as namelist items. The namelist items can be of any data type
+       and can be variables or arrays.
+
+       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
+       for each of the namelist items. GDB process these namelist dies
+       and print namelist variables during print and ptype commands.  */
+    TYPE_CODE_NAMELIST,
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..2e8325c0b1d
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed
+# differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-12-10 16:18                 ` Kumar N, Bhuvanendra via Gdb-patches
@ 2021-12-20  5:13                   ` Joel Brobecker via Gdb-patches
  2021-12-23 15:51                     ` Kumar N, Bhuvanendra via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Joel Brobecker via Gdb-patches @ 2021-12-20  5:13 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: Achra, Nitika, Andrew Burgess, E, Nagajyothi, Joel Brobecker,
	George, Jini Susan, Sharma, Alok Kumar, gdb-patches

Hi Bhuvan,

> Thanks a lot for your comments. I have tried to address all your
> previous comments. I have attached the revised patch and also inlined.
> Not sure if you see some trailing spaces or indentation issues still,
> mostly they are due to my email client(MS outlook). Please let me know
> if you have any comments. Thanks again.

I believe Andrew had some questions (failed assertion).
https://sourceware.org/pipermail/gdb-patches/2021-December/184362.html

Have you looked into that?

-- 
Joel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-12-20  5:13                   ` Joel Brobecker via Gdb-patches
@ 2021-12-23 15:51                     ` Kumar N, Bhuvanendra via Gdb-patches
  2022-01-20 16:20                       ` Kumar N, Bhuvanendra via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2021-12-23 15:51 UTC (permalink / raw)
  To: Joel Brobecker, Andrew Burgess
  Cc: Achra, Nitika, Andrew Burgess, E, Nagajyothi, George, Jini Susan,
	Sharma, Alok Kumar, gdb-patches

[AMD Official Use Only]

Hi,

I could reproduce the assert that Andrew mentioned with the patch and -D_GLIBCXX_DEBUG=1. I am looking into it.

I had to configure like this as Andrew suggested.

../binutils-gdb/configure  --disable-sim --enable-targets=all CFLAGS="-O0 -g3 -D_GLIBCXX_DEBUG=1" CXXFLAGS="-O0 -g3 -D_GLIBCXX_DEBUG=1"

Regards,
Bhuvan

-----Original Message-----
From: Joel Brobecker <brobecker@adacore.com> 
Sent: Monday, December 20, 2021 10:43 AM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: Joel Brobecker <brobecker@adacore.com>; gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Andrew Burgess <aburgess@redhat.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

Hi Bhuvan,

> Thanks a lot for your comments. I have tried to address all your 
> previous comments. I have attached the revised patch and also inlined.
> Not sure if you see some trailing spaces or indentation issues still, 
> mostly they are due to my email client(MS outlook). Please let me know 
> if you have any comments. Thanks again.

I believe Andrew had some questions (failed assertion).
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceware.org%2Fpipermail%2Fgdb-patches%2F2021-December%2F184362.html&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C0e5d2c316a6743220b7908d9c3777633%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637755740127814129%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=7FIqu1y2JDqVzKKGbOpSS0qOBfZQdofAmYvOYM%2BS2Wk%3D&amp;reserved=0

Have you looked into that?

--
Joel

^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2021-12-23 15:51                     ` Kumar N, Bhuvanendra via Gdb-patches
@ 2022-01-20 16:20                       ` Kumar N, Bhuvanendra via Gdb-patches
  2022-02-03 18:43                         ` Andrew Burgess via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2022-01-20 16:20 UTC (permalink / raw)
  To: Joel Brobecker, Andrew Burgess
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	gdb-patches, E, Nagajyothi

[-- Attachment #1: Type: text/plain, Size: 17545 bytes --]

[AMD Official Use Only]

Hi all,

Sorry for the delay in sharing the revised patch, I was occupied with some other work. Please find the revised patch with all the details and also patch is inlined below.

Reason for the assert failure when GDB is built with -D_GLIBCXX_DEBUG=1 is, the size or length(TYPE_LENGTH) of the namelist variable type was not populated, it was zero, hence assert was failing in gdbsupport/array-view.h. Now this is fixed and I could test with -D_GLIBCXX_DEBUG=1

Compiler is not emitting the size of the namelist variable type, hence GDB is calculating it. In similar types like DW_TAG_structure_type, DW_AT_byte_size attribute is emitted by compiler and GDB uses it with TYPE_LENGTH. It's not the case with DW_TAG_namelist. Hence size of the namelist variable type is calculated in GDB. Also unlike DW_TAG_structure_type, namelist items are not allocated in continuous memory, they are spread across, hence for each namelist item symbol table lookup is done before printing its value. This way making sure namelist items printing is intact.

Regards,
Bhuvan

PATCH inlined:

From 68d315db5488b17b6e47e052947768a4c8a19fa4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Tue, 18 Jan 2022 18:12:33 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
 variables.

Gfortran supports namelist(a fortran feature); it emits
DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
process these dies and does not support 'print' or 'ptype' commands
on namelist variables. An attempt to print namelist variables
results in gdb bailing out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.

This commit is to make the print and ptype commands work for
namelist variables and its items. Sample output of these
commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 24 +++++++++++++
 gdb/gdbtypes.h                         | 13 +++++++
 gdb/testsuite/gdb.fortran/namelist.exp | 50 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 gdb/value.c                            |  2 +-
 include/dwarf2.def                     |  2 +-
 8 files changed, 159 insertions(+), 9 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index cbd9a3012eb..2629a0ff432 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && ! die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          /* Typically, DW_TAG_namelist_item are references to namelist items.
+             If so, follow that reference.  */
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15635,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15823,7 +15841,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15867,7 +15886,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21971,8 +21992,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22909,6 +22939,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22964,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 27d9a730978..48044d1ab1c 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,8 +295,22 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
+      /* Calculate and set the total size or length of the namelist variable
+         type, which is summation of size of each item in the namelist
+         variable. Please note the namelist items are not allocated in
+         continuous memory unlike other types, hence for each namelist item
+         symbol table lookup is done before printing its value.  */
+      if (type->code () == TYPE_CODE_NAMELIST)
+        {
+          unsigned int total_size = 0;
+          for (index = 0; index < type->num_fields (); index++)
+            total_size += TYPE_LENGTH (type->field (index).type ());
+          TYPE_LENGTH (type) = total_size;
+        }
+
       fprintf_filtered (stream, "( ");
       for (index = 0; index < type->num_fields (); index++)
 	{
@@ -320,6 +334,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol
+	            (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index dc575c42996..8da362bddec 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,19 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    /* * Fortran namelist is a group of variables or arrays that can be
+       read or written.
+
+       Namelist syntax: NAMELIST / groupname / namelist_items ...
+       NAMELIST statement assign a group name to a collection of variables
+       called as namelist items. The namelist items can be of any data type
+       and can be variables or arrays.
+
+       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
+       for each of the namelist items. GDB process these namelist dies
+       and print namelist variables during print and ptype commands.  */
+    TYPE_CODE_NAMELIST,
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..2e8325c0b1d
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed
+# differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/gdb/value.c b/gdb/value.c
index bb2adae0a51..16be02fb199 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3901,7 +3901,7 @@ value_fetch_lazy_memory (struct value *val)
   CORE_ADDR addr = value_address (val);
   struct type *type = check_typedef (value_enclosing_type (val));
 
-  if (TYPE_LENGTH (type))
+  if (TYPE_LENGTH (type) && (type->code () != TYPE_CODE_NAMELIST))
       read_value_memory (val, 0, value_stack (val),
 			 addr, value_contents_all_raw (val),
 			 type_length_units (type));
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1



-----Original Message-----
From: Kumar N, Bhuvanendra 
Sent: Thursday, December 23, 2021 9:22 PM
To: Joel Brobecker <brobecker@adacore.com>; Andrew Burgess <aburgess@redhat.com>
Cc: gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Andrew Burgess <aburgess@redhat.com>
Subject: RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[AMD Official Use Only]

Hi,

I could reproduce the assert that Andrew mentioned with the patch and -D_GLIBCXX_DEBUG=1. I am looking into it.

I had to configure like this as Andrew suggested.

../binutils-gdb/configure  --disable-sim --enable-targets=all CFLAGS="-O0 -g3 -D_GLIBCXX_DEBUG=1" CXXFLAGS="-O0 -g3 -D_GLIBCXX_DEBUG=1"

Regards,
Bhuvan

-----Original Message-----
From: Joel Brobecker <brobecker@adacore.com>
Sent: Monday, December 20, 2021 10:43 AM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: Joel Brobecker <brobecker@adacore.com>; gdb-patches@sourceware.org; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; E, Nagajyothi <Nagajyothi.E@amd.com>; Andrew Burgess <aburgess@redhat.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

Hi Bhuvan,

> Thanks a lot for your comments. I have tried to address all your 
> previous comments. I have attached the revised patch and also inlined.
> Not sure if you see some trailing spaces or indentation issues still, 
> mostly they are due to my email client(MS outlook). Please let me know 
> if you have any comments. Thanks again.

I believe Andrew had some questions (failed assertion).
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceware.org%2Fpipermail%2Fgdb-patches%2F2021-December%2F184362.html&amp;data=04%7C01%7CBhuvanendra.KumarN%40amd.com%7C0e5d2c316a6743220b7908d9c3777633%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637755740127814129%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=7FIqu1y2JDqVzKKGbOpSS0qOBfZQdofAmYvOYM%2BS2Wk%3D&amp;reserved=0

Have you looked into that?

--
Joel

[-- Attachment #2: 0001-gdb-fortran-Fix-ptype-and-print-commands-for-namelis.patch --]
[-- Type: application/octet-stream, Size: 13701 bytes --]

From 68d315db5488b17b6e47e052947768a4c8a19fa4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Cbhkumarn=E2=80=9D?= <Bhuvanendra.KumarN@amd.com>
Date: Tue, 18 Jan 2022 18:12:33 +0530
Subject: [PATCH] gdb/fortran: Fix ptype and print commands for namelist
 variables.

Gfortran supports namelist(a fortran feature); it emits
DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
process these dies and does not support 'print' or 'ptype' commands
on namelist variables. An attempt to print namelist variables
results in gdb bailing out with the error message as shown below.
(gdb) print nml
No symbol "nml" in current context.

This commit is to make the print and ptype commands work for
namelist variables and its items. Sample output of these
commands is shared below, with fixed gdb.
(gdb) ptype nml
type = Type nml
    integer(kind=4) :: a
    integer(kind=4) :: b
End Type nml
(gdb) print nml
$1 = ( a = 10, b = 20 )
---
 gdb/dwarf2/read.c                      | 44 +++++++++++++++++++----
 gdb/f-typeprint.c                      |  6 +++-
 gdb/f-valprint.c                       | 24 +++++++++++++
 gdb/gdbtypes.h                         | 13 +++++++
 gdb/testsuite/gdb.fortran/namelist.exp | 50 ++++++++++++++++++++++++++
 gdb/testsuite/gdb.fortran/namelist.f90 | 27 ++++++++++++++
 gdb/value.c                            |  2 +-
 include/dwarf2.def                     |  2 +-
 8 files changed, 159 insertions(+), 9 deletions(-)
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.exp
 create mode 100644 gdb/testsuite/gdb.fortran/namelist.f90

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index cbd9a3012eb..2629a0ff432 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9705,6 +9705,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14562,8 +14563,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && ! die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+          /* Typically, DW_TAG_namelist_item are references to namelist items.
+             If so, follow that reference.  */
+          struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+          struct die_info *item_die = nullptr;
+          struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+            item_die = follow_die_ref (die, attr1, &item_cu);
+          if (item_die != nullptr)
+            die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15621,6 +15635,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15823,7 +15841,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15867,7 +15886,9 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 }
 
 /* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+   its members and creating a symbol for it. This function also
+   handles Fortran namelist variable, its items or members and
+   creating a symbol for it.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21971,8 +21992,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+            }
+	  else
+            {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+            }
 
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
@@ -22909,6 +22939,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22933,6 +22964,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 1791cb29451..5b34622dacb 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 27d9a730978..48044d1ab1c 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -295,8 +295,22 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
+      /* Calculate and set the total size or length of the namelist variable
+         type, which is summation of size of each item in the namelist
+         variable. Please note the namelist items are not allocated in
+         continuous memory unlike other types, hence for each namelist item
+         symbol table lookup is done before printing its value.  */
+      if (type->code () == TYPE_CODE_NAMELIST)
+        {
+          unsigned int total_size = 0;
+          for (index = 0; index < type->num_fields (); index++)
+            total_size += TYPE_LENGTH (type->field (index).type ());
+          TYPE_LENGTH (type) = total_size;
+        }
+
       fprintf_filtered (stream, "( ");
       for (index = 0; index < type->num_fields (); index++)
 	{
@@ -320,6 +334,16 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 		  fputs_filtered (" = ", stream);
 		}
 
+	      /* While printing namelist items, fetch the appropriate value
+	         field before printing its value.  */
+	      if (type->code () == TYPE_CODE_NAMELIST)
+	        {
+	          struct block_symbol symni = lookup_symbol
+	            (field_name, get_selected_block (0), VAR_DOMAIN, nullptr);
+	          if (symni.symbol != nullptr)
+	            field = value_of_variable (symni.symbol, symni.block);
+	        }
+
 	      common_val_print (field, stream, recurse + 1,
 				options, current_language);
 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index dc575c42996..8da362bddec 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -195,6 +195,19 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    /* * Fortran namelist is a group of variables or arrays that can be
+       read or written.
+
+       Namelist syntax: NAMELIST / groupname / namelist_items ...
+       NAMELIST statement assign a group name to a collection of variables
+       called as namelist items. The namelist items can be of any data type
+       and can be variables or arrays.
+
+       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
+       for each of the namelist items. GDB process these namelist dies
+       and print namelist variables during print and ptype commands.  */
+    TYPE_CODE_NAMELIST,
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..2e8325c0b1d
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed
+# differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..fb36690d765
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/gdb/value.c b/gdb/value.c
index bb2adae0a51..16be02fb199 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3901,7 +3901,7 @@ value_fetch_lazy_memory (struct value *val)
   CORE_ADDR addr = value_address (val);
   struct type *type = check_typedef (value_enclosing_type (val));
 
-  if (TYPE_LENGTH (type))
+  if (TYPE_LENGTH (type) && (type->code () != TYPE_CODE_NAMELIST))
       read_value_memory (val, 0, value_stack (val),
 			 addr, value_contents_all_raw (val),
 			 type_length_units (type));
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 1ae6e1df298..6b8be1f6a16 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2022-01-20 16:20                       ` Kumar N, Bhuvanendra via Gdb-patches
@ 2022-02-03 18:43                         ` Andrew Burgess via Gdb-patches
  2022-02-07 14:41                           ` Kumar N, Bhuvanendra via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Andrew Burgess via Gdb-patches @ 2022-02-03 18:43 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: Achra, Nitika, E, Nagajyothi, Joel Brobecker, George, Jini Susan,
	Sharma, Alok Kumar, gdb-patches

* Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2022-01-20 16:20:46 +0000]:

> [AMD Official Use Only]
> 
> Hi all,
> 
> Sorry for the delay in sharing the revised patch, I was occupied with some other work. Please find the revised patch with all the details and also patch is inlined below.
> 
> Reason for the assert failure when GDB is built with
> -D_GLIBCXX_DEBUG=1 is, the size or length(TYPE_LENGTH) of the
> namelist variable type was not populated, it was zero, hence assert
> was failing in gdbsupport/array-view.h. Now this is fixed and I
> could test with -D_GLIBCXX_DEBUG=1
> 
> Compiler is not emitting the size of the namelist variable type,
> hence GDB is calculating it. In similar types like
> DW_TAG_structure_type, DW_AT_byte_size attribute is emitted by
> compiler and GDB uses it with TYPE_LENGTH. It's not the case with
> DW_TAG_namelist. Hence size of the namelist variable type is
> calculated in GDB. Also unlike DW_TAG_structure_type, namelist items
> are not allocated in continuous memory, they are spread across,
> hence for each namelist item symbol table lookup is done before
> printing its value. This way making sure namelist items printing is
> intact.

Hi Bhuvan,

Thanks for continuing to work on this feature, and sorry for the slow
turn around on reviews.

I took a look at the changes you made in the latest version, and I
wasn't completely convinced.  Setting the type length seems like a bad
idea, given that these namelists don't have a valid address, and don't
actually live in memory in a contiguous block.  I assume this is why
you ended up adding the change in value.c too.

I think if we just reorder the code in f-valprint.c a little, then we
can avoid the need to compute the type length.  Could you test the
patch below please, and let me know if you see any problems.

This is basically your work with some whitespace clean up in
dwarf2/read.c, the value.c change reverted, and f-valprint.c reworked
a little.  Oh, and I updated the copyright year in the testsuite
files.

Let me know what you think.

Thanks,
Andrew

---

commit 3b365631ef31051210b7ad26463aaccd3501cbfd
Author: Bhuvanendra Kumar N <Bhuvanendra.KumarN@amd.com>
Date:   Wed Feb 2 17:52:27 2022 +0000

    gdb/fortran: support ptype and print commands for namelist variables
    
    Gfortran supports namelists (a Fortran feature); it emits
    DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
    process these dies and does not support 'print' or 'ptype' commands on
    namelist variables.
    
    An attempt to print namelist variables results in gdb bailing out with
    the error message as shown below.
    
      (gdb) print nml
      No symbol "nml" in current context.
    
    This commit is to make the print and ptype commands work for namelist
    variables and its items. Sample output of these commands is shared
    below, with fixed gdb.
    
      (gdb) ptype nml
      type = Type nml
          integer(kind=4) :: a
          integer(kind=4) :: b
      End Type nml
      (gdb) print nml
      $1 = ( a = 10, b = 20 )

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 1a749eac334..056ba97ee91 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9694,6 +9694,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14556,8 +14557,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
 
   fp = &new_field->field;
 
-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && !die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+	  /* Typically, DW_TAG_namelist_item are references to namelist items.
+	     If so, follow that reference.  */
+	  struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+	  struct die_info *item_die = nullptr;
+	  struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+	    item_die = follow_die_ref (die, attr1, &item_cu);
+	  if (item_die != nullptr)
+	    die = item_die;
+        }
       /* Data member other than a C++ static data member.  */
 
       /* Get type of field.  */
@@ -15615,6 +15629,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT);
@@ -15817,7 +15835,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
 			  struct dwarf2_cu *cu)
 {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
 	 should be a DW_TAG_member that is a declaration, but
@@ -15860,8 +15879,10 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
     handle_variant (child_die, type, fi, template_args, cu);
 }
 
-/* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+/* Finish creating a structure or union type, including filling in its
+   members and creating a symbol for it. This function also handles Fortran
+   namelist variables, their items or members and creating a symbol for
+   them.  */
 
 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -21963,9 +21984,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_union_type:
 	case DW_TAG_set_type:
 	case DW_TAG_enumeration_type:
-	  SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-	  SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-
+	case DW_TAG_namelist:
+	  if (die->tag == DW_TAG_namelist)
+	    {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+	      SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+	    }
+	  else
+	    {
+	      SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+	      SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+	    }
 	  {
 	    /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
 	       really ever be static objects: otherwise, if you try
@@ -22902,6 +22931,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;
 
@@ -22926,6 +22956,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
 	 structures or unions.  These were of the form "._%d" in GCC 4.1,
 	 or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c
index 6fd3d519c86..3b26bf74b61 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
 	prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
 	prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
 	fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 3d13eb11fb0..10dfcaf7c41 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -512,24 +512,38 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
 
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
 	 types.  */
       fprintf_filtered (stream, "( ");
       for (index = 0; index < type->num_fields (); index++)
 	{
-	  struct value *field = value_field (val, index);
-
-	  struct type *field_type = check_typedef (type->field (index).type ());
-
+	  struct type *field_type
+	    = check_typedef (type->field (index).type ());
 
 	  if (field_type->code () != TYPE_CODE_FUNC)
 	    {
-	      const char *field_name;
+	      const char *field_name = type->field (index).name ();
+	      struct value *field;
+
+	      if (type->code () == TYPE_CODE_NAMELIST)
+		{
+		  /* While printing namelist items, fetch the appropriate
+		     value field before printing its value.  */
+		  struct block_symbol sym
+		    = lookup_symbol (field_name, get_selected_block (nullptr),
+				     VAR_DOMAIN, nullptr);
+		  if (sym.symbol == nullptr)
+		    error (_("failed to find symbol for name list component %s"),
+			   field_name);
+		  field = value_of_variable (sym.symbol, sym.block);
+		}
+	      else
+		field = value_field (val, index);
 
 	      if (printed_field > 0)
 		fputs_filtered (", ", stream);
 
-	      field_name = type->field (index).name ();
 	      if (field_name != NULL)
 		{
 		  fputs_styled (field_name, variable_name_style.style (),
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 7238873e4db..5072dc24bfa 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -196,6 +196,19 @@ enum type_code
 
     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    /* * Fortran namelist is a group of variables or arrays that can be
+       read or written.
+
+       Namelist syntax: NAMELIST / groupname / namelist_items ...
+       NAMELIST statement assign a group name to a collection of variables
+       called as namelist items. The namelist items can be of any data type
+       and can be variables or arrays.
+
+       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
+       for each of the namelist items. GDB process these namelist dies
+       and print namelist variables during print and ptype commands.  */
+    TYPE_CODE_NAMELIST,
   };
 
 /* * Some bits for the type's instance_flags word.  See the macros
diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..d6263e12fec
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 2021-2022 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/>.
+
+# This file is part of the gdb testsuite.  It contains tests for fortran
+# namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed
+# differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"]
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..9e2ba0489d2
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 2021-2022 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/>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 4214c80907a..530c6f849f9 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)
 DW_AT (DW_AT_friend, 0x41)
 DW_AT (DW_AT_identifier_case, 0x42)
 DW_AT (DW_AT_macro_info, 0x43)
-DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)


^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2022-02-03 18:43                         ` Andrew Burgess via Gdb-patches
@ 2022-02-07 14:41                           ` Kumar N, Bhuvanendra via Gdb-patches
  2022-02-11 16:20                             ` Andrew Burgess via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2022-02-07 14:41 UTC (permalink / raw)
  To: Andrew Burgess
  Cc: George, Jini Susan, Achra, Nitika, Sharma,  Alok Kumar,
	gdb-patches, Joel Brobecker

[AMD Official Use Only]

Hi Andrew,

Thanks for the revised patch and suggestions, I looked at your code changes (rearranging the code in f-valprint.c), the changes looks fine and also unit and regression tested the changes. Also tested with -D_GLIBCXX_DEBUG=1, even though we are not calling value_field() for namelist now.

Please let me know how to proceed further, thanks again

Regards,
bhuvan

-----Original Message-----
From: Andrew Burgess <aburgess@redhat.com> 
Sent: Friday, February 4, 2022 12:14 AM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: Joel Brobecker <brobecker@adacore.com>; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; gdb-patches@sourceware.org; E, Nagajyothi <Nagajyothi.E@amd.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2022-01-20 16:20:46 +0000]:

> [AMD Official Use Only]
>
> Hi all,
>
> Sorry for the delay in sharing the revised patch, I was occupied with some other work. Please find the revised patch with all the details and also patch is inlined below.
>
> Reason for the assert failure when GDB is built with
> -D_GLIBCXX_DEBUG=1 is, the size or length(TYPE_LENGTH) of the namelist 
> variable type was not populated, it was zero, hence assert was failing 
> in gdbsupport/array-view.h. Now this is fixed and I could test with 
> -D_GLIBCXX_DEBUG=1
>
> Compiler is not emitting the size of the namelist variable type, hence 
> GDB is calculating it. In similar types like DW_TAG_structure_type, 
> DW_AT_byte_size attribute is emitted by compiler and GDB uses it with 
> TYPE_LENGTH. It's not the case with DW_TAG_namelist. Hence size of the 
> namelist variable type is calculated in GDB. Also unlike 
> DW_TAG_structure_type, namelist items are not allocated in continuous 
> memory, they are spread across, hence for each namelist item symbol 
> table lookup is done before printing its value. This way making sure 
> namelist items printing is intact.

Hi Bhuvan,

Thanks for continuing to work on this feature, and sorry for the slow turn around on reviews.

I took a look at the changes you made in the latest version, and I wasn't completely convinced.  Setting the type length seems like a bad idea, given that these namelists don't have a valid address, and don't actually live in memory in a contiguous block.  I assume this is why you ended up adding the change in value.c too.

I think if we just reorder the code in f-valprint.c a little, then we can avoid the need to compute the type length.  Could you test the patch below please, and let me know if you see any problems.

This is basically your work with some whitespace clean up in dwarf2/read.c, the value.c change reverted, and f-valprint.c reworked a little.  Oh, and I updated the copyright year in the testsuite files.

Let me know what you think.

Thanks,
Andrew

---

commit 3b365631ef31051210b7ad26463aaccd3501cbfd
Author: Bhuvanendra Kumar N <Bhuvanendra.KumarN@amd.com>
Date:   Wed Feb 2 17:52:27 2022 +0000

    gdb/fortran: support ptype and print commands for namelist variables

    Gfortran supports namelists (a Fortran feature); it emits
    DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
    process these dies and does not support 'print' or 'ptype' commands on
    namelist variables.

    An attempt to print namelist variables results in gdb bailing out with
    the error message as shown below.

      (gdb) print nml
      No symbol "nml" in current context.

    This commit is to make the print and ptype commands work for namelist
    variables and its items. Sample output of these commands is shared
    below, with fixed gdb.

      (gdb) ptype nml
      type = Type nml
          integer(kind=4) :: a
          integer(kind=4) :: b
      End Type nml
      (gdb) print nml
      $1 = ( a = 10, b = 20 )

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 1a749eac334..056ba97ee91 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -9694,6 +9694,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       process_structure_scope (die, cu);
       break;
     case DW_TAG_enumeration_type:
@@ -14556,8 +14557,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,

   fp = &new_field->field;

-  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
-    {
+  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
+      && !die_is_declaration (die, cu))
+    {
+      if (die->tag == DW_TAG_namelist_item)
+        {
+         /* Typically, DW_TAG_namelist_item are references to namelist items.
+            If so, follow that reference.  */
+         struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
+         struct die_info *item_die = nullptr;
+         struct dwarf2_cu *item_cu = cu;
+          if (attr1->form_is_ref ())
+           item_die = follow_die_ref (die, attr1, &item_cu);
+         if (item_die != nullptr)
+           die = item_die;
+        }
       /* Data member other than a C++ static data member.  */

       /* Get type of field.  */
@@ -15615,6 +15629,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
     {
       type->set_code (TYPE_CODE_UNION);
     }
+  else if (die->tag == DW_TAG_namelist)
+    {
+      type->set_code (TYPE_CODE_NAMELIST);
+    }
   else
     {
       type->set_code (TYPE_CODE_STRUCT); @@ -15817,7 +15835,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
                          struct dwarf2_cu *cu)  {
   if (child_die->tag == DW_TAG_member
-      || child_die->tag == DW_TAG_variable)
+      || child_die->tag == DW_TAG_variable
+      || child_die->tag == DW_TAG_namelist_item)
     {
       /* NOTE: carlton/2002-11-05: A C++ static data member
         should be a DW_TAG_member that is a declaration, but @@ -15860,8 +15879,10 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
     handle_variant (child_die, type, fi, template_args, cu);  }

-/* Finish creating a structure or union type, including filling in
-   its members and creating a symbol for it.  */
+/* Finish creating a structure or union type, including filling in its
+   members and creating a symbol for it. This function also handles Fortran
+   namelist variables, their items or members and creating a symbol for
+   them.  */

 static void
 process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21963,9 +21984,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
        case DW_TAG_union_type:
        case DW_TAG_set_type:
        case DW_TAG_enumeration_type:
-         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
-         SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
-
+       case DW_TAG_namelist:
+         if (die->tag == DW_TAG_namelist)
+           {
+             SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
+             SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
+           }
+         else
+           {
+             SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
+             SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+           }
          {
            /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
               really ever be static objects: otherwise, if you try @@ -22902,6 +22931,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
       && die->tag != DW_TAG_class_type
       && die->tag != DW_TAG_interface_type
       && die->tag != DW_TAG_structure_type
+      && die->tag != DW_TAG_namelist
       && die->tag != DW_TAG_union_type)
     return NULL;

@@ -22926,6 +22956,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
     case DW_TAG_interface_type:
     case DW_TAG_structure_type:
     case DW_TAG_union_type:
+    case DW_TAG_namelist:
       /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
         structures or unions.  These were of the form "._%d" in GCC 4.1,
         or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 6fd3d519c86..3b26bf74b61 100644
--- a/gdb/f-typeprint.c
+++ b/gdb/f-typeprint.c
@@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
     case TYPE_CODE_UNDEF:
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
     case TYPE_CODE_ENUM:
     case TYPE_CODE_INT:
     case TYPE_CODE_FLT:
@@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
       const char *prefix = "";
       if (type->code () == TYPE_CODE_UNION)
        prefix = "Type, C_Union :: ";
-      else if (type->code () == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT
+               || type->code () == TYPE_CODE_NAMELIST)
        prefix = "Type ";
       fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
       return;
@@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,

     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       if (type->code () == TYPE_CODE_UNION)
        fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
       else
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 3d13eb11fb0..10dfcaf7c41 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -512,24 +512,38 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,

     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
+    case TYPE_CODE_NAMELIST:
       /* Starting from the Fortran 90 standard, Fortran supports derived
         types.  */
       fprintf_filtered (stream, "( ");
       for (index = 0; index < type->num_fields (); index++)
        {
-         struct value *field = value_field (val, index);
-
-         struct type *field_type = check_typedef (type->field (index).type ());
-
+         struct type *field_type
+           = check_typedef (type->field (index).type ());

          if (field_type->code () != TYPE_CODE_FUNC)
            {
-             const char *field_name;
+             const char *field_name = type->field (index).name ();
+             struct value *field;
+
+             if (type->code () == TYPE_CODE_NAMELIST)
+               {
+                 /* While printing namelist items, fetch the appropriate
+                    value field before printing its value.  */
+                 struct block_symbol sym
+                   = lookup_symbol (field_name, get_selected_block (nullptr),
+                                    VAR_DOMAIN, nullptr);
+                 if (sym.symbol == nullptr)
+                   error (_("failed to find symbol for name list component %s"),
+                          field_name);
+                 field = value_of_variable (sym.symbol, sym.block);
+               }
+             else
+               field = value_field (val, index);

              if (printed_field > 0)
                fputs_filtered (", ", stream);

-             field_name = type->field (index).name ();
              if (field_name != NULL)
                {
                  fputs_styled (field_name, variable_name_style.style (), diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 7238873e4db..5072dc24bfa 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -196,6 +196,19 @@ enum type_code

     /* * Fixed Point type.  */
     TYPE_CODE_FIXED_POINT,
+
+    /* * Fortran namelist is a group of variables or arrays that can be
+       read or written.
+
+       Namelist syntax: NAMELIST / groupname / namelist_items ...
+       NAMELIST statement assign a group name to a collection of variables
+       called as namelist items. The namelist items can be of any data type
+       and can be variables or arrays.
+
+       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
+       for each of the namelist items. GDB process these namelist dies
+       and print namelist variables during print and ptype commands.  */
+    TYPE_CODE_NAMELIST,
   };

 /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
new file mode 100644
index 00000000000..d6263e12fec
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.exp
@@ -0,0 +1,50 @@
+# Copyright (C) 2021-2022 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7Cbhuvanendra.kumarn%40amd.com%7C61b9987b80a841d7bf8e08d9e745279b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637795106480474874%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=U2mggF3i%2BjaettHJ9HjvyEFyj5%2B334T0VE56jqmS6oc%3D&amp;reserved=0>.
+
+# This file is part of the gdb testsuite.  It contains tests for 
+fortran # namelist.
+
+if { [skip_fortran_tests] } { return -1 }
+
+standard_testfile .f90
+load_lib "fortran.exp"
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
+    return -1
+}
+
+if ![fortran_runto_main] then {
+    perror "couldn't run to main"
+    continue
+}
+
+# Depending on the compiler being used, the type names can be printed # 
+differently.
+set int [fortran_int4]
+
+gdb_breakpoint [gdb_get_line_number "Display namelist"] 
+gdb_continue_to_breakpoint "Display namelist"
+
+if {[test_compiler_info {gcc-*}]} {
+    gdb_test "ptype nml" \
+        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
+    gdb_test "print nml" \
+        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
+} else {
+    gdb_test "ptype nml" \
+        "No symbol \"nml\" in current context\\."
+    gdb_test "print nml" \
+        "No symbol \"nml\" in current context\\."
+}
diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
new file mode 100644
index 00000000000..9e2ba0489d2
--- /dev/null
+++ b/gdb/testsuite/gdb.fortran/namelist.f90
@@ -0,0 +1,27 @@
+! Copyright (C) 2021-2022 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7Cbhuvanendra.kumarn%40amd.com%7C61b9987b80a841d7bf8e08d9e745279b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637795106480474874%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=U2mggF3i%2BjaettHJ9HjvyEFyj5%2B334T0VE56jqmS6oc%3D&amp;reserved=0>.
+!
+! This file is the Fortran source file for namelist.exp.
+
+program main
+
+  integer :: a, b
+  namelist /nml/ a, b
+
+  a = 10
+  b = 20
+  Write(*,nml) ! Display namelist
+
+end program main
diff --git a/include/dwarf2.def b/include/dwarf2.def index 4214c80907a..530c6f849f9 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
+DW_AT (DW_AT_namelist_item, 0x44)
 DW_AT (DW_AT_priority, 0x45)
 DW_AT (DW_AT_segment, 0x46)
 DW_AT (DW_AT_specification, 0x47)

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2022-02-07 14:41                           ` Kumar N, Bhuvanendra via Gdb-patches
@ 2022-02-11 16:20                             ` Andrew Burgess via Gdb-patches
  2022-02-11 16:39                               ` Kumar N, Bhuvanendra via Gdb-patches
  0 siblings, 1 reply; 21+ messages in thread
From: Andrew Burgess via Gdb-patches @ 2022-02-11 16:20 UTC (permalink / raw)
  To: Kumar N, Bhuvanendra
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	Joel Brobecker, gdb-patches

* Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2022-02-07 14:41:09 +0000]:

> [AMD Official Use Only]
> 
> Hi Andrew,
> 
> Thanks for the revised patch and suggestions, I looked at your code changes (rearranging the code in f-valprint.c), the changes looks fine and also unit and regression tested the changes. Also tested with -D_GLIBCXX_DEBUG=1, even though we are not calling value_field() for namelist now.
> 
> Please let me know how to proceed further, thanks again

Thanks, I pushed this patch.

Andrew



> 
> Regards,
> bhuvan
> 
> -----Original Message-----
> From: Andrew Burgess <aburgess@redhat.com> 
> Sent: Friday, February 4, 2022 12:14 AM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: Joel Brobecker <brobecker@adacore.com>; George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; gdb-patches@sourceware.org; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
> 
> [CAUTION: External Email]
> 
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2022-01-20 16:20:46 +0000]:
> 
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Sorry for the delay in sharing the revised patch, I was occupied with some other work. Please find the revised patch with all the details and also patch is inlined below.
> >
> > Reason for the assert failure when GDB is built with
> > -D_GLIBCXX_DEBUG=1 is, the size or length(TYPE_LENGTH) of the namelist 
> > variable type was not populated, it was zero, hence assert was failing 
> > in gdbsupport/array-view.h. Now this is fixed and I could test with 
> > -D_GLIBCXX_DEBUG=1
> >
> > Compiler is not emitting the size of the namelist variable type, hence 
> > GDB is calculating it. In similar types like DW_TAG_structure_type, 
> > DW_AT_byte_size attribute is emitted by compiler and GDB uses it with 
> > TYPE_LENGTH. It's not the case with DW_TAG_namelist. Hence size of the 
> > namelist variable type is calculated in GDB. Also unlike 
> > DW_TAG_structure_type, namelist items are not allocated in continuous 
> > memory, they are spread across, hence for each namelist item symbol 
> > table lookup is done before printing its value. This way making sure 
> > namelist items printing is intact.
> 
> Hi Bhuvan,
> 
> Thanks for continuing to work on this feature, and sorry for the slow turn around on reviews.
> 
> I took a look at the changes you made in the latest version, and I wasn't completely convinced.  Setting the type length seems like a bad idea, given that these namelists don't have a valid address, and don't actually live in memory in a contiguous block.  I assume this is why you ended up adding the change in value.c too.
> 
> I think if we just reorder the code in f-valprint.c a little, then we can avoid the need to compute the type length.  Could you test the patch below please, and let me know if you see any problems.
> 
> This is basically your work with some whitespace clean up in dwarf2/read.c, the value.c change reverted, and f-valprint.c reworked a little.  Oh, and I updated the copyright year in the testsuite files.
> 
> Let me know what you think.
> 
> Thanks,
> Andrew
> 
> ---
> 
> commit 3b365631ef31051210b7ad26463aaccd3501cbfd
> Author: Bhuvanendra Kumar N <Bhuvanendra.KumarN@amd.com>
> Date:   Wed Feb 2 17:52:27 2022 +0000
> 
>     gdb/fortran: support ptype and print commands for namelist variables
> 
>     Gfortran supports namelists (a Fortran feature); it emits
>     DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
>     process these dies and does not support 'print' or 'ptype' commands on
>     namelist variables.
> 
>     An attempt to print namelist variables results in gdb bailing out with
>     the error message as shown below.
> 
>       (gdb) print nml
>       No symbol "nml" in current context.
> 
>     This commit is to make the print and ptype commands work for namelist
>     variables and its items. Sample output of these commands is shared
>     below, with fixed gdb.
> 
>       (gdb) ptype nml
>       type = Type nml
>           integer(kind=4) :: a
>           integer(kind=4) :: b
>       End Type nml
>       (gdb) print nml
>       $1 = ( a = 10, b = 20 )
> 
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 1a749eac334..056ba97ee91 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9694,6 +9694,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14556,8 +14557,21 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
> 
>    fp = &new_field->field;
> 
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +      && !die_is_declaration (die, cu))
> +    {
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +         /* Typically, DW_TAG_namelist_item are references to namelist items.
> +            If so, follow that reference.  */
> +         struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +         struct die_info *item_die = nullptr;
> +         struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +           item_die = follow_die_ref (die, attr1, &item_cu);
> +         if (item_die != nullptr)
> +           die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
> 
>        /* Get type of field.  */
> @@ -15615,6 +15629,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      {
>        type->set_code (TYPE_CODE_UNION);
>      }
> +  else if (die->tag == DW_TAG_namelist)
> +    {
> +      type->set_code (TYPE_CODE_NAMELIST);
> +    }
>    else
>      {
>        type->set_code (TYPE_CODE_STRUCT); @@ -15817,7 +15835,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                           struct dwarf2_cu *cu)  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>          should be a DW_TAG_member that is a declaration, but @@ -15860,8 +15879,10 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>      handle_variant (child_die, type, fi, template_args, cu);  }
> 
> -/* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +/* Finish creating a structure or union type, including filling in its
> +   members and creating a symbol for it. This function also handles Fortran
> +   namelist variables, their items or members and creating a symbol for
> +   them.  */
> 
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21963,9 +21984,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>         case DW_TAG_union_type:
>         case DW_TAG_set_type:
>         case DW_TAG_enumeration_type:
> -         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -         SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> -
> +       case DW_TAG_namelist:
> +         if (die->tag == DW_TAG_namelist)
> +           {
> +             SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +             SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +           }
> +         else
> +           {
> +             SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +             SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +           }
>           {
>             /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
>                really ever be static objects: otherwise, if you try @@ -22902,6 +22931,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
> 
> @@ -22926,6 +22956,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>          structures or unions.  These were of the form "._%d" in GCC 4.1,
>          or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 6fd3d519c86..3b26bf74b61 100644
> --- a/gdb/f-typeprint.c
> +++ b/gdb/f-typeprint.c
> @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>        const char *prefix = "";
>        if (type->code () == TYPE_CODE_UNION)
>         prefix = "Type, C_Union :: ";
> -      else if (type->code () == TYPE_CODE_STRUCT)
> +      else if (type->code () == TYPE_CODE_STRUCT
> +               || type->code () == TYPE_CODE_NAMELIST)
>         prefix = "Type ";
>        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
>        return;
> @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
> 
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        if (type->code () == TYPE_CODE_UNION)
>         fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
>        else
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 3d13eb11fb0..10dfcaf7c41 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -512,24 +512,38 @@ f_language::value_print_inner (struct value *val, struct ui_file *stream,
> 
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        /* Starting from the Fortran 90 standard, Fortran supports derived
>          types.  */
>        fprintf_filtered (stream, "( ");
>        for (index = 0; index < type->num_fields (); index++)
>         {
> -         struct value *field = value_field (val, index);
> -
> -         struct type *field_type = check_typedef (type->field (index).type ());
> -
> +         struct type *field_type
> +           = check_typedef (type->field (index).type ());
> 
>           if (field_type->code () != TYPE_CODE_FUNC)
>             {
> -             const char *field_name;
> +             const char *field_name = type->field (index).name ();
> +             struct value *field;
> +
> +             if (type->code () == TYPE_CODE_NAMELIST)
> +               {
> +                 /* While printing namelist items, fetch the appropriate
> +                    value field before printing its value.  */
> +                 struct block_symbol sym
> +                   = lookup_symbol (field_name, get_selected_block (nullptr),
> +                                    VAR_DOMAIN, nullptr);
> +                 if (sym.symbol == nullptr)
> +                   error (_("failed to find symbol for name list component %s"),
> +                          field_name);
> +                 field = value_of_variable (sym.symbol, sym.block);
> +               }
> +             else
> +               field = value_field (val, index);
> 
>               if (printed_field > 0)
>                 fputs_filtered (", ", stream);
> 
> -             field_name = type->field (index).name ();
>               if (field_name != NULL)
>                 {
>                   fputs_styled (field_name, variable_name_style.style (), diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 7238873e4db..5072dc24bfa 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -196,6 +196,19 @@ enum type_code
> 
>      /* * Fixed Point type.  */
>      TYPE_CODE_FIXED_POINT,
> +
> +    /* * Fortran namelist is a group of variables or arrays that can be
> +       read or written.
> +
> +       Namelist syntax: NAMELIST / groupname / namelist_items ...
> +       NAMELIST statement assign a group name to a collection of variables
> +       called as namelist items. The namelist items can be of any data type
> +       and can be variables or arrays.
> +
> +       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
> +       for each of the namelist items. GDB process these namelist dies
> +       and print namelist variables during print and ptype commands.  */
> +    TYPE_CODE_NAMELIST,
>    };
> 
>  /* * Some bits for the type's instance_flags word.  See the macros diff --git a/gdb/testsuite/gdb.fortran/namelist.exp b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..d6263e12fec
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,50 @@
> +# Copyright (C) 2021-2022 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7Cbhuvanendra.kumarn%40amd.com%7C61b9987b80a841d7bf8e08d9e745279b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637795106480474874%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=U2mggF3i%2BjaettHJ9HjvyEFyj5%2B334T0VE56jqmS6oc%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed # 
> +differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..9e2ba0489d2
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 2021-2022 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7Cbhuvanendra.kumarn%40amd.com%7C61b9987b80a841d7bf8e08d9e745279b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637795106480474874%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=U2mggF3i%2BjaettHJ9HjvyEFyj5%2B334T0VE56jqmS6oc%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 4214c80907a..530c6f849f9 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)


^ permalink raw reply	[flat|nested] 21+ messages in thread

* RE: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)
  2022-02-11 16:20                             ` Andrew Burgess via Gdb-patches
@ 2022-02-11 16:39                               ` Kumar N, Bhuvanendra via Gdb-patches
  0 siblings, 0 replies; 21+ messages in thread
From: Kumar N, Bhuvanendra via Gdb-patches @ 2022-02-11 16:39 UTC (permalink / raw)
  To: Andrew Burgess
  Cc: George, Jini Susan, Achra, Nitika, Sharma, Alok Kumar,
	Joel Brobecker, gdb-patches

[AMD Official Use Only]

Thanks a lot Andrew and Joel for the valuable review comments

regards,
bhuvan

-----Original Message-----
From: Andrew Burgess <aburgess@redhat.com> 
Sent: Friday, February 11, 2022 9:51 PM
To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
Cc: George, Jini Susan <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; gdb-patches@sourceware.org; Joel Brobecker <brobecker@adacore.com>
Subject: Re: [PATCH] Fix ptype and print commands for namelist variables(a fortran feature)

[CAUTION: External Email]

* Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2022-02-07 14:41:09 +0000]:

> [AMD Official Use Only]
>
> Hi Andrew,
>
> Thanks for the revised patch and suggestions, I looked at your code changes (rearranging the code in f-valprint.c), the changes looks fine and also unit and regression tested the changes. Also tested with -D_GLIBCXX_DEBUG=1, even though we are not calling value_field() for namelist now.
>
> Please let me know how to proceed further, thanks again

Thanks, I pushed this patch.

Andrew



>
> Regards,
> bhuvan
>
> -----Original Message-----
> From: Andrew Burgess <aburgess@redhat.com>
> Sent: Friday, February 4, 2022 12:14 AM
> To: Kumar N, Bhuvanendra <Bhuvanendra.KumarN@amd.com>
> Cc: Joel Brobecker <brobecker@adacore.com>; George, Jini Susan 
> <JiniSusan.George@amd.com>; Achra, Nitika <Nitika.Achra@amd.com>; 
> Sharma, Alok Kumar <AlokKumar.Sharma@amd.com>; 
> gdb-patches@sourceware.org; E, Nagajyothi <Nagajyothi.E@amd.com>
> Subject: Re: [PATCH] Fix ptype and print commands for namelist 
> variables(a fortran feature)
>
> [CAUTION: External Email]
>
> * Kumar N, Bhuvanendra via Gdb-patches <gdb-patches@sourceware.org> [2022-01-20 16:20:46 +0000]:
>
> > [AMD Official Use Only]
> >
> > Hi all,
> >
> > Sorry for the delay in sharing the revised patch, I was occupied with some other work. Please find the revised patch with all the details and also patch is inlined below.
> >
> > Reason for the assert failure when GDB is built with
> > -D_GLIBCXX_DEBUG=1 is, the size or length(TYPE_LENGTH) of the 
> > namelist variable type was not populated, it was zero, hence assert 
> > was failing in gdbsupport/array-view.h. Now this is fixed and I 
> > could test with
> > -D_GLIBCXX_DEBUG=1
> >
> > Compiler is not emitting the size of the namelist variable type, 
> > hence GDB is calculating it. In similar types like 
> > DW_TAG_structure_type, DW_AT_byte_size attribute is emitted by 
> > compiler and GDB uses it with TYPE_LENGTH. It's not the case with 
> > DW_TAG_namelist. Hence size of the namelist variable type is 
> > calculated in GDB. Also unlike DW_TAG_structure_type, namelist items 
> > are not allocated in continuous memory, they are spread across, 
> > hence for each namelist item symbol table lookup is done before 
> > printing its value. This way making sure namelist items printing is intact.
>
> Hi Bhuvan,
>
> Thanks for continuing to work on this feature, and sorry for the slow turn around on reviews.
>
> I took a look at the changes you made in the latest version, and I wasn't completely convinced.  Setting the type length seems like a bad idea, given that these namelists don't have a valid address, and don't actually live in memory in a contiguous block.  I assume this is why you ended up adding the change in value.c too.
>
> I think if we just reorder the code in f-valprint.c a little, then we can avoid the need to compute the type length.  Could you test the patch below please, and let me know if you see any problems.
>
> This is basically your work with some whitespace clean up in dwarf2/read.c, the value.c change reverted, and f-valprint.c reworked a little.  Oh, and I updated the copyright year in the testsuite files.
>
> Let me know what you think.
>
> Thanks,
> Andrew
>
> ---
>
> commit 3b365631ef31051210b7ad26463aaccd3501cbfd
> Author: Bhuvanendra Kumar N <Bhuvanendra.KumarN@amd.com>
> Date:   Wed Feb 2 17:52:27 2022 +0000
>
>     gdb/fortran: support ptype and print commands for namelist 
> variables
>
>     Gfortran supports namelists (a Fortran feature); it emits
>     DW_TAG_namelist and DW_TAG_namelist_item dies. But gdb does not
>     process these dies and does not support 'print' or 'ptype' commands on
>     namelist variables.
>
>     An attempt to print namelist variables results in gdb bailing out with
>     the error message as shown below.
>
>       (gdb) print nml
>       No symbol "nml" in current context.
>
>     This commit is to make the print and ptype commands work for namelist
>     variables and its items. Sample output of these commands is shared
>     below, with fixed gdb.
>
>       (gdb) ptype nml
>       type = Type nml
>           integer(kind=4) :: a
>           integer(kind=4) :: b
>       End Type nml
>       (gdb) print nml
>       $1 = ( a = 10, b = 20 )
>
> diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 
> 1a749eac334..056ba97ee91 100644
> --- a/gdb/dwarf2/read.c
> +++ b/gdb/dwarf2/read.c
> @@ -9694,6 +9694,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        process_structure_scope (die, cu);
>        break;
>      case DW_TAG_enumeration_type:
> @@ -14556,8 +14557,21 @@ dwarf2_add_field (struct field_info *fip, 
> struct die_info *die,
>
>    fp = &new_field->field;
>
> -  if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
> -    {
> +  if ((die->tag == DW_TAG_member || die->tag == DW_TAG_namelist_item)
> +      && !die_is_declaration (die, cu))
> +    {
> +      if (die->tag == DW_TAG_namelist_item)
> +        {
> +         /* Typically, DW_TAG_namelist_item are references to namelist items.
> +            If so, follow that reference.  */
> +         struct attribute *attr1 = dwarf2_attr (die, DW_AT_namelist_item, cu);
> +         struct die_info *item_die = nullptr;
> +         struct dwarf2_cu *item_cu = cu;
> +          if (attr1->form_is_ref ())
> +           item_die = follow_die_ref (die, attr1, &item_cu);
> +         if (item_die != nullptr)
> +           die = item_die;
> +        }
>        /* Data member other than a C++ static data member.  */
>
>        /* Get type of field.  */
> @@ -15615,6 +15629,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
>      {
>        type->set_code (TYPE_CODE_UNION);
>      }
> +  else if (die->tag == DW_TAG_namelist)
> +    {
> +      type->set_code (TYPE_CODE_NAMELIST);
> +    }
>    else
>      {
>        type->set_code (TYPE_CODE_STRUCT); @@ -15817,7 +15835,8 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>                           struct dwarf2_cu *cu)  {
>    if (child_die->tag == DW_TAG_member
> -      || child_die->tag == DW_TAG_variable)
> +      || child_die->tag == DW_TAG_variable
> +      || child_die->tag == DW_TAG_namelist_item)
>      {
>        /* NOTE: carlton/2002-11-05: A C++ static data member
>          should be a DW_TAG_member that is a declaration, but @@ -15860,8 +15879,10 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
>      handle_variant (child_die, type, fi, template_args, cu);  }
>
> -/* Finish creating a structure or union type, including filling in
> -   its members and creating a symbol for it.  */
> +/* Finish creating a structure or union type, including filling in its
> +   members and creating a symbol for it. This function also handles Fortran
> +   namelist variables, their items or members and creating a symbol for
> +   them.  */
>
>  static void
>  process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) @@ -21963,9 +21984,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
>         case DW_TAG_union_type:
>         case DW_TAG_set_type:
>         case DW_TAG_enumeration_type:
> -         SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> -         SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> -
> +       case DW_TAG_namelist:
> +         if (die->tag == DW_TAG_namelist)
> +           {
> +             SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
> +             SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
> +           }
> +         else
> +           {
> +             SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
> +             SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
> +           }
>           {
>             /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
>                really ever be static objects: otherwise, if you try @@ -22902,6 +22931,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>        && die->tag != DW_TAG_class_type
>        && die->tag != DW_TAG_interface_type
>        && die->tag != DW_TAG_structure_type
> +      && die->tag != DW_TAG_namelist
>        && die->tag != DW_TAG_union_type)
>      return NULL;
>
> @@ -22926,6 +22956,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
>      case DW_TAG_interface_type:
>      case DW_TAG_structure_type:
>      case DW_TAG_union_type:
> +    case DW_TAG_namelist:
>        /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
>          structures or unions.  These were of the form "._%d" in GCC 4.1,
>          or simply "<anonymous struct>" or "<anonymous union>" in GCC 
> 4.3 diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 
> 6fd3d519c86..3b26bf74b61 100644
> --- a/gdb/f-typeprint.c
> +++ b/gdb/f-typeprint.c
> @@ -121,6 +121,7 @@ f_language::f_type_print_varspec_prefix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -261,6 +262,7 @@ f_language::f_type_print_varspec_suffix (struct type *type,
>      case TYPE_CODE_UNDEF:
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>      case TYPE_CODE_ENUM:
>      case TYPE_CODE_INT:
>      case TYPE_CODE_FLT:
> @@ -305,7 +307,8 @@ f_language::f_type_print_base (struct type *type, struct ui_file *stream,
>        const char *prefix = "";
>        if (type->code () == TYPE_CODE_UNION)
>         prefix = "Type, C_Union :: ";
> -      else if (type->code () == TYPE_CODE_STRUCT)
> +      else if (type->code () == TYPE_CODE_STRUCT
> +               || type->code () == TYPE_CODE_NAMELIST)
>         prefix = "Type ";
>        fprintf_filtered (stream, "%*s%s%s", level, "", prefix, type->name ());
>        return;
> @@ -391,6 +394,7 @@ f_language::f_type_print_base (struct type *type, 
> struct ui_file *stream,
>
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        if (type->code () == TYPE_CODE_UNION)
>         fprintf_filtered (stream, "%*sType, C_Union :: ", level, "");
>        else
> diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 
> 3d13eb11fb0..10dfcaf7c41 100644
> --- a/gdb/f-valprint.c
> +++ b/gdb/f-valprint.c
> @@ -512,24 +512,38 @@ f_language::value_print_inner (struct value 
> *val, struct ui_file *stream,
>
>      case TYPE_CODE_STRUCT:
>      case TYPE_CODE_UNION:
> +    case TYPE_CODE_NAMELIST:
>        /* Starting from the Fortran 90 standard, Fortran supports derived
>          types.  */
>        fprintf_filtered (stream, "( ");
>        for (index = 0; index < type->num_fields (); index++)
>         {
> -         struct value *field = value_field (val, index);
> -
> -         struct type *field_type = check_typedef (type->field (index).type ());
> -
> +         struct type *field_type
> +           = check_typedef (type->field (index).type ());
>
>           if (field_type->code () != TYPE_CODE_FUNC)
>             {
> -             const char *field_name;
> +             const char *field_name = type->field (index).name ();
> +             struct value *field;
> +
> +             if (type->code () == TYPE_CODE_NAMELIST)
> +               {
> +                 /* While printing namelist items, fetch the appropriate
> +                    value field before printing its value.  */
> +                 struct block_symbol sym
> +                   = lookup_symbol (field_name, get_selected_block (nullptr),
> +                                    VAR_DOMAIN, nullptr);
> +                 if (sym.symbol == nullptr)
> +                   error (_("failed to find symbol for name list component %s"),
> +                          field_name);
> +                 field = value_of_variable (sym.symbol, sym.block);
> +               }
> +             else
> +               field = value_field (val, index);
>
>               if (printed_field > 0)
>                 fputs_filtered (", ", stream);
>
> -             field_name = type->field (index).name ();
>               if (field_name != NULL)
>                 {
>                   fputs_styled (field_name, variable_name_style.style 
> (), diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 
> 7238873e4db..5072dc24bfa 100644
> --- a/gdb/gdbtypes.h
> +++ b/gdb/gdbtypes.h
> @@ -196,6 +196,19 @@ enum type_code
>
>      /* * Fixed Point type.  */
>      TYPE_CODE_FIXED_POINT,
> +
> +    /* * Fortran namelist is a group of variables or arrays that can be
> +       read or written.
> +
> +       Namelist syntax: NAMELIST / groupname / namelist_items ...
> +       NAMELIST statement assign a group name to a collection of variables
> +       called as namelist items. The namelist items can be of any data type
> +       and can be variables or arrays.
> +
> +       Compiler emit DW_TAG_namelist for group name and DW_TAG_namelist_item
> +       for each of the namelist items. GDB process these namelist dies
> +       and print namelist variables during print and ptype commands.  */
> +    TYPE_CODE_NAMELIST,
>    };
>
>  /* * Some bits for the type's instance_flags word.  See the macros 
> diff --git a/gdb/testsuite/gdb.fortran/namelist.exp 
> b/gdb/testsuite/gdb.fortran/namelist.exp
> new file mode 100644
> index 00000000000..d6263e12fec
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.exp
> @@ -0,0 +1,50 @@
> +# Copyright (C) 2021-2022 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7Cbhuvanendra.kumarn%40amd.com%7Cb14ff209f3e6461accc708d9ed7a8087%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637801932676939523%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=lzid16khZ3Yh0y7F2dQhtLak89zk5lu%2F4k4ckPSm2lI%3D&amp;reserved=0>.
> +
> +# This file is part of the gdb testsuite.  It contains tests for 
> +fortran # namelist.
> +
> +if { [skip_fortran_tests] } { return -1 }
> +
> +standard_testfile .f90
> +load_lib "fortran.exp"
> +
> +if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug f90}]} {
> +    return -1
> +}
> +
> +if ![fortran_runto_main] then {
> +    perror "couldn't run to main"
> +    continue
> +}
> +
> +# Depending on the compiler being used, the type names can be printed 
> +# differently.
> +set int [fortran_int4]
> +
> +gdb_breakpoint [gdb_get_line_number "Display namelist"] 
> +gdb_continue_to_breakpoint "Display namelist"
> +
> +if {[test_compiler_info {gcc-*}]} {
> +    gdb_test "ptype nml" \
> +        "type = Type nml\r\n *$int :: a\r\n *$int :: b\r\n *End Type nml"
> +    gdb_test "print nml" \
> +        "\\$\[0-9\]+ = \\( a = 10, b = 20 \\)"
> +} else {
> +    gdb_test "ptype nml" \
> +        "No symbol \"nml\" in current context\\."
> +    gdb_test "print nml" \
> +        "No symbol \"nml\" in current context\\."
> +}
> diff --git a/gdb/testsuite/gdb.fortran/namelist.f90 
> b/gdb/testsuite/gdb.fortran/namelist.f90
> new file mode 100644
> index 00000000000..9e2ba0489d2
> --- /dev/null
> +++ b/gdb/testsuite/gdb.fortran/namelist.f90
> @@ -0,0 +1,27 @@
> +! Copyright (C) 2021-2022 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 <https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.gnu.org%2Flicenses%2F&amp;data=04%7C01%7Cbhuvanendra.kumarn%40amd.com%7Cb14ff209f3e6461accc708d9ed7a8087%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637801932676939523%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=lzid16khZ3Yh0y7F2dQhtLak89zk5lu%2F4k4ckPSm2lI%3D&amp;reserved=0>.
> +!
> +! This file is the Fortran source file for namelist.exp.
> +
> +program main
> +
> +  integer :: a, b
> +  namelist /nml/ a, b
> +
> +  a = 10
> +  b = 20
> +  Write(*,nml) ! Display namelist
> +
> +end program main
> diff --git a/include/dwarf2.def b/include/dwarf2.def index 
> 4214c80907a..530c6f849f9 100644
> --- a/include/dwarf2.def
> +++ b/include/dwarf2.def
> @@ -289,7 +289,7 @@ DW_AT (DW_AT_frame_base, 0x40)  DW_AT 
> (DW_AT_friend, 0x41)  DW_AT (DW_AT_identifier_case, 0x42)  DW_AT 
> (DW_AT_macro_info, 0x43) -DW_AT (DW_AT_namelist_items, 0x44)
> +DW_AT (DW_AT_namelist_item, 0x44)
>  DW_AT (DW_AT_priority, 0x45)
>  DW_AT (DW_AT_segment, 0x46)
>  DW_AT (DW_AT_specification, 0x47)

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2022-02-11 16:40 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-24  9:16 [PATCH] Fix ptype and print commands for namelist variables(a fortran feature) Kumar N, Bhuvanendra via Gdb-patches
2021-08-24  9:21 ` Kumar N, Bhuvanendra via Gdb-patches
2021-09-20  9:41 ` Andrew Burgess
2021-09-22 12:38   ` Kumar N, Bhuvanendra via Gdb-patches
2021-10-06 15:51     ` Andrew Burgess
2021-10-07 21:05       ` Kumar N, Bhuvanendra via Gdb-patches
2021-10-18 17:02         ` Kumar N, Bhuvanendra via Gdb-patches
2021-11-04 15:50         ` Andrew Burgess via Gdb-patches
2021-11-19 14:09         ` FW: " Kumar N, Bhuvanendra via Gdb-patches
2021-11-19 14:32           ` Kumar N, Bhuvanendra via Gdb-patches
2021-12-03 18:56             ` Kumar N, Bhuvanendra via Gdb-patches
2021-12-04 13:20               ` Joel Brobecker via Gdb-patches
2021-12-10 16:18                 ` Kumar N, Bhuvanendra via Gdb-patches
2021-12-20  5:13                   ` Joel Brobecker via Gdb-patches
2021-12-23 15:51                     ` Kumar N, Bhuvanendra via Gdb-patches
2022-01-20 16:20                       ` Kumar N, Bhuvanendra via Gdb-patches
2022-02-03 18:43                         ` Andrew Burgess via Gdb-patches
2022-02-07 14:41                           ` Kumar N, Bhuvanendra via Gdb-patches
2022-02-11 16:20                             ` Andrew Burgess via Gdb-patches
2022-02-11 16:39                               ` Kumar N, Bhuvanendra via Gdb-patches
2021-12-09 13:16             ` Andrew Burgess via Gdb-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox