This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Slightly improved DWARF2 debug info for Fortran


Hello,

Right now, gfortran writes out useless debug information: No information
about modules, no info about array dimensions, no printable function
arguments, etc.

This patch is a start to improve the debugging info for Fortran.  Without
the patch, gdb doesn't know that Fortran arguments are passed by reference
so it can't really print anything useful for the actual arguments for a
subroutine or function call.

Example:

        program test
        implicit none
        integer i
        real f
        character*10 x

        call sub(1, 3.1415926535897932385128089594061862, "Hi World!")

        i = 2
        f = 2.3
        x = "Go Fortran!"
        call sub(i, f, x)
        end

        subroutine sub(a, b, c)
        implicit none
        integer a
        real b
        character*10 c
        return
        end subroutine

Without the patch, when you step into "sub", you get:
(gdb) next
7               call sub(1, 3.1415926535897932385128089594061862, "Hi World!")
(gdb) step
sub_ (a=@0x469fd4, b=@0x469fd0, c=@0x469fc4, _c=9) at debug-pass-by-reference.f:20

Needless to say, this is totally useless.


After patch, we get something still quite odd but at least a lot more
useful IMHO:

(gdb) next
7               call sub(1, 3.1415926535897932385128089594061862, "Hi World!")
(gdb) step
sub_ (a=1, b=3.14159274, c=(72 'H', 105 'i', 32 ' ', 87 'W', 111 'o', 114 'r', 108 'l', 100 'd', 33 '!', 0 '\000'), _c=9) at debug-pass-by-reference.f:20


I've also modified dwarf2out to add the DW_CC_program attribute.  The
purpose is to have MAIN__ recognized as the main program, but gdb does
not yet understand that.  I'm planning to figure out how to fix that.

I've only bootstrapped c,fortran with this patch, because I'm first
looking for comments from people who know dwarf2out.c better than I do. 
I know almost nothing about DWARF and even less about dwarf2out so I
could really use a good review here ;-)

Thanks,

Gr.
Steven



        * dwarf2out.c (is_main_program): New.
        (add_calling_convention_attribute): Use it to output DW_CC_program.
        (loc_descriptor_from_tree_1): For Fortran PARM_DECLs with a
        REFERENCE_TYPE, output DW_OP_deref.
        (gen_formal_parameter_die): Output the referenced type for such
        PARM_DECLs from here.

Index: dwarf2out.c
===================================================================
--- dwarf2out.c (revision 117927)
+++ dwarf2out.c (working copy)
@@ -4068,6 +4068,7 @@ static bool is_cxx (void);
 static bool is_java (void);
 static bool is_fortran (void);
 static bool is_ada (void);
+static bool is_main_program (dw_die_ref);
 static void remove_AT (dw_die_ref, enum dwarf_attribute);
 static void remove_child_TAG (dw_die_ref, enum dwarf_tag);
 static void add_child_die (dw_die_ref, dw_die_ref);
@@ -5453,6 +5454,20 @@ is_ada (void)
   return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
 }
 
+/* Return TRUE if the subroutine for SUBR_DIE is a main program.  */
+static inline bool
+is_main_program (dw_die_ref subr_die)
+{
+  if (is_fortran ())
+    {
+      /* For GNU Fortran the main program is always called MAIN__.  */
+      const char *subroutine_name = get_AT_string (subr_die, DW_AT_name);
+      return (strcmp (subroutine_name, "MAIN__") == 0);
+    }
+
+  return false;
+}
+
 /* Remove the specified attribute if present.  */
 
 static void
@@ -9194,7 +9209,14 @@ loc_descriptor_from_tree_1 (tree loc, in
 
            /* Certain constructs can only be represented at top-level.  */
            if (want_address == 2)
-             return loc_descriptor (rtl);
+             {
+               ret = loc_descriptor (rtl);
+               if (is_fortran ()
+                   && TREE_CODE (loc) == PARM_DECL
+                   && TREE_CODE (TREE_TYPE (loc)) == REFERENCE_TYPE)
+                 add_loc_descr (&ret, new_loc_descr (DW_OP_deref, 0, 0));
+               return ret;
+             }
 
            mode = GET_MODE (rtl);
            if (MEM_P (rtl))
@@ -11105,11 +11127,13 @@ add_calling_convention_attribute (dw_die
 {
   enum dwarf_calling_convention value = DW_CC_normal;
 
-  value = targetm.dwarf_calling_convention (type);
+  if (is_main_program (subr_die))
+    value = DW_CC_program;
+  else
+    value = targetm.dwarf_calling_convention (type);
 
-  /* Only add the attribute if the backend requests it, and
-     is not DW_CC_normal.  */
-  if (value && (value != DW_CC_normal))
+  /* Only add the attribute if it is not DW_CC_normal.  */
+  if (value != DW_CC_normal)
     add_AT_unsigned (subr_die, DW_AT_calling_convention, value);
 }
 
@@ -11407,8 +11431,14 @@ gen_formal_parameter_die (tree node, dw_
        add_abstract_origin_attribute (parm_die, origin);
       else
        {
+         tree type = TREE_TYPE (node);
+
          add_name_and_src_coords_attributes (parm_die, node);
-         add_type_attribute (parm_die, TREE_TYPE (node),
+         if (is_fortran ()
+             && TREE_CODE (node) == PARM_DECL
+             && TREE_CODE (type) == REFERENCE_TYPE)
+           type = TREE_TYPE (type);
+         add_type_attribute (parm_die, type,
                              TREE_READONLY (node),
                              TREE_THIS_VOLATILE (node),
                              context_die);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]