66f35a6
2008-05-07  Jakub Jelinek  <jakub@redhat.com>
66f35a6
 
66f35a6
	PR debug/35896
66f35a6
	* dwarf2out.c (dw_expand_expr, common_check): Removed.
66f35a6
	(fortran_common): New function.
66f35a6
	(gen_variable_die): Call fortran_common instead of common_check,
66f35a6
	adjust for it returning tree instead of rtx.  Formatting.
66f35a6
66f35a6
2008-04-26  George Helffrich  <george@gcc.gnu.org>
66f35a6
66f35a6
	PR fortran/35892
66f35a6
	PR fortran/35154
66f35a6
	* trans-common.c (create_common):  Add decl to function
66f35a6
	chain (if inside one) to preserve identifier scope in debug output.
66f35a6
66f35a6
	* gfortran.dg/debug/pr35154-stabs.f:  New test case for
66f35a6
	.stabs functionality.
66f35a6
	* gfortran.dg/debug/pr35154-dwarf2.f:  New test case for
66f35a6
	DWARF functionality.
66f35a6
66f35a6
2008-04-18  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
66f35a6
66f35a6
	PR fortran/35724
66f35a6
	* trans-common.c (create_common): Revert patch causing regression.
66f35a6
66f35a6
2008-04-01  George Helffrich  <george@gcc.gnu.org>
66f35a6
66f35a6
	PR fortran/PR35154, fortran/PR23057
66f35a6
	* fortran/trans-common.c (create_common):  Add decl to function
66f35a6
	chain to preserve identifier scope in debug output.
66f35a6
66f35a6
	* dbxout.c: Emit .stabs debug info for Fortran COMMON block
66f35a6
	variables as base symbol name + offset using N_BCOMM/N_ECOMM.
66f35a6
	(is_fortran, dbxout_common_name, dbxout_common_check): New functions.
66f35a6
	(dbxout_symbol_location): Transform N_LCSYM to N_GSYM for storage
66f35a6
	in common.
66f35a6
	(dbxout_syms): Check for COMMON-based symbol and wrap in
66f35a6
	N_BCOMM/N_ECOMM stab bracket, including as many symbols as possible
66f35a6
	in bracket for efficiency.
66f35a6
66f35a6
	* dwarf2out.c: Emit DWARF debug info for Fortran COMMON block
66f35a6
	using DW_TAG_common_block + member offset.
66f35a6
	(add_pubname_string): New function.
66f35a6
	(dw_expand_expr): New function to find block name and offset for
66f35a6
	COMMON var.
66f35a6
	(common_check): New function to check whether symbol in Fortran COMMON.
66f35a6
	(gen_variable_die): If COMMON, use DW_TAG_common_block.
66f35a6
66f35a6
	* testsuite/gcc.dg/debug/pr35154.c:  New test to check that non-Fortran
66f35a6
	use of common is unchanged.
66f35a6
66f35a6
	* testsuite/lib/gfortran-dg.exp:  New harness to compile Fortran progs
66f35a6
	with all combinations of debug options available on target.
66f35a6
	* testsuite/gfortran.dg/debug/debug.exp:  Ditto.
66f35a6
	* testsuite/gfortran.dg/debug/trivial.f:  Ditto.
66f35a6
66f35a6
--- gcc/dbxout.c	(revision 133800)
66f35a6
+++ gcc/dbxout.c	(revision 133801)
66f35a6
@@ -322,10 +322,13 @@ static void dbxout_type_methods (tree);
66f35a6
 static void dbxout_range_type (tree);
66f35a6
 static void dbxout_type (tree, int);
66f35a6
 static bool print_int_cst_bounds_in_octal_p (tree);
66f35a6
+static bool is_fortran (void);
66f35a6
 static void dbxout_type_name (tree);
66f35a6
 static void dbxout_class_name_qualifiers (tree);
66f35a6
 static int dbxout_symbol_location (tree, tree, const char *, rtx);
66f35a6
 static void dbxout_symbol_name (tree, const char *, int);
66f35a6
+static void dbxout_common_name (tree, const char *, STAB_CODE_TYPE);
66f35a6
+static const char *dbxout_common_check (tree, int *);
66f35a6
 static void dbxout_global_decl (tree);
66f35a6
 static void dbxout_type_decl (tree, int);
66f35a6
 static void dbxout_handle_pch (unsigned);
66f35a6
@@ -973,6 +976,14 @@ get_lang_number (void)
66f35a6
 
66f35a6
 }
66f35a6
 
66f35a6
+static bool
66f35a6
+is_fortran (void)
66f35a6
+{
66f35a6
+   unsigned int lang = get_lang_number ();
66f35a6
+
66f35a6
+   return (lang == N_SO_FORTRAN) || (lang == N_SO_FORTRAN90);
66f35a6
+}
66f35a6
+
66f35a6
 /* At the beginning of compilation, start writing the symbol table.
66f35a6
    Initialize `typevec' and output the standard data types of C.  */
66f35a6
 
66f35a6
@@ -2868,8 +2879,15 @@ dbxout_symbol_location (tree decl, tree 
66f35a6
     {
66f35a6
       if (TREE_PUBLIC (decl))
66f35a6
 	{
66f35a6
+	  int offs;
66f35a6
 	  letter = 'G';
66f35a6
 	  code = N_GSYM;
66f35a6
+	  if (NULL != dbxout_common_check (decl, &offs))
66f35a6
+	    {
66f35a6
+	      letter = 'V';
66f35a6
+	      addr = 0;
66f35a6
+	      number = offs;
66f35a6
+	    }
66f35a6
 	}
66f35a6
       else
66f35a6
 	{
66f35a6
@@ -2915,7 +2933,17 @@ dbxout_symbol_location (tree decl, tree 
66f35a6
 	  if (DECL_INITIAL (decl) == 0
66f35a6
 	      || (!strcmp (lang_hooks.name, "GNU C++")
66f35a6
 		  && DECL_INITIAL (decl) == error_mark_node))
66f35a6
-	    code = N_LCSYM;
66f35a6
+	    {
66f35a6
+	      int offs;
66f35a6
+	      code = N_LCSYM;
66f35a6
+	      if (NULL != dbxout_common_check (decl, &offs))
66f35a6
+	        {
66f35a6
+		  addr = 0;
66f35a6
+		  number = offs;
66f35a6
+		  letter = 'V';
66f35a6
+		  code = N_GSYM;
66f35a6
+		}
66f35a6
+	    }
66f35a6
 	  else if (DECL_IN_TEXT_SECTION (decl))
66f35a6
 	    /* This is not quite right, but it's the closest
66f35a6
 	       of all the codes that Unix defines.  */
66f35a6
@@ -3004,9 +3032,17 @@ dbxout_symbol_location (tree decl, tree 
66f35a6
 	 variable, thereby avoiding the need for a register.  In such
66f35a6
 	 cases we're forced to lie to debuggers and tell them that
66f35a6
 	 this variable was itself `static'.  */
66f35a6
+      int offs;
66f35a6
       code = N_LCSYM;
66f35a6
       letter = 'V';
66f35a6
-      addr = XEXP (XEXP (home, 0), 0);
66f35a6
+      if (NULL == dbxout_common_check (decl, &offs))
66f35a6
+        addr = XEXP (XEXP (home, 0), 0);
66f35a6
+      else
66f35a6
+        {
66f35a6
+	  addr = 0;
66f35a6
+	  number = offs;
66f35a6
+	  code = N_GSYM;
66f35a6
+	}
66f35a6
     }
66f35a6
   else if (GET_CODE (home) == CONCAT)
66f35a6
     {
66f35a6
@@ -3091,6 +3127,115 @@ dbxout_symbol_name (tree decl, const cha
66f35a6
     stabstr_C (letter);
66f35a6
 }
66f35a6
 
66f35a6
+
66f35a6
+/* Output the common block name for DECL in a stabs.
66f35a6
+
66f35a6
+   Symbols in global common (.comm) get wrapped with an N_BCOMM/N_ECOMM pair
66f35a6
+   around each group of symbols in the same .comm area.  The N_GSYM stabs
66f35a6
+   that are emitted only contain the offset in the common area.  This routine
66f35a6
+   emits the N_BCOMM and N_ECOMM stabs.  */
66f35a6
+
66f35a6
+static void
66f35a6
+dbxout_common_name (tree decl, const char *name, STAB_CODE_TYPE op)
66f35a6
+{
66f35a6
+  dbxout_begin_complex_stabs ();
66f35a6
+  stabstr_S (name);
66f35a6
+  dbxout_finish_complex_stabs (decl, op, NULL_RTX, NULL, 0);
66f35a6
+}
66f35a6
+
66f35a6
+/* Check decl to determine whether it is a VAR_DECL destined for storage in a
66f35a6
+   common area.  If it is, the return value will be a non-null string giving
66f35a6
+   the name of the common storage block it will go into.  If non-null, the
66f35a6
+   value is the offset into the common block for that symbol's storage.  */
66f35a6
+
66f35a6
+static const char *
66f35a6
+dbxout_common_check (tree decl, int *value)
66f35a6
+{
66f35a6
+  rtx home;
66f35a6
+  rtx sym_addr;
66f35a6
+  const char *name = NULL;
66f35a6
+  
66f35a6
+  /* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
66f35a6
+     it does not have a value (the offset into the common area), or if it
66f35a6
+     is thread local (as opposed to global) then it isn't common, and shouldn't
66f35a6
+     be handled as such.
66f35a6
+     
66f35a6
+     ??? DECL_THREAD_LOCAL_P check prevents problems with improper .stabs
66f35a6
+     for thread-local symbols.  Can be handled via same mechanism as used
66f35a6
+     in dwarf2out.c.  */
66f35a6
+  if (TREE_CODE (decl) != VAR_DECL
66f35a6
+      || !TREE_PUBLIC(decl)
66f35a6
+      || !TREE_STATIC(decl)
66f35a6
+      || !DECL_HAS_VALUE_EXPR_P(decl)
66f35a6
+      || DECL_THREAD_LOCAL_P (decl)
66f35a6
+      || !is_fortran ())
66f35a6
+    return NULL;
66f35a6
+
66f35a6
+  home = DECL_RTL (decl); 
66f35a6
+  if (home == NULL_RTX || GET_CODE (home) != MEM)
66f35a6
+    return NULL;
66f35a6
+
66f35a6
+  sym_addr = dbxout_expand_expr (DECL_VALUE_EXPR (decl));
66f35a6
+  if (sym_addr == NULL_RTX || GET_CODE (sym_addr) != MEM)
66f35a6
+    return NULL;
66f35a6
+
66f35a6
+  sym_addr = XEXP (sym_addr, 0);
66f35a6
+  if (GET_CODE (sym_addr) == CONST)
66f35a6
+    sym_addr = XEXP (sym_addr, 0);
66f35a6
+  if ((GET_CODE (sym_addr) == SYMBOL_REF || GET_CODE (sym_addr) == PLUS)
66f35a6
+      && DECL_INITIAL (decl) == 0)
66f35a6
+    {
66f35a6
+
66f35a6
+      /* We have a sym that will go into a common area, meaning that it
66f35a6
+         will get storage reserved with a .comm/.lcomm assembler pseudo-op.
66f35a6
+
66f35a6
+         Determine name of common area this symbol will be an offset into,
66f35a6
+         and offset into that area.  Also retrieve the decl for the area
66f35a6
+         that the symbol is offset into.  */
66f35a6
+      tree cdecl = NULL;
66f35a6
+
66f35a6
+      switch (GET_CODE (sym_addr))
66f35a6
+        {
66f35a6
+        case PLUS:
66f35a6
+          if (GET_CODE (XEXP (sym_addr, 0)) == CONST_INT)
66f35a6
+            {
66f35a6
+              name =
66f35a6
+                targetm.strip_name_encoding(XSTR (XEXP (sym_addr, 1), 0));
66f35a6
+              *value = INTVAL (XEXP (sym_addr, 0));
66f35a6
+              cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 1));
66f35a6
+            }
66f35a6
+          else
66f35a6
+            {
66f35a6
+              name =
66f35a6
+                targetm.strip_name_encoding(XSTR (XEXP (sym_addr, 0), 0));
66f35a6
+              *value = INTVAL (XEXP (sym_addr, 1));
66f35a6
+              cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 0));
66f35a6
+            }
66f35a6
+          break;
66f35a6
+
66f35a6
+        case SYMBOL_REF:
66f35a6
+          name = targetm.strip_name_encoding(XSTR (sym_addr, 0));
66f35a6
+          *value = 0;
66f35a6
+          cdecl = SYMBOL_REF_DECL (sym_addr);
66f35a6
+          break;
66f35a6
+
66f35a6
+        default:
66f35a6
+          error ("common symbol debug info is not structured as "
66f35a6
+                 "symbol+offset");
66f35a6
+        }
66f35a6
+
66f35a6
+      /* Check area common symbol is offset into.  If this is not public, then
66f35a6
+         it is not a symbol in a common block.  It must be a .lcomm symbol, not
66f35a6
+         a .comm symbol.  */
66f35a6
+      if (cdecl == NULL || !TREE_PUBLIC(cdecl))
66f35a6
+        name = NULL;
66f35a6
+    }
66f35a6
+  else
66f35a6
+    name = NULL;
66f35a6
+
66f35a6
+  return name;
66f35a6
+}
66f35a6
+
66f35a6
 /* Output definitions of all the decls in a chain. Return nonzero if
66f35a6
    anything was output */
66f35a6
 
66f35a6
@@ -3098,11 +3243,38 @@ int
66f35a6
 dbxout_syms (tree syms)
66f35a6
 {
66f35a6
   int result = 0;
66f35a6
+  const char *comm_prev = NULL;
66f35a6
+  tree syms_prev = NULL;
66f35a6
+
66f35a6
   while (syms)
66f35a6
     {
66f35a6
+      int temp, copen, cclos;
66f35a6
+      const char *comm_new;
66f35a6
+
66f35a6
+      /* Check for common symbol, and then progression into a new/different
66f35a6
+         block of common symbols.  Emit closing/opening common bracket if
66f35a6
+         necessary.  */
66f35a6
+      comm_new = dbxout_common_check (syms, &temp);
66f35a6
+      copen = comm_new != NULL
66f35a6
+              && (comm_prev == NULL || strcmp (comm_new, comm_prev));
66f35a6
+      cclos = comm_prev != NULL
66f35a6
+              && (comm_new == NULL || strcmp (comm_new, comm_prev));
66f35a6
+      if (cclos)
66f35a6
+        dbxout_common_name (syms_prev, comm_prev, N_ECOMM);
66f35a6
+      if (copen)
66f35a6
+        {
66f35a6
+          dbxout_common_name (syms, comm_new, N_BCOMM);
66f35a6
+          syms_prev = syms;
66f35a6
+        }
66f35a6
+      comm_prev = comm_new;
66f35a6
+
66f35a6
       result += dbxout_symbol (syms, 1);
66f35a6
       syms = TREE_CHAIN (syms);
66f35a6
     }
66f35a6
+
66f35a6
+  if (comm_prev != NULL)
66f35a6
+    dbxout_common_name (syms_prev, comm_prev, N_ECOMM);
66f35a6
+
66f35a6
   return result;
66f35a6
 }
66f35a6
 
66f35a6
--- gcc/dwarf2out.c	(revision 133800)
66f35a6
+++ gcc/dwarf2out.c	(revision 133801)
66f35a6
@@ -4429,6 +4429,7 @@ static void output_compilation_unit_head
66f35a6
 static void output_comp_unit (dw_die_ref, int);
66f35a6
 static const char *dwarf2_name (tree, int);
66f35a6
 static void add_pubname (tree, dw_die_ref);
66f35a6
+static void add_pubname_string (const char *, dw_die_ref);
66f35a6
 static void add_pubtype (tree, dw_die_ref);
66f35a6
 static void output_pubnames (VEC (pubname_entry,gc) *);
66f35a6
 static void add_arange (tree, dw_die_ref);
66f35a6
@@ -7659,18 +7660,23 @@ dwarf2_name (tree decl, int scope)
66f35a6
 /* Add a new entry to .debug_pubnames if appropriate.  */
66f35a6
 
66f35a6
 static void
66f35a6
-add_pubname (tree decl, dw_die_ref die)
66f35a6
+add_pubname_string (const char *str, dw_die_ref die)
66f35a6
 {
66f35a6
   pubname_entry e;
66f35a6
 
66f35a6
-  if (! TREE_PUBLIC (decl))
66f35a6
-    return;
66f35a6
-
66f35a6
   e.die = die;
66f35a6
-  e.name = xstrdup (dwarf2_name (decl, 1));
66f35a6
+  e.name = xstrdup (str);
66f35a6
   VEC_safe_push (pubname_entry, gc, pubname_table, &e);
66f35a6
 }
66f35a6
 
66f35a6
+static void
66f35a6
+add_pubname (tree decl, dw_die_ref die)
66f35a6
+{
66f35a6
+
66f35a6
+  if (TREE_PUBLIC (decl))
66f35a6
+    add_pubname_string (dwarf2_name (decl, 1), die);
66f35a6
+}
66f35a6
+
66f35a6
 /* Add a new entry to .debug_pubtypes if appropriate.  */
66f35a6
 
66f35a6
 static void
66f35a6
@@ -10914,6 +10920,57 @@ secname_for_decl (const_tree decl)
66f35a6
   return secname;
66f35a6
 }
66f35a6
 
66f35a6
+/* Check whether decl is a Fortran COMMON symbol.  If not, NULL_RTX is returned.
66f35a6
+   If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the
66f35a6
+   value is the offset into the common block for the symbol.  */
66f35a6
+
66f35a6
+static tree
66f35a6
+fortran_common (tree decl, HOST_WIDE_INT *value)
66f35a6
+{
66f35a6
+  tree val_expr, cvar;
66f35a6
+  enum machine_mode mode;
66f35a6
+  HOST_WIDE_INT bitsize, bitpos;
66f35a6
+  tree offset;
66f35a6
+  int volatilep = 0, unsignedp = 0;
66f35a6
+
66f35a6
+  /* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
66f35a6
+     it does not have a value (the offset into the common area), or if it
66f35a6
+     is thread local (as opposed to global) then it isn't common, and shouldn't
66f35a6
+     be handled as such.  */
66f35a6
+  if (TREE_CODE (decl) != VAR_DECL
66f35a6
+      || !TREE_PUBLIC (decl)
66f35a6
+      || !TREE_STATIC (decl)
66f35a6
+      || !DECL_HAS_VALUE_EXPR_P (decl)
66f35a6
+      || !is_fortran ())
66f35a6
+    return NULL_TREE;
66f35a6
+
66f35a6
+  val_expr = DECL_VALUE_EXPR (decl);
66f35a6
+  if (TREE_CODE (val_expr) != COMPONENT_REF)
66f35a6
+    return NULL_TREE;
66f35a6
+
66f35a6
+  cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset,
66f35a6
+			      &mode, &unsignedp, &volatilep, true);
66f35a6
+
66f35a6
+  if (cvar == NULL_TREE
66f35a6
+      || TREE_CODE (cvar) != VAR_DECL
66f35a6
+      || DECL_ARTIFICIAL (cvar)
66f35a6
+      || !TREE_PUBLIC (cvar))
66f35a6
+    return NULL_TREE;
66f35a6
+
66f35a6
+  *value = 0;
66f35a6
+  if (offset != NULL)
66f35a6
+    {
66f35a6
+      if (!host_integerp (offset, 0))
66f35a6
+	return NULL_TREE;
66f35a6
+      *value = tree_low_cst (offset, 0);
66f35a6
+    }
66f35a6
+  if (bitpos != 0)
66f35a6
+    *value += bitpos / BITS_PER_UNIT;
66f35a6
+
66f35a6
+  return cvar;
66f35a6
+}
66f35a6
+
66f35a6
+
66f35a6
 /* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
66f35a6
    data attribute for a variable or a parameter.  We generate the
66f35a6
    DW_AT_const_value attribute only in those cases where the given variable
66f35a6
@@ -12811,9 +12868,10 @@ gen_subprogram_die (tree decl, dw_die_re
66f35a6
 static void
66f35a6
 gen_variable_die (tree decl, dw_die_ref context_die)
66f35a6
 {
66f35a6
+  HOST_WIDE_INT off;
66f35a6
+  tree com_decl;
66f35a6
+  dw_die_ref var_die;
66f35a6
   tree origin = decl_ultimate_origin (decl);
66f35a6
-  dw_die_ref var_die = new_die (DW_TAG_variable, context_die, decl);
66f35a6
-
66f35a6
   dw_die_ref old_die = lookup_decl_die (decl);
66f35a6
   int declaration = (DECL_EXTERNAL (decl)
66f35a6
 		     /* If DECL is COMDAT and has not actually been
66f35a6
@@ -12837,6 +12895,37 @@ gen_variable_die (tree decl, dw_die_ref 
66f35a6
 			 && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
66f35a6
 		     || class_or_namespace_scope_p (context_die));
66f35a6
 
66f35a6
+  com_decl = fortran_common (decl, &off;;
66f35a6
+
66f35a6
+  /* Symbol in common gets emitted as a child of the common block, in the form
66f35a6
+     of a data member.
66f35a6
+
66f35a6
+     ??? This creates a new common block die for every common block symbol.
66f35a6
+     Better to share same common block die for all symbols in that block.  */
66f35a6
+  if (com_decl)
66f35a6
+    {
66f35a6
+      tree field;
66f35a6
+      dw_die_ref com_die;
66f35a6
+      const char *cnam = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
66f35a6
+      dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
66f35a6
+
66f35a6
+      field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
66f35a6
+      var_die = new_die (DW_TAG_common_block, context_die, decl);
66f35a6
+      add_name_and_src_coords_attributes (var_die, field);
66f35a6
+      add_AT_flag (var_die, DW_AT_external, 1);
66f35a6
+      add_AT_loc (var_die, DW_AT_location, loc);
66f35a6
+      com_die = new_die (DW_TAG_member, var_die, decl);
66f35a6
+      add_name_and_src_coords_attributes (com_die, decl);
66f35a6
+      add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
66f35a6
+			  TREE_THIS_VOLATILE (decl), context_die);
66f35a6
+      add_AT_loc (com_die, DW_AT_data_member_location,
66f35a6
+		  int_loc_descriptor (off));
66f35a6
+      add_pubname_string (cnam, var_die); /* ??? needed? */
66f35a6
+      return;
66f35a6
+    }
66f35a6
+
66f35a6
+  var_die = new_die (DW_TAG_variable, context_die, decl);
66f35a6
+
66f35a6
   if (origin != NULL)
66f35a6
     add_abstract_origin_attribute (var_die, origin);
66f35a6
 
66f35a6
@@ -13812,8 +13901,13 @@ decls_for_scope (tree stmt, dw_die_ref c
66f35a6
 	    add_child_die (context_die, die);
66f35a6
 	  /* Do not produce debug information for static variables since
66f35a6
 	     these might be optimized out.  We are called for these later
66f35a6
-	     in varpool_analyze_pending_decls. */
66f35a6
-	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
66f35a6
+	     in varpool_analyze_pending_decls.
66f35a6
+
66f35a6
+	     But *do* produce it for Fortran COMMON variables because,
66f35a6
+	     even though they are static, their names can differ depending
66f35a6
+	     on the scope, which we need to preserve.  */
66f35a6
+	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
66f35a6
+	      && !(is_fortran () && TREE_PUBLIC (decl)))
66f35a6
 	    ;
66f35a6
 	  else
66f35a6
 	    gen_decl_die (decl, context_die);
66f35a6
@@ -14137,6 +14231,16 @@ gen_decl_die (tree decl, dw_die_ref cont
66f35a6
       if (debug_info_level <= DINFO_LEVEL_TERSE)
66f35a6
 	break;
66f35a6
 
66f35a6
+      /* If this is the global definition of the Fortran COMMON block, we don't
66f35a6
+         need to do anything.  Syntactically, the block itself has no identity,
66f35a6
+         just its constituent identifiers.  */
66f35a6
+      if (TREE_CODE (decl) == VAR_DECL
66f35a6
+          && TREE_PUBLIC (decl)
66f35a6
+          && TREE_STATIC (decl)
66f35a6
+          && is_fortran ()
66f35a6
+          && !DECL_HAS_VALUE_EXPR_P (decl))
66f35a6
+        break;
66f35a6
+
66f35a6
       /* Output any DIEs that are needed to specify the type of this data
66f35a6
 	 object.  */
66f35a6
       if (TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl))
66f35a6
@@ -14203,7 +14307,15 @@ dwarf2out_global_decl (tree decl)
66f35a6
   /* Output DWARF2 information for file-scope tentative data object
66f35a6
      declarations, file-scope (extern) function declarations (which had no
66f35a6
      corresponding body) and file-scope tagged type declarations and
66f35a6
-     definitions which have not yet been forced out.  */
66f35a6
+     definitions which have not yet been forced out.
66f35a6
+
66f35a6
+     Ignore the global decl of any Fortran COMMON blocks which also wind up here
66f35a6
+     though they have already been described in the local scope for the 
66f35a6
+     procedures using them.  */
66f35a6
+  if (TREE_CODE (decl) == VAR_DECL
66f35a6
+      && TREE_PUBLIC (decl) && TREE_STATIC (decl) && is_fortran ())
66f35a6
+    return;
66f35a6
+
66f35a6
   if (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
66f35a6
     dwarf2out_decl (decl);
66f35a6
 }
66f35a6
--- gcc/fortran/trans-common.c	(revision 134695)
66f35a6
+++ gcc/fortran/trans-common.c	(revision 134696)
66f35a6
@@ -687,7 +687,11 @@ create_common (gfc_common_head *com, seg
66f35a6
       /* This is a fake variable just for debugging purposes.  */
66f35a6
       TREE_ASM_WRITTEN (var_decl) = 1;
66f35a6
 
66f35a6
-      if (com)
66f35a6
+      /* To preserve identifier names in COMMON, chain to procedure
66f35a6
+	 scope unless at top level in a module definition.  */
66f35a6
+      if (com
66f35a6
+	  && s->sym->ns->proc_name
66f35a6
+	  && s->sym->ns->proc_name->attr.flavor == FL_MODULE)
66f35a6
 	var_decl = pushdecl_top_level (var_decl);
66f35a6
       else
66f35a6
 	gfc_add_decl_to_function (var_decl);
66f35a6
--- gcc/testsuite/gfortran.dg/debug/pr35154-stabs.f	(revision 0)
66f35a6
+++ gcc/testsuite/gfortran.dg/debug/pr35154-stabs.f	(revision 134696)
66f35a6
@@ -0,0 +1,35 @@
66f35a6
+C     Test program for common block debugging.  G. Helffrich 11 July 2004.
66f35a6
+C { dg-do compile }
66f35a6
+C { dg-skip-if "No stabs" { mmix-*-* *-*-netware* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-sysv5* *-*-vxworks* } { "*" } { "" } }
66f35a6
+C { dg-skip-if "No stabs" {*-*-* } { "*" } { "-gstabs" } }
66f35a6
+      common i,j
66f35a6
+      common /label/l,m
66f35a6
+      i = 1
66f35a6
+      j = 2
66f35a6
+      k = 3
66f35a6
+      l = 4
66f35a6
+      m = 5
66f35a6
+      call sub
66f35a6
+      end
66f35a6
+      subroutine sub
66f35a6
+      common /label/l,m
66f35a6
+      logical first
66f35a6
+      save n
66f35a6
+      data first /.true./
66f35a6
+      if (first) then
66f35a6
+         n = 0
66f35a6
+	 first = .false.
66f35a6
+      endif
66f35a6
+      n = n + 1
66f35a6
+      l = l + 1
66f35a6
+      return
66f35a6
+      end
66f35a6
+
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"__BLNK__\",226" } }
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"i:V.*\",.*,0" } }
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"j:V.*\",.*,4" } }
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"__BLNK__\",228" } }
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"label_\",226" } }
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"l:V.*\",.*,0" } }
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"m:V.*\",.*,4" } }
66f35a6
+C { dg-final { scan-assembler ".stabs.*\"label_\",228" } }
66f35a6
--- gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f	(revision 0)
66f35a6
+++ gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f	(revision 134696)
66f35a6
@@ -0,0 +1,37 @@
66f35a6
+C     Test program for common block debugging.  G. Helffrich 11 July 2004.
66f35a6
+C { dg-do compile }
66f35a6
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "*" } { "-gdwarf-2" } }
66f35a6
+C { dg-options "-dA" }
66f35a6
+      common i,j
66f35a6
+      common /label/l,m
66f35a6
+      i = 1
66f35a6
+      j = 2
66f35a6
+      k = 3
66f35a6
+      l = 4
66f35a6
+      m = 5
66f35a6
+      call sub
66f35a6
+      end
66f35a6
+      subroutine sub
66f35a6
+      common /label/l,m
66f35a6
+      logical first
66f35a6
+      save n
66f35a6
+      data first /.true./
66f35a6
+      if (first) then
66f35a6
+         n = 0
66f35a6
+	 first = .false.
66f35a6
+      endif
66f35a6
+      n = n + 1
66f35a6
+      l = l + 1
66f35a6
+      return
66f35a6
+      end
66f35a6
+
66f35a6
+C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
66f35a6
+C { dg-final { scan-assembler "DW_AT_name: \"__BLNK__\"" } }
66f35a6
+C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
66f35a6
+C { dg-final { scan-assembler "\"i.*\".*DW_AT_name" } }
66f35a6
+C { dg-final { scan-assembler "\"j.*\".*DW_AT_name" } }
66f35a6
+C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
66f35a6
+C { dg-final { scan-assembler "DW_AT_name: \"label\"" } }
66f35a6
+C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
66f35a6
+C { dg-final { scan-assembler "\"l.*\".*DW_AT_name" } }
66f35a6
+C { dg-final { scan-assembler "\"m.*\".*DW_AT_name" } }
66f35a6
--- gcc/testsuite/gcc.dg/debug/pr35154.c	(revision 0)
66f35a6
+++ gcc/testsuite/gcc.dg/debug/pr35154.c	(revision 133801)
66f35a6
@@ -0,0 +1,34 @@
66f35a6
+/* Test to make sure that stabs for C symbols that go into .comm have the
66f35a6
+   proper structure.  These should be lettered G for the struct that gives
66f35a6
+   the name to the .comm, and should be V or S for .lcomm symbols.  */
66f35a6
+
66f35a6
+static char i_outer;
66f35a6
+struct {
66f35a6
+   char f1;
66f35a6
+   char f2;
66f35a6
+} opta;
66f35a6
+struct {
66f35a6
+   char f1;
66f35a6
+   char f2;
66f35a6
+} optb;
66f35a6
+
66f35a6
+int
66f35a6
+main()
66f35a6
+{
66f35a6
+   static char i_inner[2];
66f35a6
+   i_inner[0] = 'a'; i_inner[1] = 'b';
66f35a6
+   opta.f1 = 'c';
66f35a6
+   opta.f2 = 'd';
66f35a6
+   optb.f1 = 'C';
66f35a6
+   optb.f2 = 'D';
66f35a6
+   i_outer = 'e';
66f35a6
+/* { dg-do compile } */
66f35a6
+/* { dg-skip-if "No stabs" { mmix-*-* *-*-netware* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-sysv5* *-*-vxworks* } { "*" } { "" } } */
66f35a6
+/* { dg-skip-if "stabs only" { *-*-* } { "*" } { "-gstabs" } } */
66f35a6
+   return 0;
66f35a6
+}
66f35a6
+
66f35a6
+/* { dg-final { scan-assembler ".stabs.*i_inner:V" } } */
66f35a6
+/* { dg-final { scan-assembler ".stabs.*i_outer:S" } } */
66f35a6
+/* { dg-final { scan-assembler ".stabs.*opta:G" } } */
66f35a6
+/* { dg-final { scan-assembler ".stabs.*optb:G" } } */
66f35a6
--- gcc/testsuite/lib/gfortran-dg.exp	(revision 133800)
66f35a6
+++ gcc/testsuite/lib/gfortran-dg.exp	(revision 133801)
66f35a6
@@ -1,4 +1,4 @@
66f35a6
-#   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
66f35a6
+#   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
66f35a6
 
66f35a6
 # This program is free software; you can redistribute it and/or modify
66f35a6
 # it under the terms of the GNU General Public License as published by
66f35a6
@@ -107,3 +107,57 @@ proc gfortran-dg-runtest { testcases def
66f35a6
 	}
66f35a6
     }
66f35a6
 }
66f35a6
+
66f35a6
+proc gfortran-dg-debug-runtest { target_compile trivial opt_opts testcases } {
66f35a6
+    global srcdir subdir DEBUG_TORTURE_OPTIONS
66f35a6
+
66f35a6
+    if ![info exists DEBUG_TORTURE_OPTIONS] {
66f35a6
+       set DEBUG_TORTURE_OPTIONS ""
66f35a6
+       set type_list [list "-gstabs" "-gstabs+" "-gxcoff" "-gxcoff+" "-gcoff" "-gdwarf-2" ]
66f35a6
+       foreach type $type_list {
66f35a6
+           set comp_output [$target_compile \
66f35a6
+                   "$srcdir/$subdir/$trivial" "trivial.S" assembly \
66f35a6
+                   "additional_flags=$type"]
66f35a6
+           if { [string match "exit status *" $comp_output] } {
66f35a6
+               continue
66f35a6
+           }
66f35a6
+           if { [string match \
66f35a6
+                       "* target system does not support the * debug format*" \
66f35a6
+                       $comp_output]
66f35a6
+           } {
66f35a6
+               continue
66f35a6
+           }
66f35a6
+           foreach level {1 "" 3} {
66f35a6
+               lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
66f35a6
+               foreach opt $opt_opts {
66f35a6
+                   lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}" \
66f35a6
+                      "$opt" ]
66f35a6
+               }
66f35a6
+           }
66f35a6
+       }
66f35a6
+    }
66f35a6
+
66f35a6
+    verbose -log "Using options $DEBUG_TORTURE_OPTIONS"
66f35a6
+
66f35a6
+    global runtests
66f35a6
+
66f35a6
+    foreach test $testcases {
66f35a6
+       # If we're only testing specific files and this isn't one of 
66f35a6
+       # them, skip it.
66f35a6
+       if ![runtest_file_p $runtests $test] {
66f35a6
+           continue
66f35a6
+       }
66f35a6
+
66f35a6
+       set nshort [file tail [file dirname $test]]/[file tail $test]
66f35a6
+
66f35a6
+       foreach flags $DEBUG_TORTURE_OPTIONS {
66f35a6
+           set doit 1
66f35a6
+           # gcc-specific checking removed here
66f35a6
+
66f35a6
+           if { $doit } {
66f35a6
+               verbose -log "Testing $nshort, $flags" 1
66f35a6
+               dg-test $test $flags ""
66f35a6
+           }
66f35a6
+       }
66f35a6
+    }
66f35a6
+}
66f35a6
--- gcc/testsuite/gfortran.dg/debug/debug.exp	(revision 0)
66f35a6
+++ gcc/testsuite/gfortran.dg/debug/debug.exp	(revision 133801)
66f35a6
@@ -0,0 +1,41 @@
66f35a6
+#  Copyright (C) 2008 Free Software Foundation, Inc.
66f35a6
+
66f35a6
+#  This file is part of GCC.
66f35a6
+#
66f35a6
+#  GCC is free software; you can redistribute it and/or modify it under
66f35a6
+#  the terms of the GNU General Public License as published by the Free
66f35a6
+#  Software Foundation; either version 3, or (at your option) any later
66f35a6
+#  version.
66f35a6
+#
66f35a6
+#  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
66f35a6
+#  WARRANTY; without even the implied warranty of MERCHANTABILITY or
66f35a6
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
66f35a6
+#  for more details.
66f35a6
+#
66f35a6
+#  You should have received a copy of the GNU General Public License
66f35a6
+#  along with GCC; see the file COPYING3.  If not see
66f35a6
+#  <http://www.gnu.org/licenses/>.
66f35a6
+
66f35a6
+# GCC testsuite that uses the `dg.exp' driver.
66f35a6
+
66f35a6
+# Load support procs.
66f35a6
+load_lib gfortran-dg.exp
66f35a6
+load_lib gfortran.exp
66f35a6
+
66f35a6
+# Debugging testsuite proc
66f35a6
+proc gfortran-debug-dg-test { prog do_what extra_tool_flags } {
66f35a6
+   return [gfortran-dg-test $prog $do_what $extra_tool_flags]
66f35a6
+}
66f35a6
+
66f35a6
+# Initialize `dg'.
66f35a6
+dg-init
66f35a6
+
66f35a6
+# Main loop.
66f35a6
+
66f35a6
+gfortran_init
66f35a6
+
66f35a6
+gfortran-dg-debug-runtest gfortran_target_compile trivial.f "" \
66f35a6
+    [lsort [glob -nocomplain $srcdir/$subdir/*.\[fS\]]]
66f35a6
+
66f35a6
+# All done.
66f35a6
+dg-finish
66f35a6
--- gcc/testsuite/gfortran.dg/debug/trivial.f	(revision 0)
66f35a6
+++ gcc/testsuite/gfortran.dg/debug/trivial.f	(revision 133801)
66f35a6
@@ -0,0 +1,2 @@
66f35a6
+      program trivial
66f35a6
+      end