OSDN Git Service

PR fortran/23057
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Aug 2008 18:45:25 +0000 (18:45 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Aug 2008 18:45:25 +0000 (18:45 +0000)
* dwarf2out.c (gen_variable_die): Represent Fortran COMMON vars
as DW_TAG_variable children of DW_TAG_common_block rather than
DW_TAG_member children.  Put DW_AT_external to individual
DW_TAG_variable DIEs, not to DW_TAG_common_block.

* gfortran.dg/debug/pr35154-dwarf2.f: Adjust for replacement
of DW_TAG_member with DW_TAG_variable.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139775 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f

index 809bfd6..9fa3c46 100644 (file)
@@ -1,5 +1,11 @@
 2008-08-29  Jakub Jelinek  <jakub@redhat.com>
 
+       PR fortran/23057
+       * dwarf2out.c (gen_variable_die): Represent Fortran COMMON vars
+       as DW_TAG_variable children of DW_TAG_common_block rather than
+       DW_TAG_member children.  Put DW_AT_external to individual
+       DW_TAG_variable DIEs, not to DW_TAG_common_block.
+
        * dwarf2out.c (add_bound_info): If lookup_decl_die failed, try
        loc_descriptor_from_tree_1.
 
index 4c6364c..ab9d0dc 100644 (file)
@@ -13531,43 +13531,66 @@ gen_variable_die (tree decl, dw_die_ref context_die)
     {
       tree field;
       dw_die_ref com_die;
+      dw_loc_descr_ref loc;
 
-      if (lookup_decl_die (decl))
-       return;
+      com_die = lookup_decl_die (decl);
+      if (com_die)
+       {
+         if (get_AT (com_die, DW_AT_location) == NULL)
+           {
+             loc = loc_descriptor_from_tree (com_decl);
+             if (loc)
+               {
+                 if (off)
+                   add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst,
+                                                       off, 0));
+                 add_AT_loc (com_die, DW_AT_location, loc);
+                 remove_AT (com_die, DW_AT_declaration);
+               }
+           }
+         return;
+       }
       field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
       var_die = lookup_decl_die (com_decl);
+      loc = loc_descriptor_from_tree (com_decl);
       if (var_die == NULL)
        {
          const char *cnam
            = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
-         dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
 
          var_die = new_die (DW_TAG_common_block, context_die, decl);
          add_name_and_src_coords_attributes (var_die, com_decl);
-         add_AT_flag (var_die, DW_AT_external, 1);
          if (loc)
-           add_AT_loc (var_die, DW_AT_location, loc);
+           {
+             add_AT_loc (var_die, DW_AT_location, loc);
+             /* Avoid sharing the same loc descriptor between
+                DW_TAG_common_block and DW_TAG_variable.  */
+             loc = loc_descriptor_from_tree (com_decl);
+           }
           else if (DECL_EXTERNAL (decl))
            add_AT_flag (var_die, DW_AT_declaration, 1);
          add_pubname_string (cnam, var_die); /* ??? needed? */
          equate_decl_number_to_die (com_decl, var_die);
        }
-      else if (get_AT (var_die, DW_AT_location) == NULL)
+      else if (get_AT (var_die, DW_AT_location) == NULL && loc)
        {
-         dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
-
-         if (loc)
-           {
-             add_AT_loc (var_die, DW_AT_location, loc);
-             remove_AT (var_die, DW_AT_declaration);
-           }
+         add_AT_loc (var_die, DW_AT_location, loc);
+         loc = loc_descriptor_from_tree (com_decl);
+         remove_AT (var_die, DW_AT_declaration);
        }
-      com_die = new_die (DW_TAG_member, var_die, decl);
+      com_die = new_die (DW_TAG_variable, var_die, decl);
       add_name_and_src_coords_attributes (com_die, decl);
       add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
                          TREE_THIS_VOLATILE (decl), context_die);
-      add_AT_loc (com_die, DW_AT_data_member_location,
-                 int_loc_descriptor (off));
+      add_AT_flag (com_die, DW_AT_external, 1);
+      if (loc)
+       {
+         if (off)
+           add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst, off, 0));
+         add_AT_loc (com_die, DW_AT_location, loc);
+       }
+      else if (DECL_EXTERNAL (decl))
+       add_AT_flag (com_die, DW_AT_declaration, 1);
       equate_decl_number_to_die (decl, com_die);
       return;
     }
index 2aa360a..5f0d09e 100644 (file)
@@ -1,3 +1,9 @@
+2008-08-22  Jakub Jelinek  <jakub@redhat.com>
+
+       PR fortran/23057
+       * gfortran.dg/debug/pr35154-dwarf2.f: Adjust for replacement
+       of DW_TAG_member with DW_TAG_variable.
+
 2008-08-29  Jan Hubicka  <jh@suse.cz>
 
        * gcc.dg/ipa/modif-1.c: Update template.
index 0203d13..d5003a3 100644 (file)
@@ -27,11 +27,11 @@ C { dg-options "-dA" }
 
 C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
 C { dg-final { scan-assembler "DW_AT_name: \"__BLNK__\"" } }
-C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
+C { dg-final { scan-assembler "(DIE.*DW_TAG_variable)" } }
 C { dg-final { scan-assembler "\"i.*\".*DW_AT_name" } }
 C { dg-final { scan-assembler "\"j.*\".*DW_AT_name" } }
 C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
 C { dg-final { scan-assembler "DW_AT_name: \"label\"" } }
-C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
+C { dg-final { scan-assembler "(DIE.*DW_TAG_variable)" } }
 C { dg-final { scan-assembler "\"l.*\".*DW_AT_name" } }
 C { dg-final { scan-assembler "\"m.*\".*DW_AT_name" } }