public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
@ 2013-11-09 14:27 Tobias Burnus
  2013-11-11 19:07 ` Cary Coutant
  2013-11-24 13:44 ` Tobias Burnus
  0 siblings, 2 replies; 9+ messages in thread
From: Tobias Burnus @ 2013-11-09 14:27 UTC (permalink / raw)
  To: gcc patches, gfortran, Jakub Jelinek, Tom Tromey

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

Hi all,

I have a problem generating DW_TAG_namelist dies in conjunction with 
USE-only association.

For a NAMELIST in a module on in a procedure (subroutine, function), one 
generates a DW_TAG_namelist which contains a list of 
DW_TAG_namelist_item. (Works, except that gdb doesn't support 
DW_TAG_namelist at all, cf. Sourceware/gdb PR fortran/15353.)

For "USE mod_name", one just generates DW_TAG_imported_module – and the 
debugger has to find the variables/namelists itself. (Also works.)

But for "USE mod_name, only: nml", one is supposed to generate a 
DW_TAG_imported_declaration.

And there I am stuck. For normal variables, the 
DW_TAG_imported_declaration refers to a DW_TAG_variable die. 
Analogously, for a namelist one would have to refer to a DW_TAG_namelist 
die. But such DW_TAG_namelist comes with a DW_TAG_namelist_item list. 
And for the latter, one needs to have the die of all variables in the 
namelist. But with use-only the symbols aren't use associate and no decl 
or die exists. (Failing call tree with the patch: gfc_trans_use_stmts -> 
dwarf2out_imported_module_or_decl_1 -> force_decl_die.)

What's the proper DWARF way of handling this? Creating a DW_TAG_namelist 
without any DW_TAG_namelist_items, relying on the debugger to pick those 
from the module? Or how is one supposed to handle it?

Would as a first step the patch be acceptable without the change in 
gfc_trans_use_stmts? Without those bits, the patch works and just 
doesn't attempt to generate the DW_TAG_imported_declaration for use-only.

* * *

Regarding the attached patch: It is based on 
http://gcc.gnu.org/ml/gcc-patches/2013-06/msg00534.html and handles
- Namelists in subroutines/functions
- Namelists in modules
- USE association without ONLY

It doesn't handle (see above) USE association with ONLY. (Side note: 
Namelists may not be renamed. [The namelist name appears in the file 
when doing I/O, thus, renaming doesn't make sense.])

For

    integer :: i,
    real :: r
    NAMELIST /nml/ i, r
GCC now generates the output:

  <2><238>: Abbrev Number: 11 (DW_TAG_namelist)
     <239>   DW_AT_name        : nml
     <23d>   DW_AT_sibling     : <0x24c>
  <3><241>: Abbrev Number: 12 (DW_TAG_namelist_item)
     <242>   DW_AT_namelist_items: <0x24c>
  <3><246>: Abbrev Number: 12 (DW_TAG_namelist_item)
     <247>   DW_AT_namelist_items: <0x255>
  <2><24c>: Abbrev Number: 13 (DW_TAG_variable)
     <24d>   DW_AT_name        : i
...



Test case would be (e.g. file1.f90):
   module m
      implicit none
      integer :: ii
      real :: rr
      namelist /nml/ ii, rr
   end module m

subroutine bar()
    complex :: xyz
    namelist /nml/ xyz
    write(*,nml=nml)
end subroutine bar

and as USE-er for "m" (e.g. file2.f90):
   use m, only: nml  ! Or: "use m"
   implicit none
   write(*,nml=nml)
   !   ii = 5
   end


Tobias

[-- Attachment #2: nml-debug2.diff --]
[-- Type: text/x-patch, Size: 11902 bytes --]

gcc/
2013-11-09  Tobias Burnus  <burnus@net-b.de>

	PR debug/37132
	* lto-streamer.h (LTO_tags): Add LTO_namelist_decl_ref.
	* tree.def (NAMELIST_DECL): Add.
	* tree.h (NAMELIST_DECL_ASSOCIATED_DECL): New macro.
	* tree.c (initialize_tree_contains_struct): Add asserts for it.
	* dwarf2out.c (gen_namelist_decl): New function.
	(gen_decl_die, dwarf2out_decl): Call it.
	* lto-streamer-in.c (lto_input_tree_ref): Handle NAMELIST_DECL.
	(lto_input_tree_ref, lto_input_tree_1): Update lto_tag_check_range
	call.
	* lto-streamer-out.c (lto_output_tree_ref): Handle NAMELIST_DECL.

gcc/fortran
2013-11-09  Tobias Burnus  <burnus@net-b.de>

	PR debug/37132
	* trans-decl.c (generate_namelist_decl, create_module_nml_decl):
	New static functions.
	(gfc_generate_module_vars, generate_local_vars): Call them.
	(gfc_trans_use_stmts): Handle namelists for debug genertion.

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 5ef7bd2..67bf631 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3182,6 +3182,7 @@ static inline int is_redundant_typedef (const_tree);
 static bool is_naming_typedef_decl (const_tree);
 static inline dw_die_ref get_context_die (tree);
 static void gen_namespace_die (tree, dw_die_ref);
+static void gen_namelist_decl (tree, dw_die_ref, tree);
 static dw_die_ref gen_decl_die (tree, tree, dw_die_ref);
 static dw_die_ref force_decl_die (tree);
 static dw_die_ref force_type_die (tree);
@@ -20420,6 +20421,11 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
 	gen_namespace_die (decl, context_die);
       break;
 
+    case NAMELIST_DECL:
+      gen_namelist_decl (DECL_NAME (decl), context_die,
+			 NAMELIST_DECL_ASSOCIATED_DECL (decl));
+      break;
+
     default:
       /* Probably some frontend-internal decl.  Assume we don't care.  */
       gcc_assert ((int)TREE_CODE (decl) > NUM_TREE_CODES);
@@ -20581,6 +20587,34 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
 
 }
 
+/* Output debug information for namelists.   */
+
+static void
+gen_namelist_decl (tree name, dw_die_ref scope_die, tree item_decls)
+{
+  dw_die_ref nml_die, nml_item_die, nml_item_ref_die;
+  tree value;
+  unsigned i;
+
+  if (debug_info_level <= DINFO_LEVEL_TERSE)
+    return;
+
+  gcc_assert (scope_die != NULL);
+  nml_die = new_die (DW_TAG_namelist, scope_die, NULL);
+  add_AT_string (nml_die, DW_AT_name, IDENTIFIER_POINTER (name));
+
+  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (item_decls), i, value)
+    {
+      nml_item_ref_die = lookup_decl_die (value);
+      if (!nml_item_ref_die)
+	nml_item_ref_die = force_decl_die (value);
+
+      nml_item_die = new_die (DW_TAG_namelist_item, nml_die, NULL);
+      add_AT_die_ref (nml_item_die, DW_AT_namelist_items, nml_item_ref_die);
+    }
+}
+
+
 /* Write the debugging output for DECL.  */
 
 void
@@ -20701,6 +20735,9 @@ dwarf2out_decl (tree decl)
 
       break;
 
+    case NAMELIST_DECL:
+      break;
+
     default:
       return;
     }
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index c2c736e..b615ff6 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -4140,6 +4140,37 @@ gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
 
 static struct module_htab_entry *cur_module;
 
+
+/* Generate debugging symbols for namelists. This function must come after
+   generate_local_decl to ensure that the variables in the namelist are
+   already declared.  */
+
+static tree
+generate_namelist_decl (gfc_symbol * sym)
+{
+  gfc_namelist *nml;
+  tree decl;
+  vec<constructor_elt, va_gc> *nml_decls = NULL;
+
+  gcc_assert (sym->attr.flavor == FL_NAMELIST);
+  for (nml = sym->namelist; nml; nml = nml->next)
+    {
+      if (nml->sym->backend_decl == NULL_TREE)
+	{
+	  nml->sym->attr.referenced = 1;
+	  nml->sym->backend_decl = gfc_get_symbol_decl (nml->sym);
+	}
+      CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, nml->sym->backend_decl);
+    }
+
+  decl = make_node (NAMELIST_DECL);
+  TREE_TYPE (decl) = void_type_node;
+  NAMELIST_DECL_ASSOCIATED_DECL (decl) = build_constructor (NULL_TREE, nml_decls);
+  DECL_NAME (decl) = get_identifier (sym->name);
+  return decl;
+}
+
+
 /* Output an initialized decl for a module variable.  */
 
 static void
@@ -4329,6 +4360,18 @@ gfc_trans_use_stmts (gfc_namespace * ns)
 		  DECL_IGNORED_P (decl) = 0;
 		  DECL_INITIAL (decl) = NULL_TREE;
 		}
+	      else if (st->n.sym->attr.flavor == FL_NAMELIST
+		       && st->n.sym->attr.use_only
+		       && st->n.sym->module
+		       && strcmp (st->n.sym->module, use_stmt->module_name)
+			  == 0)
+		{
+		  decl = generate_namelist_decl (st->n.sym);
+		  DECL_CONTEXT (decl) = entry->namespace_decl;
+		  DECL_EXTERNAL (decl) = 1;
+		  DECL_IGNORED_P (decl) = 0;
+		  DECL_INITIAL (decl) = NULL_TREE;
+		}
 	      else
 		{
 		  *slot = error_mark_node;
@@ -4606,6 +4649,21 @@ generate_coarray_init (gfc_namespace * ns __attribute((unused)))
 }
 
 
+static void
+create_module_nml_decl (gfc_symbol *sym)
+{
+  if (sym->attr.flavor == FL_NAMELIST)
+    {
+      tree decl = generate_namelist_decl (sym);
+      pushdecl (decl);
+      gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
+      DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
+      rest_of_decl_compilation (decl, 1, 0);
+      gfc_module_add_decl (cur_module, decl);
+    }
+}
+
+
 /* Generate all the required code for module variables.  */
 
 void
@@ -4624,6 +4682,7 @@ gfc_generate_module_vars (gfc_namespace * ns)
 
   /* Create decls for all the module variables.  */
   gfc_traverse_ns (ns, gfc_create_module_variable);
+  gfc_traverse_ns (ns, create_module_nml_decl);
 
   if (gfc_option.coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
     generate_coarray_init (ns);
@@ -4889,10 +4948,23 @@ generate_local_decl (gfc_symbol * sym)
     sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
 }
 
+
+static void
+generate_local_nml_decl (gfc_symbol * sym)
+{
+  if (sym->attr.flavor == FL_NAMELIST && !sym->attr.use_assoc)
+    {
+      tree decl = generate_namelist_decl (sym);
+      pushdecl (decl);
+    }
+}
+
+
 static void
 generate_local_vars (gfc_namespace * ns)
 {
   gfc_traverse_ns (ns, generate_local_decl);
+  gfc_traverse_ns (ns, generate_local_nml_decl);
 }
 
 
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index d4a52a7..138852a 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -200,7 +200,7 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
   unsigned HOST_WIDE_INT ix_u;
   tree result = NULL_TREE;
 
-  lto_tag_check_range (tag, LTO_field_decl_ref, LTO_global_decl_ref);
+  lto_tag_check_range (tag, LTO_field_decl_ref, LTO_namelist_decl_ref);
 
   switch (tag)
     {
@@ -244,6 +244,28 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
       result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
       break;
 
+    case LTO_namelist_decl_ref:
+      {
+	tree tmp;
+	vec<constructor_elt, va_gc> *nml_decls = NULL;
+	unsigned i, n;
+
+	result = make_node (NAMELIST_DECL);
+	TREE_TYPE (result) = void_type_node;
+	DECL_NAME (result) = stream_read_tree (ib, data_in);
+	n = streamer_read_uhwi (ib);
+	for (i = 0; i < n; i++)
+	  {
+	    ix_u = streamer_read_uhwi (ib);
+	    tmp = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
+	    gcc_assert (tmp != NULL_TREE);
+	    CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, tmp);
+	  }
+	NAMELIST_DECL_ASSOCIATED_DECL (result) = build_constructor (NULL_TREE,
+								    nml_decls);
+	break;
+      }
+
     default:
       gcc_unreachable ();
     }
@@ -1234,7 +1256,7 @@ lto_input_tree_1 (struct lto_input_block *ib, struct data_in *data_in,
 
   if (tag == LTO_null)
     result = NULL_TREE;
-  else if (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref)
+  else if (tag >= LTO_field_decl_ref && tag <= LTO_namelist_decl_ref)
     {
       /* If TAG is a reference to an indexable tree, the next value
 	 in IB is the index into the table where we expect to find
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 5518623..2032e3b 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -49,6 +49,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 
 
+static void lto_write_tree (struct output_block*, tree, bool);
+
 /* Clear the line info stored in DATA_IN.  */
 
 static void
@@ -245,6 +247,21 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
       lto_output_type_decl_index (ob->decl_state, ob->main_stream, expr);
       break;
 
+    case NAMELIST_DECL:
+      {
+	unsigned i;
+	tree value, tmp;
+
+	streamer_write_record_start (ob, LTO_namelist_decl_ref);
+	stream_write_tree (ob, DECL_NAME (expr), true);
+	tmp = NAMELIST_DECL_ASSOCIATED_DECL (expr);
+	gcc_assert (tmp != NULL_TREE);
+	streamer_write_uhwi (ob, CONSTRUCTOR_ELTS (tmp)->length());
+	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (tmp), i, value)
+	  lto_output_var_decl_index (ob->decl_state, ob->main_stream, value);
+	break;
+      }
+
     case NAMESPACE_DECL:
       streamer_write_record_start (ob, LTO_namespace_decl_ref);
       lto_output_namespace_decl_index (ob->decl_state, ob->main_stream, expr);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 797e92e..fb3a947 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -222,7 +222,8 @@ enum LTO_tags
   LTO_const_decl_ref,
   LTO_imported_decl_ref,
   LTO_translation_unit_decl_ref,
-  LTO_global_decl_ref,			/* Do not change.  */
+  LTO_global_decl_ref,
+  LTO_namelist_decl_ref,		/* Do not change.  */
 
   /* This tag must always be last.  */
   LTO_NUM_TAGS
diff --git a/gcc/tree.c b/gcc/tree.c
index 686a680..f5a2f44 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -540,6 +540,8 @@ initialize_tree_contains_struct (void)
   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
+  gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_MINIMAL]);
+  gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_COMMON]);
 }
 
 
diff --git a/gcc/tree.def b/gcc/tree.def
index 399b5af..8514f7d 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -377,6 +377,16 @@ DEFTREECODE (NAMESPACE_DECL, "namespace_decl", tcc_declaration, 0)
    IMPORTED_DECL_ASSOCIATED_DECL (NODE) accesses the imported declaration.  */
 DEFTREECODE (IMPORTED_DECL, "imported_decl", tcc_declaration, 0)
 
+/* A namelist declaration.
+   The Fortran FE uses this to represent a namelist statement, e.g.:
+   NAMELIST /namelist-group-name/ namelist-group-object-list.
+   Whenever a declaration import appears in a lexical block, the BLOCK node
+   representing that lexical block in GIMPLE will contain an NAMELIST_DECL
+   node, linked via BLOCK_VARS accessor of the said BLOCK.
+   For a given NODE which code is NAMELIST_DECL,
+   NAMELIST_DECL_ASSOCIATED_DECL (NODE) accesses the imported declaration.  */
+DEFTREECODE (NAMELIST_DECL, "namelist_decl", tcc_declaration, 0)
+
 /* A translation unit.  This is not technically a declaration, since it
    can't be looked up, but it's close enough.  */
 DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl",\
diff --git a/gcc/tree.h b/gcc/tree.h
index c4b23d0..5e16b57 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2664,6 +2664,11 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
 #define IMPORTED_DECL_ASSOCIATED_DECL(NODE) \
 (DECL_INITIAL (IMPORTED_DECL_CHECK (NODE)))
 
+/* Getter of the symbol declaration associated with the
+   NAMELIST_DECL node.  */
+#define NAMELIST_DECL_ASSOCIATED_DECL(NODE) \
+  (DECL_INITIAL (NODE))
+
 /* A STATEMENT_LIST chains statements together in GENERIC and GIMPLE.
    To reduce overhead, the nodes containing the statements are not trees.
    This avoids the overhead of tree_common on all linked list elements.

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

* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-11-09 14:27 PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist) Tobias Burnus
@ 2013-11-11 19:07 ` Cary Coutant
  2013-11-12 11:58   ` Tobias Burnus
  2013-11-24 13:44 ` Tobias Burnus
  1 sibling, 1 reply; 9+ messages in thread
From: Cary Coutant @ 2013-11-11 19:07 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gcc patches, gfortran, Jakub Jelinek, Tom Tromey

> But for "USE mod_name, only: nml", one is supposed to generate a
> DW_TAG_imported_declaration.
>
> And there I am stuck. For normal variables, the DW_TAG_imported_declaration
> refers to a DW_TAG_variable die. Analogously, for a namelist one would have
> to refer to a DW_TAG_namelist die. But such DW_TAG_namelist comes with a
> DW_TAG_namelist_item list. And for the latter, one needs to have the die of
> all variables in the namelist. But with use-only the symbols aren't use
> associate and no decl or die exists. (Failing call tree with the patch:
> gfc_trans_use_stmts -> dwarf2out_imported_module_or_decl_1 ->
> force_decl_die.)
>
> What's the proper DWARF way of handling this? Creating a DW_TAG_namelist
> without any DW_TAG_namelist_items, relying on the debugger to pick those
> from the module? Or how is one supposed to handle it?

Why wouldn't you have DIEs for the imported namelist items? I'd think
that once the compiler has processed the USE statement and imported
the namelist into the current compilation unit, it would generate DIEs
for all the imported items, and then be able to construct a
fully-populated DW_TAG_namelist DIE. (At least it would have DIEs for
all the imported items that are actually used in that module, which
should be sufficient for debugging.)

-cary

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

* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-11-11 19:07 ` Cary Coutant
@ 2013-11-12 11:58   ` Tobias Burnus
  2013-11-12 19:09     ` Cary Coutant
  0 siblings, 1 reply; 9+ messages in thread
From: Tobias Burnus @ 2013-11-12 11:58 UTC (permalink / raw)
  To: Cary Coutant; +Cc: gcc patches, gfortran, Jakub Jelinek, Tom Tromey

Am 11.11.2013 19:18, schrieb Cary Coutant:
>> But for "USE mod_name, only: nml", one is supposed to generate a
>> DW_TAG_imported_declaration.
>>
>> And there I am stuck. For normal variables, the DW_TAG_imported_declaration
>> refers to a DW_TAG_variable die. Analogously, for a namelist one would have
>> to refer to a DW_TAG_namelist die. But such DW_TAG_namelist comes with a
>> DW_TAG_namelist_item list. And for the latter, one needs to have the die of
>> all variables in the namelist. But with use-only the symbols aren't use
>> associate and no decl or die exists. (Failing call tree with the patch:
>> gfc_trans_use_stmts -> dwarf2out_imported_module_or_decl_1 ->
>> force_decl_die.)
>>
>> What's the proper DWARF way of handling this? Creating a DW_TAG_namelist
>> without any DW_TAG_namelist_items, relying on the debugger to pick those
>> from the module? Or how is one supposed to handle it?
> Why wouldn't you have DIEs for the imported namelist items?I'd think
> that once the compiler has processed the USE statement and imported
> the namelist into the current compilation unit, it would generate DIEs
> for all the imported items, and then be able to construct a
> fully-populated DW_TAG_namelist DIE. (At least it would have DIEs for
> all the imported items that are actually used in that module, which
> should be sufficient for debugging.)

I think in most real-world cases, the module variables in the namelist 
have been imported and are available. But as shown in the example,

subroutine example()
   use mod, only: my_nml
   read(uid, my_nml)
end subroutine example

is possible and there one hasn't imported any of the module variables 
which are in namelist. Still, one might want to do:
   (gdb) print my_nml
to get something like:
   &my_nml i=6, r=8 /

One cannot simply also import, e.g., "i" as the code might have:

subroutine example()
   use mod, only: my_nml
   integer :: i            ! < Locally defined variable
   read(uid, my_nml)
   ...
end subroutine example

In that case "i" is the local variable. As written, one can create a 
decl and a die for the "i" of the module, but the question is how to 
name it.

Tobias

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

* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-11-12 11:58   ` Tobias Burnus
@ 2013-11-12 19:09     ` Cary Coutant
  0 siblings, 0 replies; 9+ messages in thread
From: Cary Coutant @ 2013-11-12 19:09 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gcc patches, gfortran, Jakub Jelinek, Tom Tromey

> One cannot simply also import, e.g., "i" as the code might have:
>
> subroutine example()
>   use mod, only: my_nml
>   integer :: i            ! < Locally defined variable
>   read(uid, my_nml)
>   ...
> end subroutine example
>
> In that case "i" is the local variable. As written, one can create a decl
> and a die for the "i" of the module, but the question is how to name it.

Ah, sorry, I didn't understand how the use statement works with a
namelist. I thought that when you import a namelist, it imports all
the names in that namelist individually, and that the read(...,
my_nml) was equivalent to read(..., ii, rr).

This sounds like a good question for the DWARF workgroup. Could you
forward this thread to dwarf-discuss@lists.dwarfstd.org? We have some
Fortran experts on that list, but I'm not one of them.

-cary

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

* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-11-09 14:27 PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist) Tobias Burnus
  2013-11-11 19:07 ` Cary Coutant
@ 2013-11-24 13:44 ` Tobias Burnus
  2013-11-29  0:51   ` *ping* " Tobias Burnus
  2013-12-04 17:48   ` Cary Coutant
  1 sibling, 2 replies; 9+ messages in thread
From: Tobias Burnus @ 2013-11-24 13:44 UTC (permalink / raw)
  To: gcc patches, gfortran, Jakub Jelinek, Cary Coutant

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

Hi all,

attached is an updated version of the patch.

Change:

Tobias Burnus wrote:
> But for "USE mod_name, only: nml", one is supposed to generate a 
> DW_TAG_imported_declaration. And there I am stuck. For normal 
> variables, the DW_TAG_imported_declaration refers to a DW_TAG_variable 
> die. Analogously, for a namelist one would have to refer to a 
> DW_TAG_namelist die. But such DW_TAG_namelist comes with a 
> DW_TAG_namelist_item list. And for the latter, one needs to have the 
> die of all variables in the namelist. But with use-only the symbols 
> aren't use associate and no decl or die exists. (Failing call tree 
> with the patch: gfc_trans_use_stmts -> 
> dwarf2out_imported_module_or_decl_1 -> force_decl_die.)

With the attached patch, one now generates DW_TAG_namelist with no 
DW_TAG_namelist_item and sets DW_AT_declaration.

Thus, for (first file)

   module mm
     integer :: ii
     real :: rr
     namelist /nml/ ii, rr
   end module mm


and (second file):

   subroutine test
     use mm, only: nml
     write(*,nml)
   end subroutine test


One now generates (first file):

  <1><1e>: Abbrev Number: 2 (DW_TAG_module)
     <1f>   DW_AT_name        : mm
     <22>   DW_AT_decl_file   : 1
     <23>   DW_AT_decl_line   : 1
     <24>   DW_AT_sibling     : <0x59>
  <2><28>: Abbrev Number: 3 (DW_TAG_variable)
     <29>   DW_AT_name        : ii
     <2c>   DW_AT_decl_file   : 1
     <2d>   DW_AT_decl_line   : 2
     <2e>   DW_AT_linkage_name: (indirect string, offset: 0x15): __mm_MOD_ii
     <32>   DW_AT_type        : <0x59>
     <36>   DW_AT_external    : 1
     <36>   DW_AT_location    : 9 byte block: 3 0 0 0 0 0 0 0 0  (DW_OP_addr: 0)
  <2><40>: Abbrev Number: 3 (DW_TAG_variable)
     <41>   DW_AT_name        : rr
     <44>   DW_AT_decl_file   : 1
     <45>   DW_AT_decl_line   : 2
     <46>   DW_AT_linkage_name: (indirect string, offset: 0x9): __mm_MOD_rr
     <4a>   DW_AT_type        : <0x60>
     <4e>   DW_AT_external    : 1
     <4e>   DW_AT_location    : 9 byte block: 3 4 0 0 0 0 0 0 0  (DW_OP_addr: 4)
  <2><58>: Abbrev Number: 0
  <1><59>: Abbrev Number: 4 (DW_TAG_base_type)
     <5a>   DW_AT_byte_size   : 4
     <5b>   DW_AT_encoding    : 5        (signed)
     <5c>   DW_AT_name        : (indirect string, offset: 0x29): integer(kind=4)
  <1><60>: Abbrev Number: 4 (DW_TAG_base_type)
     <61>   DW_AT_byte_size   : 4
     <62>   DW_AT_encoding    : 4        (float)
     <63>   DW_AT_name        : (indirect string, offset: 0x12c): real(kind=4)
  <1><67>: Abbrev Number: 5 (DW_TAG_namelist)
     <68>   DW_AT_name        : nml
  <2><6c>: Abbrev Number: 6 (DW_TAG_namelist_item)
     <6d>   DW_AT_namelist_items: <0x28>
  <2><71>: Abbrev Number: 6 (DW_TAG_namelist_item)
     <72>   DW_AT_namelist_items: <0x40>

Second file:

   <2><4f>: Abbrev Number: 3 (DW_TAG_imported_declaration)
     <50>   DW_AT_decl_file   : 1
     <51>   DW_AT_decl_line   : 2
     <52>   DW_AT_import      : <0x70>   [Abbrev Number: 6 (DW_TAG_namelist)]
  <2><56>: Abbrev Number: 4 (DW_TAG_lexical_block)
     <57>   DW_AT_low_pc      : 0xb
     <5f>   DW_AT_high_pc     : 0xb0
  <2><67>: Abbrev Number: 0
  <1><68>: Abbrev Number: 5 (DW_TAG_module)
     <69>   DW_AT_name        : mm
     <6c>   DW_AT_declaration : 1
     <6c>   DW_AT_sibling     : <0x76>
  <2><70>: Abbrev Number: 6 (DW_TAG_namelist)
     <71>   DW_AT_name        : nml
     <75>   DW_AT_declaration : 1
  <2><75>: Abbrev Number: 0
   


Does the dumps look okay? For the first file, DW_TAG_namelist doesn't 
come directly after DW_TAG_module but after its sibling 0x59; does one 
still see that "nml" belongs to that module? (On dwarf2out level, 
context die should point to the module tag, but I don't understand the 
readelf/eu-readelf output well enough to see whether that's also the 
case for the generated dwarf.)

I assume that the compiler can see from the DWARF of the second file 
that "nml" comes from module "mm" and doesn't search the value 
elsewhere. (It is possible to have multiple namelist with the same name 
in different modules.)


For previous version, I did an all-language bootstrap + regtesting; for 
this one, I only build and tested Fortran. I will do a now a full all 
language bootstrap regtesting. Assuming that it is successful:
OK for the trunk?

Tobias

[-- Attachment #2: nml-debug3.diff --]
[-- Type: text/x-patch, Size: 12711 bytes --]

gcc/
2013-11-24  Tobias Burnus  <burnus@net-b.de>

	PR debug/37132
	* lto-streamer.h (LTO_tags): Add LTO_namelist_decl_ref.
	* tree.def (NAMELIST_DECL): Add.
	* tree.h (NAMELIST_DECL_ASSOCIATED_DECL): New macro.
	* tree.c (initialize_tree_contains_struct): Add asserts for it.
	* dwarf2out.c (gen_namelist_decl): New function.
	(gen_decl_die, dwarf2out_decl): Call it.
	(dwarf2out_imported_module_or_decl_1): Handle NAMELIST_DECL.
	* lto-streamer-in.c (lto_input_tree_ref): Handle NAMELIST_DECL.
	(lto_input_tree_ref, lto_input_tree_1): Update lto_tag_check_range
	call.
	* lto-streamer-out.c (lto_output_tree_ref): Handle NAMELIST_DECL.

gcc/fortran
2013-11-24  Tobias Burnus  <burnus@net-b.de>

	PR debug/37132
	* trans-decl.c (generate_namelist_decl, create_module_nml_decl):
	New static functions.
	(gfc_generate_module_vars, generate_local_vars): Call them.
	(gfc_trans_use_stmts): Handle namelists for debug genertion.

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 3448ec4..0f35591 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3185,6 +3185,7 @@ static inline int is_redundant_typedef (const_tree);
 static bool is_naming_typedef_decl (const_tree);
 static inline dw_die_ref get_context_die (tree);
 static void gen_namespace_die (tree, dw_die_ref);
+static dw_die_ref gen_namelist_decl (tree, dw_die_ref, tree);
 static dw_die_ref gen_decl_die (tree, tree, dw_die_ref);
 static dw_die_ref force_decl_die (tree);
 static dw_die_ref force_type_die (tree);
@@ -20432,6 +20433,11 @@ gen_decl_die (tree decl, tree origin, dw_die_ref context_die)
 	gen_namespace_die (decl, context_die);
       break;
 
+    case NAMELIST_DECL:
+      gen_namelist_decl (DECL_NAME (decl), context_die,
+			 NAMELIST_DECL_ASSOCIATED_DECL (decl));
+      break;
+
     default:
       /* Probably some frontend-internal decl.  Assume we don't care.  */
       gcc_assert ((int)TREE_CODE (decl) > NUM_TREE_CODES);
@@ -20522,7 +20528,12 @@ dwarf2out_imported_module_or_decl_1 (tree decl,
 	      gen_type_die_for_member (type, decl,
 				       get_context_die (TYPE_CONTEXT (type)));
 	    }
-	  at_import_die = force_decl_die (decl);
+	  if (TREE_CODE (decl) == NAMELIST_DECL)
+	    at_import_die = gen_namelist_decl (DECL_NAME (decl),
+					 get_context_die (DECL_CONTEXT (decl)),
+					 NULL_TREE);
+	  else
+	    at_import_die = force_decl_die (decl);
 	}
     }
 
@@ -20594,6 +20605,43 @@ dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
 
 }
 
+/* Output debug information for namelists.   */
+
+static dw_die_ref
+gen_namelist_decl (tree name, dw_die_ref scope_die, tree item_decls)
+{
+  dw_die_ref nml_die, nml_item_die, nml_item_ref_die;
+  tree value;
+  unsigned i;
+
+  if (debug_info_level <= DINFO_LEVEL_TERSE)
+    return NULL;
+
+  gcc_assert (scope_die != NULL);
+  nml_die = new_die (DW_TAG_namelist, scope_die, NULL);
+  add_AT_string (nml_die, DW_AT_name, IDENTIFIER_POINTER (name));
+
+  /* If there are no item_decls, we have a nondefining namelist, e.g.
+     with USE association; hence, set DW_AT_declaration.  */
+  if (item_decls == NULL_TREE)
+    {
+      add_AT_flag (nml_die, DW_AT_declaration, 1);
+      return nml_die;
+    }
+
+  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (item_decls), i, value)
+    {
+      nml_item_ref_die = lookup_decl_die (value);
+      if (!nml_item_ref_die)
+	nml_item_ref_die = force_decl_die (value);
+
+      nml_item_die = new_die (DW_TAG_namelist_item, nml_die, NULL);
+      add_AT_die_ref (nml_item_die, DW_AT_namelist_items, nml_item_ref_die);
+    }
+  return nml_die;
+}
+
+
 /* Write the debugging output for DECL.  */
 
 void
@@ -20714,6 +20762,9 @@ dwarf2out_decl (tree decl)
 
       break;
 
+    case NAMELIST_DECL:
+      break;
+
     default:
       return;
     }
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index f974c6e..c1775b3 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -4144,6 +4144,37 @@ gfc_module_add_decl (struct module_htab_entry *entry, tree decl)
 
 static struct module_htab_entry *cur_module;
 
+
+/* Generate debugging symbols for namelists. This function must come after
+   generate_local_decl to ensure that the variables in the namelist are
+   already declared.  */
+
+static tree
+generate_namelist_decl (gfc_symbol * sym)
+{
+  gfc_namelist *nml;
+  tree decl;
+  vec<constructor_elt, va_gc> *nml_decls = NULL;
+
+  gcc_assert (sym->attr.flavor == FL_NAMELIST);
+  for (nml = sym->namelist; nml; nml = nml->next)
+    {
+      if (nml->sym->backend_decl == NULL_TREE)
+	{
+	  nml->sym->attr.referenced = 1;
+	  nml->sym->backend_decl = gfc_get_symbol_decl (nml->sym);
+	}
+      CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, nml->sym->backend_decl);
+    }
+
+  decl = make_node (NAMELIST_DECL);
+  TREE_TYPE (decl) = void_type_node;
+  NAMELIST_DECL_ASSOCIATED_DECL (decl) = build_constructor (NULL_TREE, nml_decls);
+  DECL_NAME (decl) = get_identifier (sym->name);
+  return decl;
+}
+
+
 /* Output an initialized decl for a module variable.  */
 
 static void
@@ -4333,6 +4364,18 @@ gfc_trans_use_stmts (gfc_namespace * ns)
 		  DECL_IGNORED_P (decl) = 0;
 		  DECL_INITIAL (decl) = NULL_TREE;
 		}
+	      else if (st->n.sym->attr.flavor == FL_NAMELIST
+		       && st->n.sym->attr.use_only
+		       && st->n.sym->module
+		       && strcmp (st->n.sym->module, use_stmt->module_name)
+			  == 0)
+		{
+		  decl = generate_namelist_decl (st->n.sym);
+		  DECL_CONTEXT (decl) = entry->namespace_decl;
+		  DECL_EXTERNAL (decl) = 1;
+		  DECL_IGNORED_P (decl) = 0;
+		  DECL_INITIAL (decl) = NULL_TREE;
+		}
 	      else
 		{
 		  *slot = error_mark_node;
@@ -4610,6 +4653,21 @@ generate_coarray_init (gfc_namespace * ns __attribute((unused)))
 }
 
 
+static void
+create_module_nml_decl (gfc_symbol *sym)
+{
+  if (sym->attr.flavor == FL_NAMELIST)
+    {
+      tree decl = generate_namelist_decl (sym);
+      pushdecl (decl);
+      gcc_assert (sym->ns->proc_name->attr.flavor == FL_MODULE);
+      DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
+      rest_of_decl_compilation (decl, 1, 0);
+      gfc_module_add_decl (cur_module, decl);
+    }
+}
+
+
 /* Generate all the required code for module variables.  */
 
 void
@@ -4628,6 +4686,7 @@ gfc_generate_module_vars (gfc_namespace * ns)
 
   /* Create decls for all the module variables.  */
   gfc_traverse_ns (ns, gfc_create_module_variable);
+  gfc_traverse_ns (ns, create_module_nml_decl);
 
   if (gfc_option.coarray == GFC_FCOARRAY_LIB && has_coarray_vars)
     generate_coarray_init (ns);
@@ -4893,10 +4952,23 @@ generate_local_decl (gfc_symbol * sym)
     sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
 }
 
+
+static void
+generate_local_nml_decl (gfc_symbol * sym)
+{
+  if (sym->attr.flavor == FL_NAMELIST && !sym->attr.use_assoc)
+    {
+      tree decl = generate_namelist_decl (sym);
+      pushdecl (decl);
+    }
+}
+
+
 static void
 generate_local_vars (gfc_namespace * ns)
 {
   gfc_traverse_ns (ns, generate_local_decl);
+  gfc_traverse_ns (ns, generate_local_nml_decl);
 }
 
 
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 333e815..a4e362b 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -204,7 +204,7 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
   unsigned HOST_WIDE_INT ix_u;
   tree result = NULL_TREE;
 
-  lto_tag_check_range (tag, LTO_field_decl_ref, LTO_global_decl_ref);
+  lto_tag_check_range (tag, LTO_field_decl_ref, LTO_namelist_decl_ref);
 
   switch (tag)
     {
@@ -248,6 +248,28 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
       result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
       break;
 
+    case LTO_namelist_decl_ref:
+      {
+	tree tmp;
+	vec<constructor_elt, va_gc> *nml_decls = NULL;
+	unsigned i, n;
+
+	result = make_node (NAMELIST_DECL);
+	TREE_TYPE (result) = void_type_node;
+	DECL_NAME (result) = stream_read_tree (ib, data_in);
+	n = streamer_read_uhwi (ib);
+	for (i = 0; i < n; i++)
+	  {
+	    ix_u = streamer_read_uhwi (ib);
+	    tmp = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u);
+	    gcc_assert (tmp != NULL_TREE);
+	    CONSTRUCTOR_APPEND_ELT (nml_decls, NULL_TREE, tmp);
+	  }
+	NAMELIST_DECL_ASSOCIATED_DECL (result) = build_constructor (NULL_TREE,
+								    nml_decls);
+	break;
+      }
+
     default:
       gcc_unreachable ();
     }
@@ -1240,7 +1262,7 @@ lto_input_tree_1 (struct lto_input_block *ib, struct data_in *data_in,
 
   if (tag == LTO_null)
     result = NULL_TREE;
-  else if (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref)
+  else if (tag >= LTO_field_decl_ref && tag <= LTO_namelist_decl_ref)
     {
       /* If TAG is a reference to an indexable tree, the next value
 	 in IB is the index into the table where we expect to find
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 6163d12..e61430f 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -54,6 +54,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfgloop.h"
 
 
+static void lto_write_tree (struct output_block*, tree, bool);
+
 /* Clear the line info stored in DATA_IN.  */
 
 static void
@@ -250,6 +252,21 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
       lto_output_type_decl_index (ob->decl_state, ob->main_stream, expr);
       break;
 
+    case NAMELIST_DECL:
+      {
+	unsigned i;
+	tree value, tmp;
+
+	streamer_write_record_start (ob, LTO_namelist_decl_ref);
+	stream_write_tree (ob, DECL_NAME (expr), true);
+	tmp = NAMELIST_DECL_ASSOCIATED_DECL (expr);
+	gcc_assert (tmp != NULL_TREE);
+	streamer_write_uhwi (ob, CONSTRUCTOR_ELTS (tmp)->length());
+	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (tmp), i, value)
+	  lto_output_var_decl_index (ob->decl_state, ob->main_stream, value);
+	break;
+      }
+
     case NAMESPACE_DECL:
       streamer_write_record_start (ob, LTO_namespace_decl_ref);
       lto_output_namespace_decl_index (ob->decl_state, ob->main_stream, expr);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 9dac7c9..91bbb93 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -222,7 +222,8 @@ enum LTO_tags
   LTO_const_decl_ref,
   LTO_imported_decl_ref,
   LTO_translation_unit_decl_ref,
-  LTO_global_decl_ref,			/* Do not change.  */
+  LTO_global_decl_ref,
+  LTO_namelist_decl_ref,		/* Do not change.  */
 
   /* This tag must always be last.  */
   LTO_NUM_TAGS
diff --git a/gcc/tree.c b/gcc/tree.c
index d363cfc..da33944 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -551,6 +551,8 @@ initialize_tree_contains_struct (void)
   gcc_assert (tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_MINIMAL]);
   gcc_assert (tree_contains_struct[IMPORTED_DECL][TS_DECL_COMMON]);
+  gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_MINIMAL]);
+  gcc_assert (tree_contains_struct[NAMELIST_DECL][TS_DECL_COMMON]);
 }
 
 
diff --git a/gcc/tree.def b/gcc/tree.def
index 8eecba7..a325c7a 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -377,6 +377,16 @@ DEFTREECODE (NAMESPACE_DECL, "namespace_decl", tcc_declaration, 0)
    IMPORTED_DECL_ASSOCIATED_DECL (NODE) accesses the imported declaration.  */
 DEFTREECODE (IMPORTED_DECL, "imported_decl", tcc_declaration, 0)
 
+/* A namelist declaration.
+   The Fortran FE uses this to represent a namelist statement, e.g.:
+   NAMELIST /namelist-group-name/ namelist-group-object-list.
+   Whenever a declaration import appears in a lexical block, the BLOCK node
+   representing that lexical block in GIMPLE will contain an NAMELIST_DECL
+   node, linked via BLOCK_VARS accessor of the said BLOCK.
+   For a given NODE which code is NAMELIST_DECL,
+   NAMELIST_DECL_ASSOCIATED_DECL (NODE) accesses the imported declaration.  */
+DEFTREECODE (NAMELIST_DECL, "namelist_decl", tcc_declaration, 0)
+
 /* A translation unit.  This is not technically a declaration, since it
    can't be looked up, but it's close enough.  */
 DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl",\
diff --git a/gcc/tree.h b/gcc/tree.h
index 68f9826..0c70810 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2670,6 +2670,11 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
 #define IMPORTED_DECL_ASSOCIATED_DECL(NODE) \
 (DECL_INITIAL (IMPORTED_DECL_CHECK (NODE)))
 
+/* Getter of the symbol declaration associated with the
+   NAMELIST_DECL node.  */
+#define NAMELIST_DECL_ASSOCIATED_DECL(NODE) \
+  (DECL_INITIAL (NODE))
+
 /* A STATEMENT_LIST chains statements together in GENERIC and GIMPLE.
    To reduce overhead, the nodes containing the statements are not trees.
    This avoids the overhead of tree_common on all linked list elements.

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

* *ping* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-11-24 13:44 ` Tobias Burnus
@ 2013-11-29  0:51   ` Tobias Burnus
  2013-12-04  6:37     ` Tobias Burnus
  2013-12-04 17:48   ` Cary Coutant
  1 sibling, 1 reply; 9+ messages in thread
From: Tobias Burnus @ 2013-11-29  0:51 UTC (permalink / raw)
  To: gcc patches, gfortran, Jakub Jelinek, Cary Coutant

A slightly early *ping*

Tobias Burnus wrote:
> attached is an updated version of the patch.
>
> Change:
>
> Tobias Burnus wrote:
>> But for "USE mod_name, only: nml", one is supposed to generate a 
>> DW_TAG_imported_declaration. And there I am stuck. For normal 
>> variables, the DW_TAG_imported_declaration refers to a 
>> DW_TAG_variable die. Analogously, for a namelist one would have to 
>> refer to a DW_TAG_namelist die. But such DW_TAG_namelist comes with a 
>> DW_TAG_namelist_item list. And for the latter, one needs to have the 
>> die of all variables in the namelist. But with use-only the symbols 
>> aren't use associate and no decl or die exists. (Failing call tree 
>> with the patch: gfc_trans_use_stmts -> 
>> dwarf2out_imported_module_or_decl_1 -> force_decl_die.)
>
> With the attached patch, one now generates DW_TAG_namelist with no 
> DW_TAG_namelist_item and sets DW_AT_declaration.
>
> Thus, for (first file)
>
>   module mm
>     integer :: ii
>     real :: rr
>     namelist /nml/ ii, rr
>   end module mm
>
>
> and (second file):
>
>   subroutine test
>     use mm, only: nml
>     write(*,nml)
>   end subroutine test
>
>
> One now generates (first file):
>
>  <1><1e>: Abbrev Number: 2 (DW_TAG_module)
>     <1f>   DW_AT_name        : mm
>     <22>   DW_AT_decl_file   : 1
>     <23>   DW_AT_decl_line   : 1
>     <24>   DW_AT_sibling     : <0x59>
>  <2><28>: Abbrev Number: 3 (DW_TAG_variable)
>     <29>   DW_AT_name        : ii
>     <2c>   DW_AT_decl_file   : 1
>     <2d>   DW_AT_decl_line   : 2
>     <2e>   DW_AT_linkage_name: (indirect string, offset: 0x15): 
> __mm_MOD_ii
>     <32>   DW_AT_type        : <0x59>
>     <36>   DW_AT_external    : 1
>     <36>   DW_AT_location    : 9 byte block: 3 0 0 0 0 0 0 0 0  
> (DW_OP_addr: 0)
>  <2><40>: Abbrev Number: 3 (DW_TAG_variable)
>     <41>   DW_AT_name        : rr
>     <44>   DW_AT_decl_file   : 1
>     <45>   DW_AT_decl_line   : 2
>     <46>   DW_AT_linkage_name: (indirect string, offset: 0x9): 
> __mm_MOD_rr
>     <4a>   DW_AT_type        : <0x60>
>     <4e>   DW_AT_external    : 1
>     <4e>   DW_AT_location    : 9 byte block: 3 4 0 0 0 0 0 0 0  
> (DW_OP_addr: 4)
>  <2><58>: Abbrev Number: 0
>  <1><59>: Abbrev Number: 4 (DW_TAG_base_type)
>     <5a>   DW_AT_byte_size   : 4
>     <5b>   DW_AT_encoding    : 5        (signed)
>     <5c>   DW_AT_name        : (indirect string, offset: 0x29): 
> integer(kind=4)
>  <1><60>: Abbrev Number: 4 (DW_TAG_base_type)
>     <61>   DW_AT_byte_size   : 4
>     <62>   DW_AT_encoding    : 4        (float)
>     <63>   DW_AT_name        : (indirect string, offset: 0x12c): 
> real(kind=4)
>  <1><67>: Abbrev Number: 5 (DW_TAG_namelist)
>     <68>   DW_AT_name        : nml
>  <2><6c>: Abbrev Number: 6 (DW_TAG_namelist_item)
>     <6d>   DW_AT_namelist_items: <0x28>
>  <2><71>: Abbrev Number: 6 (DW_TAG_namelist_item)
>     <72>   DW_AT_namelist_items: <0x40>
>
> Second file:
>
>   <2><4f>: Abbrev Number: 3 (DW_TAG_imported_declaration)
>     <50>   DW_AT_decl_file   : 1
>     <51>   DW_AT_decl_line   : 2
>     <52>   DW_AT_import      : <0x70>   [Abbrev Number: 6 
> (DW_TAG_namelist)]
>  <2><56>: Abbrev Number: 4 (DW_TAG_lexical_block)
>     <57>   DW_AT_low_pc      : 0xb
>     <5f>   DW_AT_high_pc     : 0xb0
>  <2><67>: Abbrev Number: 0
>  <1><68>: Abbrev Number: 5 (DW_TAG_module)
>     <69>   DW_AT_name        : mm
>     <6c>   DW_AT_declaration : 1
>     <6c>   DW_AT_sibling     : <0x76>
>  <2><70>: Abbrev Number: 6 (DW_TAG_namelist)
>     <71>   DW_AT_name        : nml
>     <75>   DW_AT_declaration : 1
>  <2><75>: Abbrev Number: 0
>
>
> Does the dumps look okay? For the first file, DW_TAG_namelist doesn't 
> come directly after DW_TAG_module but after its sibling 0x59; does one 
> still see that "nml" belongs to that module? (On dwarf2out level, 
> context die should point to the module tag, but I don't understand the 
> readelf/eu-readelf output well enough to see whether that's also the 
> case for the generated dwarf.)
>
> I assume that the compiler can see from the DWARF of the second file 
> that "nml" comes from module "mm" and doesn't search the value 
> elsewhere. (It is possible to have multiple namelist with the same 
> name in different modules.)
>
>
> For previous version, I did an all-language bootstrap + regtesting; 
> for this one, I only build and tested Fortran. I will do a now a full 
> all language bootstrap regtesting. Assuming that it is successful:
> OK for the trunk?
>
> Tobias

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

* Re: *ping* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-11-29  0:51   ` *ping* " Tobias Burnus
@ 2013-12-04  6:37     ` Tobias Burnus
  0 siblings, 0 replies; 9+ messages in thread
From: Tobias Burnus @ 2013-12-04  6:37 UTC (permalink / raw)
  To: gcc patches, gfortran, Jakub Jelinek, Cary Coutant

On November 28, 2013, Tobias Burnus wrote:
> A slightly early *ping*
>
> Tobias Burnus wrote:
>> attached is an updated version of the patch.
>>
>> Change:
>>
>> Tobias Burnus wrote:
>>> But for "USE mod_name, only: nml", one is supposed to generate a 
>>> DW_TAG_imported_declaration. And there I am stuck. For normal 
>>> variables, the DW_TAG_imported_declaration refers to a 
>>> DW_TAG_variable die. Analogously, for a namelist one would have to 
>>> refer to a DW_TAG_namelist die. But such DW_TAG_namelist comes with 
>>> a DW_TAG_namelist_item list. And for the latter, one needs to have 
>>> the die of all variables in the namelist. But with use-only the 
>>> symbols aren't use associate and no decl or die exists. (Failing 
>>> call tree with the patch: gfc_trans_use_stmts -> 
>>> dwarf2out_imported_module_or_decl_1 -> force_decl_die.)
>>
>> With the attached patch, one now generates DW_TAG_namelist with no 
>> DW_TAG_namelist_item and sets DW_AT_declaration.
>>
>> Thus, for (first file)
>>
>>   module mm
>>     integer :: ii
>>     real :: rr
>>     namelist /nml/ ii, rr
>>   end module mm
>>
>>
>> and (second file):
>>
>>   subroutine test
>>     use mm, only: nml
>>     write(*,nml)
>>   end subroutine test
>>
>>
>> One now generates (first file):
>>
>>  <1><1e>: Abbrev Number: 2 (DW_TAG_module)
>>     <1f>   DW_AT_name        : mm
>>     <22>   DW_AT_decl_file   : 1
>>     <23>   DW_AT_decl_line   : 1
>>     <24>   DW_AT_sibling     : <0x59>
>>  <2><28>: Abbrev Number: 3 (DW_TAG_variable)
>>     <29>   DW_AT_name        : ii
>>     <2c>   DW_AT_decl_file   : 1
>>     <2d>   DW_AT_decl_line   : 2
>>     <2e>   DW_AT_linkage_name: (indirect string, offset: 0x15): 
>> __mm_MOD_ii
>>     <32>   DW_AT_type        : <0x59>
>>     <36>   DW_AT_external    : 1
>>     <36>   DW_AT_location    : 9 byte block: 3 0 0 0 0 0 0 0 0  
>> (DW_OP_addr: 0)
>>  <2><40>: Abbrev Number: 3 (DW_TAG_variable)
>>     <41>   DW_AT_name        : rr
>>     <44>   DW_AT_decl_file   : 1
>>     <45>   DW_AT_decl_line   : 2
>>     <46>   DW_AT_linkage_name: (indirect string, offset: 0x9): 
>> __mm_MOD_rr
>>     <4a>   DW_AT_type        : <0x60>
>>     <4e>   DW_AT_external    : 1
>>     <4e>   DW_AT_location    : 9 byte block: 3 4 0 0 0 0 0 0 0  
>> (DW_OP_addr: 4)
>>  <2><58>: Abbrev Number: 0
>>  <1><59>: Abbrev Number: 4 (DW_TAG_base_type)
>>     <5a>   DW_AT_byte_size   : 4
>>     <5b>   DW_AT_encoding    : 5        (signed)
>>     <5c>   DW_AT_name        : (indirect string, offset: 0x29): 
>> integer(kind=4)
>>  <1><60>: Abbrev Number: 4 (DW_TAG_base_type)
>>     <61>   DW_AT_byte_size   : 4
>>     <62>   DW_AT_encoding    : 4        (float)
>>     <63>   DW_AT_name        : (indirect string, offset: 0x12c): 
>> real(kind=4)
>>  <1><67>: Abbrev Number: 5 (DW_TAG_namelist)
>>     <68>   DW_AT_name        : nml
>>  <2><6c>: Abbrev Number: 6 (DW_TAG_namelist_item)
>>     <6d>   DW_AT_namelist_items: <0x28>
>>  <2><71>: Abbrev Number: 6 (DW_TAG_namelist_item)
>>     <72>   DW_AT_namelist_items: <0x40>
>>
>> Second file:
>>
>>   <2><4f>: Abbrev Number: 3 (DW_TAG_imported_declaration)
>>     <50>   DW_AT_decl_file   : 1
>>     <51>   DW_AT_decl_line   : 2
>>     <52>   DW_AT_import      : <0x70>   [Abbrev Number: 6 
>> (DW_TAG_namelist)]
>>  <2><56>: Abbrev Number: 4 (DW_TAG_lexical_block)
>>     <57>   DW_AT_low_pc      : 0xb
>>     <5f>   DW_AT_high_pc     : 0xb0
>>  <2><67>: Abbrev Number: 0
>>  <1><68>: Abbrev Number: 5 (DW_TAG_module)
>>     <69>   DW_AT_name        : mm
>>     <6c>   DW_AT_declaration : 1
>>     <6c>   DW_AT_sibling     : <0x76>
>>  <2><70>: Abbrev Number: 6 (DW_TAG_namelist)
>>     <71>   DW_AT_name        : nml
>>     <75>   DW_AT_declaration : 1
>>  <2><75>: Abbrev Number: 0
>>
>>
>> Does the dumps look okay? For the first file, DW_TAG_namelist doesn't 
>> come directly after DW_TAG_module but after its sibling 0x59; does 
>> one still see that "nml" belongs to that module? (On dwarf2out level, 
>> context die should point to the module tag, but I don't understand 
>> the readelf/eu-readelf output well enough to see whether that's also 
>> the case for the generated dwarf.)
>>
>> I assume that the compiler can see from the DWARF of the second file 
>> that "nml" comes from module "mm" and doesn't search the value 
>> elsewhere. (It is possible to have multiple namelist with the same 
>> name in different modules.)
>>
>>
>> For previous version, I did an all-language bootstrap + regtesting; 
>> for this one, I only build and tested Fortran. I will do a now a full 
>> all language bootstrap regtesting. Assuming that it is successful:
>> OK for the trunk?
>>
>> Tobias
>
>

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

* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-11-24 13:44 ` Tobias Burnus
  2013-11-29  0:51   ` *ping* " Tobias Burnus
@ 2013-12-04 17:48   ` Cary Coutant
  2013-12-04 17:58     ` Jakub Jelinek
  1 sibling, 1 reply; 9+ messages in thread
From: Cary Coutant @ 2013-12-04 17:48 UTC (permalink / raw)
  To: Tobias Burnus; +Cc: gcc patches, gfortran, Jakub Jelinek

> gcc/
> 2013-11-24  Tobias Burnus  <burnus@net-b.de>
>
>       PR debug/37132
>       * lto-streamer.h (LTO_tags): Add LTO_namelist_decl_ref.
>       * tree.def (NAMELIST_DECL): Add.
>       * tree.h (NAMELIST_DECL_ASSOCIATED_DECL): New macro.
>       * tree.c (initialize_tree_contains_struct): Add asserts for it.
>       * dwarf2out.c (gen_namelist_decl): New function.
>       (gen_decl_die, dwarf2out_decl): Call it.
>       (dwarf2out_imported_module_or_decl_1): Handle NAMELIST_DECL.
>       * lto-streamer-in.c (lto_input_tree_ref): Handle NAMELIST_DECL.
>       (lto_input_tree_ref, lto_input_tree_1): Update lto_tag_check_range
>       call.
>       * lto-streamer-out.c (lto_output_tree_ref): Handle NAMELIST_DECL.
>
> gcc/fortran
> 2013-11-24  Tobias Burnus  <burnus@net-b.de>
>
>       PR debug/37132
>       * trans-decl.c (generate_namelist_decl, create_module_nml_decl):
>       New static functions.
>       (gfc_generate_module_vars, generate_local_vars): Call them.
>       (gfc_trans_use_stmts): Handle namelists for debug genertion.

The DWARF parts of this patch are OK with me.

-cary


On Sun, Nov 24, 2013 at 2:12 AM, Tobias Burnus <burnus@net-b.de> wrote:
> Hi all,
>
> attached is an updated version of the patch.
>
> Change:
>
>
> Tobias Burnus wrote:
>>
>> But for "USE mod_name, only: nml", one is supposed to generate a
>> DW_TAG_imported_declaration. And there I am stuck. For normal variables, the
>> DW_TAG_imported_declaration refers to a DW_TAG_variable die. Analogously,
>> for a namelist one would have to refer to a DW_TAG_namelist die. But such
>> DW_TAG_namelist comes with a DW_TAG_namelist_item list. And for the latter,
>> one needs to have the die of all variables in the namelist. But with
>> use-only the symbols aren't use associate and no decl or die exists.
>> (Failing call tree with the patch: gfc_trans_use_stmts ->
>> dwarf2out_imported_module_or_decl_1 -> force_decl_die.)
>
>
> With the attached patch, one now generates DW_TAG_namelist with no
> DW_TAG_namelist_item and sets DW_AT_declaration.
>
> Thus, for (first file)
>
>   module mm
>
>     integer :: ii
>     real :: rr
>     namelist /nml/ ii, rr
>   end module mm
>
>
> and (second file):
>
>   subroutine test
>     use mm, only: nml
>     write(*,nml)
>   end subroutine test
>
>
> One now generates (first file):
>
>  <1><1e>: Abbrev Number: 2 (DW_TAG_module)
>     <1f>   DW_AT_name        : mm
>     <22>   DW_AT_decl_file   : 1
>     <23>   DW_AT_decl_line   : 1
>     <24>   DW_AT_sibling     : <0x59>
>  <2><28>: Abbrev Number: 3 (DW_TAG_variable)
>     <29>   DW_AT_name        : ii
>     <2c>   DW_AT_decl_file   : 1
>     <2d>   DW_AT_decl_line   : 2
>     <2e>   DW_AT_linkage_name: (indirect string, offset: 0x15): __mm_MOD_ii
>     <32>   DW_AT_type        : <0x59>
>     <36>   DW_AT_external    : 1
>     <36>   DW_AT_location    : 9 byte block: 3 0 0 0 0 0 0 0 0  (DW_OP_addr:
> 0)
>  <2><40>: Abbrev Number: 3 (DW_TAG_variable)
>     <41>   DW_AT_name        : rr
>     <44>   DW_AT_decl_file   : 1
>     <45>   DW_AT_decl_line   : 2
>     <46>   DW_AT_linkage_name: (indirect string, offset: 0x9): __mm_MOD_rr
>     <4a>   DW_AT_type        : <0x60>
>     <4e>   DW_AT_external    : 1
>     <4e>   DW_AT_location    : 9 byte block: 3 4 0 0 0 0 0 0 0  (DW_OP_addr:
> 4)
>  <2><58>: Abbrev Number: 0
>  <1><59>: Abbrev Number: 4 (DW_TAG_base_type)
>     <5a>   DW_AT_byte_size   : 4
>     <5b>   DW_AT_encoding    : 5        (signed)
>     <5c>   DW_AT_name        : (indirect string, offset: 0x29):
> integer(kind=4)
>  <1><60>: Abbrev Number: 4 (DW_TAG_base_type)
>     <61>   DW_AT_byte_size   : 4
>     <62>   DW_AT_encoding    : 4        (float)
>     <63>   DW_AT_name        : (indirect string, offset: 0x12c):
> real(kind=4)
>  <1><67>: Abbrev Number: 5 (DW_TAG_namelist)
>     <68>   DW_AT_name        : nml
>  <2><6c>: Abbrev Number: 6 (DW_TAG_namelist_item)
>     <6d>   DW_AT_namelist_items: <0x28>
>  <2><71>: Abbrev Number: 6 (DW_TAG_namelist_item)
>     <72>   DW_AT_namelist_items: <0x40>
>
> Second file:
>
>   <2><4f>: Abbrev Number: 3 (DW_TAG_imported_declaration)
>     <50>   DW_AT_decl_file   : 1
>     <51>   DW_AT_decl_line   : 2
>     <52>   DW_AT_import      : <0x70>   [Abbrev Number: 6 (DW_TAG_namelist)]
>  <2><56>: Abbrev Number: 4 (DW_TAG_lexical_block)
>     <57>   DW_AT_low_pc      : 0xb
>     <5f>   DW_AT_high_pc     : 0xb0
>  <2><67>: Abbrev Number: 0
>  <1><68>: Abbrev Number: 5 (DW_TAG_module)
>     <69>   DW_AT_name        : mm
>     <6c>   DW_AT_declaration : 1
>     <6c>   DW_AT_sibling     : <0x76>
>  <2><70>: Abbrev Number: 6 (DW_TAG_namelist)
>     <71>   DW_AT_name        : nml
>     <75>   DW_AT_declaration : 1
>  <2><75>: Abbrev Number: 0
>
>
> Does the dumps look okay? For the first file, DW_TAG_namelist doesn't come
> directly after DW_TAG_module but after its sibling 0x59; does one still see
> that "nml" belongs to that module? (On dwarf2out level, context die should
> point to the module tag, but I don't understand the readelf/eu-readelf
> output well enough to see whether that's also the case for the generated
> dwarf.)
>
> I assume that the compiler can see from the DWARF of the second file that
> "nml" comes from module "mm" and doesn't search the value elsewhere. (It is
> possible to have multiple namelist with the same name in different modules.)
>
>
> For previous version, I did an all-language bootstrap + regtesting; for this
> one, I only build and tested Fortran. I will do a now a full all language
> bootstrap regtesting. Assuming that it is successful:
> OK for the trunk?
>
> Tobias

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

* Re: PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist)
  2013-12-04 17:48   ` Cary Coutant
@ 2013-12-04 17:58     ` Jakub Jelinek
  0 siblings, 0 replies; 9+ messages in thread
From: Jakub Jelinek @ 2013-12-04 17:58 UTC (permalink / raw)
  To: Cary Coutant; +Cc: Tobias Burnus, gcc patches, gfortran

On Wed, Dec 04, 2013 at 09:47:36AM -0800, Cary Coutant wrote:
> > gcc/
> > 2013-11-24  Tobias Burnus  <burnus@net-b.de>
> >
> >       PR debug/37132
> >       * lto-streamer.h (LTO_tags): Add LTO_namelist_decl_ref.
> >       * tree.def (NAMELIST_DECL): Add.
> >       * tree.h (NAMELIST_DECL_ASSOCIATED_DECL): New macro.
> >       * tree.c (initialize_tree_contains_struct): Add asserts for it.
> >       * dwarf2out.c (gen_namelist_decl): New function.
> >       (gen_decl_die, dwarf2out_decl): Call it.
> >       (dwarf2out_imported_module_or_decl_1): Handle NAMELIST_DECL.
> >       * lto-streamer-in.c (lto_input_tree_ref): Handle NAMELIST_DECL.
> >       (lto_input_tree_ref, lto_input_tree_1): Update lto_tag_check_range
> >       call.
> >       * lto-streamer-out.c (lto_output_tree_ref): Handle NAMELIST_DECL.
> >
> > gcc/fortran
> > 2013-11-24  Tobias Burnus  <burnus@net-b.de>
> >
> >       PR debug/37132
> >       * trans-decl.c (generate_namelist_decl, create_module_nml_decl):
> >       New static functions.
> >       (gfc_generate_module_vars, generate_local_vars): Call them.
> >       (gfc_trans_use_stmts): Handle namelists for debug genertion.
> 
> The DWARF parts of this patch are OK with me.

The rest is okay too.

	Jakub

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

end of thread, other threads:[~2013-12-04 17:58 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-09 14:27 PR37132 – RFC patch for generation of DWARF symbol for Fortran's namelists (DW_TAG_namelist) Tobias Burnus
2013-11-11 19:07 ` Cary Coutant
2013-11-12 11:58   ` Tobias Burnus
2013-11-12 19:09     ` Cary Coutant
2013-11-24 13:44 ` Tobias Burnus
2013-11-29  0:51   ` *ping* " Tobias Burnus
2013-12-04  6:37     ` Tobias Burnus
2013-12-04 17:48   ` Cary Coutant
2013-12-04 17:58     ` Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).