OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / dbxout.c
index f1bde1d..8c59b45 100644 (file)
@@ -1,12 +1,13 @@
 /* Output dbx-format symbol table information from GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
 /* Output dbx-format symbol table information from GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 
 /* Output dbx-format symbol table data.
 
 
 /* Output dbx-format symbol table data.
@@ -81,26 +81,23 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "reload.h"
 #include "output.h"
 #include "dbxout.h"
 #include "reload.h"
 #include "output.h"
 #include "dbxout.h"
+#include "diagnostic-core.h"
 #include "toplev.h"
 #include "tm_p.h"
 #include "ggc.h"
 #include "debug.h"
 #include "function.h"
 #include "target.h"
 #include "toplev.h"
 #include "tm_p.h"
 #include "ggc.h"
 #include "debug.h"
 #include "function.h"
 #include "target.h"
+#include "common/common-target.h"
 #include "langhooks.h"
 #include "obstack.h"
 #include "langhooks.h"
 #include "obstack.h"
+#include "expr.h"
+#include "cgraph.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"
 #endif
 
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"
 #endif
 
-#define DBXOUT_DECR_NESTING \
-  if (--debug_nesting == 0 && symbol_queue_index > 0) \
-    { emit_pending_bincls_if_required (); debug_flush_symbol_queue (); }
-
-#define DBXOUT_DECR_NESTING_AND_RETURN(x) \
-  do {--debug_nesting; return (x);} while (0)
-
 #ifndef ASM_STABS_OP
 # ifdef XCOFF_DEBUGGING_INFO
 #  define ASM_STABS_OP "\t.stabx\t"
 #ifndef ASM_STABS_OP
 # ifdef XCOFF_DEBUGGING_INFO
 #  define ASM_STABS_OP "\t.stabx\t"
@@ -170,8 +167,7 @@ enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
    The file_number and type_number elements are used if DBX_USE_BINCL
    is defined.  */
 
    The file_number and type_number elements are used if DBX_USE_BINCL
    is defined.  */
 
-struct typeinfo GTY(())
-{
+struct GTY(()) typeinfo {
   enum typestatus status;
   int file_number;
   int type_number;
   enum typestatus status;
   int file_number;
   int type_number;
@@ -216,8 +212,8 @@ struct dbx_file
   struct dbx_file *prev;          /* Chain to traverse all pending bincls.  */
 };
 
   struct dbx_file *prev;          /* Chain to traverse all pending bincls.  */
 };
 
-/* This is the top of the stack.  
-   
+/* This is the top of the stack.
+
    This is not saved for PCH, because restoring a PCH should not change it.
    next_file_number does have to be saved, because the PCH may use some
    file numbers; however, just before restoring a PCH, next_file_number
    This is not saved for PCH, because restoring a PCH should not change it.
    next_file_number does have to be saved, because the PCH may use some
    file numbers; however, just before restoring a PCH, next_file_number
@@ -241,13 +237,6 @@ static GTY(()) int scope_labelno;
 
 static GTY(()) int dbxout_source_line_counter;
 
 
 static GTY(()) int dbxout_source_line_counter;
 
-/* Nonzero if we have actually used any of the GDB extensions
-   to the debugging format.  The idea is that we use them for the
-   first time only if there's a strong reason, but once we have done that,
-   we use them whenever convenient.  */
-
-static GTY(()) int have_used_extensions = 0;
-
 /* Number for the next N_SOL filename stabs label.  The number 0 is reserved
    for the N_SO filename stabs label.  */
 
 /* Number for the next N_SOL filename stabs label.  The number 0 is reserved
    for the N_SO filename stabs label.  */
 
@@ -275,15 +264,13 @@ static int pending_bincls = 0;
 static const char *base_input_file;
 
 #ifdef DEBUG_SYMS_TEXT
 static const char *base_input_file;
 
 #ifdef DEBUG_SYMS_TEXT
-#define FORCE_TEXT function_section (current_function_decl);
+#define FORCE_TEXT switch_to_section (current_function_section ())
 #else
 #define FORCE_TEXT
 #endif
 
 #include "gstab.h"
 
 #else
 #define FORCE_TEXT
 #endif
 
 #include "gstab.h"
 
-#define STAB_CODE_TYPE enum __stab_debug_code
-
 /* 1 if PARM is passed to this function in memory.  */
 
 #define PARM_PASSED_IN_MEMORY(PARM) \
 /* 1 if PARM is passed to this function in memory.  */
 
 #define PARM_PASSED_IN_MEMORY(PARM) \
@@ -297,9 +284,12 @@ static const char *base_input_file;
 #endif
 
 /* A C expression for the integer offset value of an argument (N_PSYM)
 #endif
 
 /* A C expression for the integer offset value of an argument (N_PSYM)
-   having address X (an RTX).  The nominal offset is OFFSET.  */
+   having address X (an RTX).  The nominal offset is OFFSET.
+   Note that we use OFFSET + 0 here to avoid the self-assign warning
+   when the macro is called in a context like
+   number = DEBUGGER_ARG_OFFSET(number, X)  */
 #ifndef DEBUGGER_ARG_OFFSET
 #ifndef DEBUGGER_ARG_OFFSET
-#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET)
+#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + 0)
 #endif
 
 /* This obstack holds the stab string currently being constructed.  We
 #endif
 
 /* This obstack holds the stab string currently being constructed.  We
@@ -315,7 +305,7 @@ static void emit_pending_bincls         (void);
 static inline void emit_pending_bincls_if_required (void);
 
 static void dbxout_init (const char *);
 static inline void emit_pending_bincls_if_required (void);
 
 static void dbxout_init (const char *);
+
 static void dbxout_finish (const char *);
 static void dbxout_start_source_file (unsigned, const char *);
 static void dbxout_end_source_file (unsigned);
 static void dbxout_finish (const char *);
 static void dbxout_start_source_file (unsigned, const char *);
 static void dbxout_end_source_file (unsigned);
@@ -325,25 +315,28 @@ static void dbxout_args (tree);
 static void dbxout_type_fields (tree);
 static void dbxout_type_method_1 (tree);
 static void dbxout_type_methods (tree);
 static void dbxout_type_fields (tree);
 static void dbxout_type_method_1 (tree);
 static void dbxout_type_methods (tree);
-static void dbxout_range_type (tree);
+static void dbxout_range_type (tree, tree, tree);
 static void dbxout_type (tree, int);
 static void dbxout_type (tree, int);
-static bool print_int_cst_bounds_in_octal_p (tree);
+static bool print_int_cst_bounds_in_octal_p (tree, tree, tree);
+static bool is_fortran (void);
 static void dbxout_type_name (tree);
 static void dbxout_class_name_qualifiers (tree);
 static int dbxout_symbol_location (tree, tree, const char *, rtx);
 static void dbxout_symbol_name (tree, const char *, int);
 static void dbxout_type_name (tree);
 static void dbxout_class_name_qualifiers (tree);
 static int dbxout_symbol_location (tree, tree, const char *, rtx);
 static void dbxout_symbol_name (tree, const char *, int);
-static void dbxout_block (tree, int, tree);
+static void dbxout_common_name (tree, const char *, stab_code_type);
+static const char *dbxout_common_check (tree, int *);
 static void dbxout_global_decl (tree);
 static void dbxout_type_decl (tree, int);
 static void dbxout_handle_pch (unsigned);
 static void dbxout_global_decl (tree);
 static void dbxout_type_decl (tree, int);
 static void dbxout_handle_pch (unsigned);
+static void debug_free_queue (void);
 \f
 /* The debug hooks structure.  */
 #if defined (DBX_DEBUGGING_INFO)
 
 \f
 /* The debug hooks structure.  */
 #if defined (DBX_DEBUGGING_INFO)
 
-static void dbxout_source_line (unsigned int, const char *);
+static void dbxout_source_line (unsigned int, const char *, int, bool);
 static void dbxout_begin_prologue (unsigned int, const char *);
 static void dbxout_source_file (const char *);
 static void dbxout_begin_prologue (unsigned int, const char *);
 static void dbxout_source_file (const char *);
-static void dbxout_function_end (void);
+static void dbxout_function_end (tree);
 static void dbxout_begin_function (tree);
 static void dbxout_begin_block (unsigned, unsigned);
 static void dbxout_end_block (unsigned, unsigned);
 static void dbxout_begin_function (tree);
 static void dbxout_begin_block (unsigned, unsigned);
 static void dbxout_end_block (unsigned, unsigned);
@@ -353,16 +346,18 @@ const struct gcc_debug_hooks dbx_debug_hooks =
 {
   dbxout_init,
   dbxout_finish,
 {
   dbxout_init,
   dbxout_finish,
+  debug_nothing_void,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
   dbxout_end_source_file,
   dbxout_begin_block,
   dbxout_end_block,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
   dbxout_end_source_file,
   dbxout_begin_block,
   dbxout_end_block,
-  debug_true_tree,                      /* ignore_block */
+  debug_true_const_tree,                /* ignore_block */
   dbxout_source_line,                   /* source_line */
   dbxout_begin_prologue,                /* begin_prologue */
   debug_nothing_int_charstar,           /* end_prologue */
   dbxout_source_line,                   /* source_line */
   dbxout_begin_prologue,                /* begin_prologue */
   debug_nothing_int_charstar,           /* end_prologue */
+  debug_nothing_int_charstar,           /* begin_epilogue */
   debug_nothing_int_charstar,           /* end_epilogue */
 #ifdef DBX_FUNCTION_FIRST
   dbxout_begin_function,
   debug_nothing_int_charstar,           /* end_epilogue */
 #ifdef DBX_FUNCTION_FIRST
   dbxout_begin_function,
@@ -373,12 +368,16 @@ const struct gcc_debug_hooks dbx_debug_hooks =
   dbxout_function_decl,
   dbxout_global_decl,                   /* global_decl */
   dbxout_type_decl,                     /* type_decl */
   dbxout_function_decl,
   dbxout_global_decl,                   /* global_decl */
   dbxout_type_decl,                     /* type_decl */
-  debug_nothing_tree_tree,               /* imported_module_or_decl */
+  debug_nothing_tree_tree_tree_bool,    /* imported_module_or_decl */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
   debug_nothing_rtx,                    /* label */
   dbxout_handle_pch,                    /* handle_pch */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
   debug_nothing_rtx,                    /* label */
   dbxout_handle_pch,                    /* handle_pch */
-  debug_nothing_rtx                     /* var_location */
+  debug_nothing_rtx,                    /* var_location */
+  debug_nothing_void,                    /* switch_text_section */
+  debug_nothing_tree_tree,              /* set_name */
+  0,                                     /* start_end_main_source_file */
+  TYPE_SYMTAB_IS_ADDRESS                 /* tree_type_symtab_field */
 };
 #endif /* DBX_DEBUGGING_INFO  */
 
 };
 #endif /* DBX_DEBUGGING_INFO  */
 
@@ -387,28 +386,34 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
 {
   dbxout_init,
   dbxout_finish,
 {
   dbxout_init,
   dbxout_finish,
+  debug_nothing_void,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
   dbxout_end_source_file,
   xcoffout_begin_block,
   xcoffout_end_block,
   debug_nothing_int_charstar,
   debug_nothing_int_charstar,
   dbxout_start_source_file,
   dbxout_end_source_file,
   xcoffout_begin_block,
   xcoffout_end_block,
-  debug_true_tree,                      /* ignore_block */
+  debug_true_const_tree,                /* ignore_block */
   xcoffout_source_line,
   xcoffout_begin_prologue,              /* begin_prologue */
   debug_nothing_int_charstar,           /* end_prologue */
   xcoffout_source_line,
   xcoffout_begin_prologue,              /* begin_prologue */
   debug_nothing_int_charstar,           /* end_prologue */
+  debug_nothing_int_charstar,           /* begin_epilogue */
   xcoffout_end_epilogue,
   debug_nothing_tree,                   /* begin_function */
   xcoffout_end_function,
   debug_nothing_tree,                   /* function_decl */
   dbxout_global_decl,                   /* global_decl */
   dbxout_type_decl,                     /* type_decl */
   xcoffout_end_epilogue,
   debug_nothing_tree,                   /* begin_function */
   xcoffout_end_function,
   debug_nothing_tree,                   /* function_decl */
   dbxout_global_decl,                   /* global_decl */
   dbxout_type_decl,                     /* type_decl */
-  debug_nothing_tree_tree,               /* imported_module_or_decl */
+  debug_nothing_tree_tree_tree_bool,    /* imported_module_or_decl */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
   debug_nothing_rtx,                    /* label */
   dbxout_handle_pch,                    /* handle_pch */
   debug_nothing_tree,                   /* deferred_inline_function */
   debug_nothing_tree,                   /* outlining_inline_function */
   debug_nothing_rtx,                    /* label */
   dbxout_handle_pch,                    /* handle_pch */
-  debug_nothing_rtx                     /* var_location */
+  debug_nothing_rtx,                    /* var_location */
+  debug_nothing_void,                    /* switch_text_section */
+  debug_nothing_tree_tree,              /* set_name */
+  0,                                     /* start_end_main_source_file */
+  TYPE_SYMTAB_IS_ADDRESS                 /* tree_type_symtab_field */
 };
 #endif /* XCOFF_DEBUGGING_INFO  */
 \f
 };
 #endif /* XCOFF_DEBUGGING_INFO  */
 \f
@@ -619,6 +624,16 @@ dbxout_begin_complex_stabs (void)
   gcc_assert (stabstr_last_contin_point == 0);
 }
 
   gcc_assert (stabstr_last_contin_point == 0);
 }
 
+/* As above, but do not force text or emit pending bincls.  This is
+   used by dbxout_symbol_location, which needs to do something else.  */
+static void
+dbxout_begin_complex_stabs_noforcetext (void)
+{
+  fputs (ASM_STABS_OP, asm_out_file);
+  putc ('"', asm_out_file);
+  gcc_assert (stabstr_last_contin_point == 0);
+}
+
 /* Add CHR, a single character, to the string being built.  */
 #define stabstr_C(chr) obstack_1grow (&stabstr_ob, chr)
 
 /* Add CHR, a single character, to the string being built.  */
 #define stabstr_C(chr) obstack_1grow (&stabstr_ob, chr)
 
@@ -786,7 +801,7 @@ stabstr_continue (void)
    all of the arguments to the .stabs directive after the string.
    Overridden by xcoffout.h.  CODE is the stabs code for this symbol;
    LINE is the source line to write into the desc field (in extended
    all of the arguments to the .stabs directive after the string.
    Overridden by xcoffout.h.  CODE is the stabs code for this symbol;
    LINE is the source line to write into the desc field (in extended
-   mode).
+   mode); SYM is the symbol itself.
 
    ADDR, LABEL, and NUMBER are three different ways to represent the
    stabs value field.  At most one of these should be nonzero.
 
    ADDR, LABEL, and NUMBER are three different ways to represent the
    stabs value field.  At most one of these should be nonzero.
@@ -802,7 +817,8 @@ stabstr_continue (void)
      register variable).  It represents the value as a decimal integer.  */
 
 #ifndef DBX_FINISH_STABS
      register variable).  It represents the value as a decimal integer.  */
 
 #ifndef DBX_FINISH_STABS
-#define DBX_FINISH_STABS(CODE, LINE, ADDR, LABEL, NUMBER) do { \
+#define DBX_FINISH_STABS(SYM, CODE, LINE, ADDR, LABEL, NUMBER) \
+do {                                                           \
   int line_ = use_gnu_debug_info_extensions ? LINE : 0;                \
                                                                \
   dbxout_int (CODE);                                           \
   int line_ = use_gnu_debug_info_extensions ? LINE : 0;                \
                                                                \
   dbxout_int (CODE);                                           \
@@ -828,9 +844,9 @@ stabstr_continue (void)
    SYM is the DECL of the symbol under consideration; it is used only
    for its DECL_SOURCE_LINE.  The other arguments are all passed directly
    to DBX_FINISH_STABS; see above for details.  */
    SYM is the DECL of the symbol under consideration; it is used only
    for its DECL_SOURCE_LINE.  The other arguments are all passed directly
    to DBX_FINISH_STABS; see above for details.  */
-   
+
 static void
 static void
-dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code,
+dbxout_finish_complex_stabs (tree sym, stab_code_type code,
                             rtx addr, const char *label, int number)
 {
   int line ATTRIBUTE_UNUSED;
                             rtx addr, const char *label, int number)
 {
   int line ATTRIBUTE_UNUSED;
@@ -848,7 +864,7 @@ dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code,
       obstack_1grow (&stabstr_ob, '\0');
 
       len = obstack_object_size (&stabstr_ob);
       obstack_1grow (&stabstr_ob, '\0');
 
       len = obstack_object_size (&stabstr_ob);
-      chunk = str = obstack_finish (&stabstr_ob);
+      chunk = str = XOBFINISH (&stabstr_ob, char *);
 
       /* Within the buffer are a sequence of NUL-separated strings,
         each of which is to be written out as a separate stab
 
       /* Within the buffer are a sequence of NUL-separated strings,
         each of which is to be written out as a separate stab
@@ -864,7 +880,8 @@ dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code,
          len   -= chunklen + 1;
 
          /* Only put a line number on the last stab in the sequence.  */
          len   -= chunklen + 1;
 
          /* Only put a line number on the last stab in the sequence.  */
-         DBX_FINISH_STABS (code, len == 0 ? line : 0, addr, label, number);
+         DBX_FINISH_STABS (sym, code, len == 0 ? line : 0,
+                           addr, label, number);
          if (len == 0)
            break;
 
          if (len == 0)
            break;
 
@@ -880,50 +897,83 @@ dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code,
         comma than to do a two-character fputs.  */
       obstack_grow (&stabstr_ob, "\",", 2);
       len = obstack_object_size (&stabstr_ob);
         comma than to do a two-character fputs.  */
       obstack_grow (&stabstr_ob, "\",", 2);
       len = obstack_object_size (&stabstr_ob);
-      str = obstack_finish (&stabstr_ob);
-      
+      str = XOBFINISH (&stabstr_ob, char *);
+
       fwrite (str, 1, len, asm_out_file);
       fwrite (str, 1, len, asm_out_file);
-      DBX_FINISH_STABS (code, line, addr, label, number);
+      DBX_FINISH_STABS (sym, code, line, addr, label, number);
     }
   obstack_free (&stabstr_ob, str);
 }
 
     }
   obstack_free (&stabstr_ob, str);
 }
 
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
+
+/* When -gused is used, emit debug info for only used symbols. But in
+   addition to the standard intercepted debug_hooks there are some
+   direct calls into this file, i.e., dbxout_symbol, dbxout_parms, and
+   dbxout_reg_params.  Those routines may also be called from a higher
+   level intercepted routine. So to prevent recording data for an inner
+   call to one of these for an intercept, we maintain an intercept
+   nesting counter (debug_nesting). We only save the intercepted
+   arguments if the nesting is 1.  */
+static int debug_nesting = 0;
+
+static tree *symbol_queue;
+static int symbol_queue_index = 0;
+static int symbol_queue_size = 0;
+
+#define DBXOUT_DECR_NESTING \
+  if (--debug_nesting == 0 && symbol_queue_index > 0) \
+    { emit_pending_bincls_if_required (); debug_flush_symbol_queue (); }
+
+#define DBXOUT_DECR_NESTING_AND_RETURN(x) \
+  do {--debug_nesting; return (x);} while (0)
+
+#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
+
 #if defined (DBX_DEBUGGING_INFO)
 
 static void
 #if defined (DBX_DEBUGGING_INFO)
 
 static void
-dbxout_function_end (void)
+dbxout_function_end (tree decl ATTRIBUTE_UNUSED)
 {
   char lscope_label_name[100];
 
   /* The Lscope label must be emitted even if we aren't doing anything
      else; dbxout_block needs it.  */
 {
   char lscope_label_name[100];
 
   /* The Lscope label must be emitted even if we aren't doing anything
      else; dbxout_block needs it.  */
-  function_section (current_function_decl);
-  
+  switch_to_section (function_section (current_function_decl));
+
   /* Convert Lscope into the appropriate format for local labels in case
      the system doesn't insert underscores in front of user generated
      labels.  */
   ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno);
   targetm.asm_out.internal_label (asm_out_file, "Lscope", scope_labelno);
   /* Convert Lscope into the appropriate format for local labels in case
      the system doesn't insert underscores in front of user generated
      labels.  */
   ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno);
   targetm.asm_out.internal_label (asm_out_file, "Lscope", scope_labelno);
-  scope_labelno++;
 
   /* The N_FUN tag at the end of the function is a GNU extension,
      which may be undesirable, and is unnecessary if we do not have
      named sections.  */
   if (!use_gnu_debug_info_extensions
       || NO_DBX_FUNCTION_END
 
   /* The N_FUN tag at the end of the function is a GNU extension,
      which may be undesirable, and is unnecessary if we do not have
      named sections.  */
   if (!use_gnu_debug_info_extensions
       || NO_DBX_FUNCTION_END
-      || !targetm.have_named_sections)
+      || !targetm_common.have_named_sections)
     return;
 
   /* By convention, GCC will mark the end of a function with an N_FUN
      symbol and an empty string.  */
     return;
 
   /* By convention, GCC will mark the end of a function with an N_FUN
      symbol and an empty string.  */
-#ifdef DBX_OUTPUT_NFUN
-  DBX_OUTPUT_NFUN (asm_out_file, lscope_label_name, current_function_decl);
-#else
-  dbxout_begin_empty_stabs (N_FUN);
-  dbxout_stab_value_label_diff (lscope_label_name,
-                               XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
-                               
-#endif
+  if (flag_reorder_blocks_and_partition)
+    {
+      dbxout_begin_empty_stabs (N_FUN);
+      dbxout_stab_value_label_diff (crtl->subsections.hot_section_end_label,
+                                   crtl->subsections.hot_section_label);
+      dbxout_begin_empty_stabs (N_FUN);
+      dbxout_stab_value_label_diff (crtl->subsections.cold_section_end_label,
+                                   crtl->subsections.cold_section_label);
+    }
+  else
+    {
+      char begin_label[20];
+      /* Reference current function start using LFBB.  */
+      ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno);
+      dbxout_begin_empty_stabs (N_FUN);
+      dbxout_stab_value_label_diff (lscope_label_name, begin_label);
+    }
 
   if (!NO_DBX_BNSYM_ENSYM && !flag_debug_only_used_symbols)
     dbxout_stabd (N_ENSYM, 0);
 
   if (!NO_DBX_BNSYM_ENSYM && !flag_debug_only_used_symbols)
     dbxout_stabd (N_ENSYM, 0);
@@ -942,17 +992,27 @@ get_lang_number (void)
     return N_SO_CC;
   else if (strcmp (language_string, "GNU F77") == 0)
     return N_SO_FORTRAN;
     return N_SO_CC;
   else if (strcmp (language_string, "GNU F77") == 0)
     return N_SO_FORTRAN;
-  else if (strcmp (language_string, "GNU F95") == 0)
+  else if (strcmp (language_string, "GNU Fortran") == 0)
     return N_SO_FORTRAN90; /* CHECKME */
   else if (strcmp (language_string, "GNU Pascal") == 0)
     return N_SO_PASCAL;
   else if (strcmp (language_string, "GNU Objective-C") == 0)
     return N_SO_OBJC;
     return N_SO_FORTRAN90; /* CHECKME */
   else if (strcmp (language_string, "GNU Pascal") == 0)
     return N_SO_PASCAL;
   else if (strcmp (language_string, "GNU Objective-C") == 0)
     return N_SO_OBJC;
+  else if (strcmp (language_string, "GNU Objective-C++") == 0)
+    return N_SO_OBJCPLUS;
   else
     return 0;
 
 }
 
   else
     return 0;
 
 }
 
+static bool
+is_fortran (void)
+{
+   unsigned int lang = get_lang_number ();
+
+   return (lang == N_SO_FORTRAN) || (lang == N_SO_FORTRAN90);
+}
+
 /* At the beginning of compilation, start writing the symbol table.
    Initialize `typevec' and output the standard data types of C.  */
 
 /* At the beginning of compilation, start writing the symbol table.
    Initialize `typevec' and output the standard data types of C.  */
 
@@ -962,9 +1022,10 @@ dbxout_init (const char *input_file_name)
   char ltext_label_name[100];
   bool used_ltext_label_name = false;
   tree syms = lang_hooks.decls.getdecls ();
   char ltext_label_name[100];
   bool used_ltext_label_name = false;
   tree syms = lang_hooks.decls.getdecls ();
+  const char *mapped_name;
 
   typevec_len = 100;
 
   typevec_len = 100;
-  typevec = ggc_calloc (typevec_len, sizeof typevec[0]);
+  typevec = ggc_alloc_cleared_vec_typeinfo (typevec_len);
 
   /* stabstr_ob contains one string, which will be just fine with
      1-byte alignment.  */
 
   /* stabstr_ob contains one string, which will be just fine with
      1-byte alignment.  */
@@ -987,6 +1048,7 @@ dbxout_init (const char *input_file_name)
            cwd = "/";
          else if (!IS_DIR_SEPARATOR (cwd[strlen (cwd) - 1]))
            cwd = concat (cwd, "/", NULL);
            cwd = "/";
          else if (!IS_DIR_SEPARATOR (cwd[strlen (cwd) - 1]))
            cwd = concat (cwd, "/", NULL);
+         cwd = remap_debug_filename (cwd);
        }
 #ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY
       DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asm_out_file, cwd);
        }
 #ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY
       DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asm_out_file, cwd);
@@ -997,17 +1059,18 @@ dbxout_init (const char *input_file_name)
 #endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */
     }
 
 #endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */
     }
 
+  mapped_name = remap_debug_filename (input_file_name);
 #ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME
 #ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME
-  DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, input_file_name);
+  DBX_OUTPUT_MAIN_SOURCE_FILENAME (asm_out_file, mapped_name);
 #else
 #else
-  dbxout_begin_simple_stabs_desc (input_file_name, N_SO, get_lang_number ());
+  dbxout_begin_simple_stabs_desc (mapped_name, N_SO, get_lang_number ());
   dbxout_stab_value_label (ltext_label_name);
   used_ltext_label_name = true;
 #endif
 
   if (used_ltext_label_name)
     {
   dbxout_stab_value_label (ltext_label_name);
   used_ltext_label_name = true;
 #endif
 
   if (used_ltext_label_name)
     {
-      text_section ();
+      switch_to_section (text_section);
       targetm.asm_out.internal_label (asm_out_file, "Ltext", 0);
     }
 
       targetm.asm_out.internal_label (asm_out_file, "Ltext", 0);
     }
 
@@ -1023,7 +1086,7 @@ dbxout_init (const char *input_file_name)
   next_type_number = 1;
 
 #ifdef DBX_USE_BINCL
   next_type_number = 1;
 
 #ifdef DBX_USE_BINCL
-  current_file = xmalloc (sizeof *current_file);
+  current_file = XNEW (struct dbx_file);
   current_file->next = NULL;
   current_file->file_number = 0;
   current_file->next_type_number = 1;
   current_file->next = NULL;
   current_file->file_number = 0;
   current_file->next_type_number = 1;
@@ -1054,7 +1117,7 @@ dbxout_init (const char *input_file_name)
 static void
 dbxout_typedefs (tree syms)
 {
 static void
 dbxout_typedefs (tree syms)
 {
-  for (; syms != NULL_TREE; syms = TREE_CHAIN (syms))
+  for (; syms != NULL_TREE; syms = DECL_CHAIN (syms))
     {
       if (TREE_CODE (syms) == TYPE_DECL)
        {
     {
       if (TREE_CODE (syms) == TYPE_DECL)
        {
@@ -1132,17 +1195,17 @@ dbxout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
                          const char *filename ATTRIBUTE_UNUSED)
 {
 #ifdef DBX_USE_BINCL
                          const char *filename ATTRIBUTE_UNUSED)
 {
 #ifdef DBX_USE_BINCL
-  struct dbx_file *n = xmalloc (sizeof *n);
+  struct dbx_file *n = XNEW (struct dbx_file);
 
   n->next = current_file;
   n->next_type_number = 1;
 
   n->next = current_file;
   n->next_type_number = 1;
-  /* Do not assign file number now. 
+  /* Do not assign file number now.
      Delay it until we actually emit BINCL.  */
   n->file_number = 0;
   n->prev = NULL;
   current_file->prev = n;
   n->bincl_status = BINCL_PENDING;
      Delay it until we actually emit BINCL.  */
   n->file_number = 0;
   n->prev = NULL;
   current_file->prev = n;
   n->bincl_status = BINCL_PENDING;
-  n->pending_bincl_name = filename;
+  n->pending_bincl_name = remap_debug_filename (filename);
   pending_bincls = 1;
   current_file = n;
 #endif
   pending_bincls = 1;
   current_file = n;
 #endif
@@ -1191,6 +1254,9 @@ dbxout_handle_pch (unsigned at_end)
 }
 
 #if defined (DBX_DEBUGGING_INFO)
 }
 
 #if defined (DBX_DEBUGGING_INFO)
+
+static void dbxout_block (tree, int, tree);
+
 /* Output debugging info to FILE to switch to sourcefile FILENAME.  */
 
 static void
 /* Output debugging info to FILE to switch to sourcefile FILENAME.  */
 
 static void
@@ -1206,15 +1272,16 @@ dbxout_source_file (const char *filename)
     {
       /* Don't change section amid function.  */
       if (current_function_decl == NULL_TREE)
     {
       /* Don't change section amid function.  */
       if (current_function_decl == NULL_TREE)
-       text_section ();
+       switch_to_section (text_section);
 
 
-      dbxout_begin_simple_stabs (filename, N_SOL);
+      dbxout_begin_simple_stabs (remap_debug_filename (filename), N_SOL);
       dbxout_stab_value_internal_label ("Ltext", &source_label_number);
       lastfile = filename;
     }
 }
 
       dbxout_stab_value_internal_label ("Ltext", &source_label_number);
       lastfile = filename;
     }
 }
 
-/* Output N_BNSYM and line number symbol entry.  */
+/* Output N_BNSYM, line number symbol entry, and local symbol at
+   function scope  */
 
 static void
 dbxout_begin_prologue (unsigned int lineno, const char *filename)
 
 static void
 dbxout_begin_prologue (unsigned int lineno, const char *filename)
@@ -1225,14 +1292,23 @@ dbxout_begin_prologue (unsigned int lineno, const char *filename)
       && !flag_debug_only_used_symbols)
     dbxout_stabd (N_BNSYM, 0);
 
       && !flag_debug_only_used_symbols)
     dbxout_stabd (N_BNSYM, 0);
 
-  dbxout_source_line (lineno, filename);
+  /* pre-increment the scope counter */
+  scope_labelno++;
+
+  dbxout_source_line (lineno, filename, 0, true);
+  /* Output function begin block at function scope, referenced
+     by dbxout_block, dbxout_source_line and dbxout_function_end.  */
+  emit_pending_bincls_if_required ();
+  targetm.asm_out.internal_label (asm_out_file, "LFBB", scope_labelno);
 }
 
 /* Output a line number symbol entry for source file FILENAME and line
    number LINENO.  */
 
 static void
 }
 
 /* Output a line number symbol entry for source file FILENAME and line
    number LINENO.  */
 
 static void
-dbxout_source_line (unsigned int lineno, const char *filename)
+dbxout_source_line (unsigned int lineno, const char *filename,
+                    int discriminator ATTRIBUTE_UNUSED,
+                    bool is_stmt ATTRIBUTE_UNUSED)
 {
   dbxout_source_file (filename);
 
 {
   dbxout_source_file (filename);
 
@@ -1241,11 +1317,12 @@ dbxout_source_line (unsigned int lineno, const char *filename)
 #else
   if (DBX_LINES_FUNCTION_RELATIVE)
     {
 #else
   if (DBX_LINES_FUNCTION_RELATIVE)
     {
-      rtx begin_label = XEXP (DECL_RTL (current_function_decl), 0);
+      char begin_label[20];
       dbxout_begin_stabn_sline (lineno);
       dbxout_begin_stabn_sline (lineno);
+      /* Reference current function start using LFBB.  */
+      ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno);
       dbxout_stab_value_internal_label_diff ("LM", &dbxout_source_line_counter,
       dbxout_stab_value_internal_label_diff ("LM", &dbxout_source_line_counter,
-                                            XSTR (begin_label, 0));
-
+                                            begin_label);
     }
   else
     dbxout_stabd (N_SLINE, lineno);
     }
   else
     dbxout_stabd (N_SLINE, lineno);
@@ -1284,7 +1361,7 @@ dbxout_function_decl (tree decl)
   dbxout_begin_function (decl);
 #endif
   dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
   dbxout_begin_function (decl);
 #endif
   dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
-  dbxout_function_end ();
+  dbxout_function_end (decl);
 }
 
 #endif /* DBX_DEBUGGING_INFO  */
 }
 
 #endif /* DBX_DEBUGGING_INFO  */
@@ -1294,9 +1371,7 @@ dbxout_function_decl (tree decl)
 static void
 dbxout_global_decl (tree decl)
 {
 static void
 dbxout_global_decl (tree decl)
 {
-  if (TREE_CODE (decl) == VAR_DECL
-      && ! DECL_EXTERNAL (decl)
-      && DECL_RTL_SET_P (decl))        /* Not necessary?  */
+  if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
       int saved_tree_used = TREE_USED (decl);
       TREE_USED (decl) = 1;
     {
       int saved_tree_used = TREE_USED (decl);
       TREE_USED (decl) = 1;
@@ -1323,7 +1398,7 @@ dbxout_finish (const char *filename ATTRIBUTE_UNUSED)
   DBX_OUTPUT_MAIN_SOURCE_FILE_END (asm_out_file, filename);
 #elif defined DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
  {
   DBX_OUTPUT_MAIN_SOURCE_FILE_END (asm_out_file, filename);
 #elif defined DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END
  {
-   text_section ();
+   switch_to_section (text_section);
    dbxout_begin_empty_stabs (N_SO);
    dbxout_stab_value_internal_label ("Letext", 0);
  }
    dbxout_begin_empty_stabs (N_SO);
    dbxout_stab_value_internal_label ("Letext", 0);
  }
@@ -1349,7 +1424,73 @@ dbxout_type_index (tree type)
 }
 
 \f
 }
 
 \f
+/* Generate the symbols for any queued up type symbols we encountered
+   while generating the type info for some originally used symbol.
+   This might generate additional entries in the queue.  Only when
+   the nesting depth goes to 0 is this routine called.  */
+
+static void
+debug_flush_symbol_queue (void)
+{
+  int i;
+
+  /* Make sure that additionally queued items are not flushed
+     prematurely.  */
+
+  ++debug_nesting;
 
 
+  for (i = 0; i < symbol_queue_index; ++i)
+    {
+      /* If we pushed queued symbols then such symbols must be
+         output no matter what anyone else says.  Specifically,
+         we need to make sure dbxout_symbol() thinks the symbol was
+         used and also we need to override TYPE_DECL_SUPPRESS_DEBUG
+         which may be set for outside reasons.  */
+      int saved_tree_used = TREE_USED (symbol_queue[i]);
+      int saved_suppress_debug = TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]);
+      TREE_USED (symbol_queue[i]) = 1;
+      TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = 0;
+
+#ifdef DBX_DEBUGGING_INFO
+      dbxout_symbol (symbol_queue[i], 0);
+#endif
+
+      TREE_USED (symbol_queue[i]) = saved_tree_used;
+      TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = saved_suppress_debug;
+    }
+
+  symbol_queue_index = 0;
+  --debug_nesting;
+}
+
+/* Queue a type symbol needed as part of the definition of a decl
+   symbol.  These symbols are generated when debug_flush_symbol_queue()
+   is called.  */
+
+static void
+debug_queue_symbol (tree decl)
+{
+  if (symbol_queue_index >= symbol_queue_size)
+    {
+      symbol_queue_size += 10;
+      symbol_queue = XRESIZEVEC (tree, symbol_queue, symbol_queue_size);
+    }
+
+  symbol_queue[symbol_queue_index++] = decl;
+}
+
+/* Free symbol queue.  */
+static void
+debug_free_queue (void)
+{
+  if (symbol_queue)
+    {
+      free (symbol_queue);
+      symbol_queue = NULL;
+      symbol_queue_size = 0;
+    }
+}
+\f
 /* Used in several places: evaluates to '0' for a private decl,
    '1' for a protected decl, '2' for a public decl.  */
 #define DECL_ACCESSIBILITY_CHAR(DECL) \
 /* Used in several places: evaluates to '0' for a private decl,
    '1' for a protected decl, '2' for a public decl.  */
 #define DECL_ACCESSIBILITY_CHAR(DECL) \
@@ -1366,23 +1507,23 @@ dbxout_type_fields (tree type)
 
   /* Output the name, type, position (in bits), size (in bits) of each
      field that we can support.  */
 
   /* Output the name, type, position (in bits), size (in bits) of each
      field that we can support.  */
-  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
+  for (tem = TYPE_FIELDS (type); tem; tem = DECL_CHAIN (tem))
     {
       /* If one of the nodes is an error_mark or its type is then
         return early.  */
     {
       /* If one of the nodes is an error_mark or its type is then
         return early.  */
-      if (tem == error_mark_node || TREE_TYPE (tem) == error_mark_node)
+      if (error_operand_p (tem))
        return;
 
       /* Omit here local type decls until we know how to support them.  */
       if (TREE_CODE (tem) == TYPE_DECL
        return;
 
       /* Omit here local type decls until we know how to support them.  */
       if (TREE_CODE (tem) == TYPE_DECL
+         /* Omit here the nameless fields that are used to skip bits.  */
+         || DECL_IGNORED_P (tem)
          /* Omit fields whose position or size are variable or too large to
             represent.  */
          || (TREE_CODE (tem) == FIELD_DECL
              && (! host_integerp (bit_position (tem), 0)
                  || ! DECL_SIZE (tem)
          /* Omit fields whose position or size are variable or too large to
             represent.  */
          || (TREE_CODE (tem) == FIELD_DECL
              && (! host_integerp (bit_position (tem), 0)
                  || ! DECL_SIZE (tem)
-                 || ! host_integerp (DECL_SIZE (tem), 1)))
-         /* Omit here the nameless fields that are used to skip bits.  */
-          || DECL_IGNORED_P (tem))
+                 || ! host_integerp (DECL_SIZE (tem), 1))))
        continue;
 
       else if (TREE_CODE (tem) != CONST_DECL)
        continue;
 
       else if (TREE_CODE (tem) != CONST_DECL)
@@ -1400,7 +1541,6 @@ dbxout_type_fields (tree type)
              && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)
                  || TREE_CODE (tem) != FIELD_DECL))
            {
              && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)
                  || TREE_CODE (tem) != FIELD_DECL))
            {
-             have_used_extensions = 1;
              stabstr_C ('/');
              stabstr_C (DECL_ACCESSIBILITY_CHAR (tem));
            }
              stabstr_C ('/');
              stabstr_C (DECL_ACCESSIBILITY_CHAR (tem));
            }
@@ -1415,7 +1555,6 @@ dbxout_type_fields (tree type)
                {
                  tree name = DECL_ASSEMBLER_NAME (tem);
 
                {
                  tree name = DECL_ASSEMBLER_NAME (tem);
 
-                 have_used_extensions = 1;
                  stabstr_C (':');
                  stabstr_I (name);
                  stabstr_C (';');
                  stabstr_C (':');
                  stabstr_I (name);
                  stabstr_C (';');
@@ -1511,7 +1650,7 @@ dbxout_type_methods (tree type)
         These differ in the types of the arguments.  */
       for (last = NULL_TREE;
           fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last));
         These differ in the types of the arguments.  */
       for (last = NULL_TREE;
           fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last));
-          fndecl = TREE_CHAIN (fndecl))
+          fndecl = DECL_CHAIN (fndecl))
        /* Output the name of the field (after overloading), as
           well as the name of the field before overloading, along
           with its parameter list */
        /* Output the name of the field (after overloading), as
           well as the name of the field before overloading, along
           with its parameter list */
@@ -1550,10 +1689,10 @@ dbxout_type_methods (tree type)
 
 /* Emit a "range" type specification, which has the form:
    "r<index type>;<lower bound>;<upper bound>;".
 
 /* Emit a "range" type specification, which has the form:
    "r<index type>;<lower bound>;<upper bound>;".
-   TYPE is an INTEGER_TYPE.  */
+   TYPE is an INTEGER_TYPE, LOW and HIGH are the bounds.  */
 
 static void
 
 static void
-dbxout_range_type (tree type)
+dbxout_range_type (tree type, tree low, tree high)
 {
   stabstr_C ('r');
   if (TREE_TYPE (type))
 {
   stabstr_C ('r');
   if (TREE_TYPE (type))
@@ -1581,25 +1720,23 @@ dbxout_range_type (tree type)
     }
 
   stabstr_C (';');
     }
 
   stabstr_C (';');
-  if (TYPE_MIN_VALUE (type) != 0
-      && host_integerp (TYPE_MIN_VALUE (type), 0))
+  if (low && host_integerp (low, 0))
     {
     {
-      if (print_int_cst_bounds_in_octal_p (type))
-        stabstr_O (TYPE_MIN_VALUE (type));
+      if (print_int_cst_bounds_in_octal_p (type, low, high))
+        stabstr_O (low);
       else
       else
-        stabstr_D (tree_low_cst (TYPE_MIN_VALUE (type), 0));
+        stabstr_D (tree_low_cst (low, 0));
     }
   else
     stabstr_C ('0');
 
   stabstr_C (';');
     }
   else
     stabstr_C ('0');
 
   stabstr_C (';');
-  if (TYPE_MAX_VALUE (type) != 0
-      && host_integerp (TYPE_MAX_VALUE (type), 0))
+  if (high && host_integerp (high, 0))
     {
     {
-      if (print_int_cst_bounds_in_octal_p (type))
-        stabstr_O (TYPE_MAX_VALUE (type));
+      if (print_int_cst_bounds_in_octal_p (type, low, high))
+        stabstr_O (high);
       else
       else
-        stabstr_D (tree_low_cst (TYPE_MAX_VALUE (type), 0));
+        stabstr_D (tree_low_cst (high, 0));
       stabstr_C (';');
     }
   else
       stabstr_C (';');
     }
   else
@@ -1620,14 +1757,29 @@ dbxout_range_type (tree type)
 static void
 dbxout_type (tree type, int full)
 {
 static void
 dbxout_type (tree type, int full)
 {
-  tree tem;
-  tree main_variant;
   static int anonymous_type_number = 0;
   static int anonymous_type_number = 0;
+  tree tem, main_variant, low, high;
+
+  if (TREE_CODE (type) == INTEGER_TYPE)
+    {
+      if (TREE_TYPE (type) == 0)
+       {
+         low = TYPE_MIN_VALUE (type);
+         high = TYPE_MAX_VALUE (type);
+       }
+
+      else if (subrange_type_for_debug_p (type, &low, &high))
+       ;
 
 
-  if (TREE_CODE (type) == VECTOR_TYPE)
-    /* The frontend feeds us a representation for the vector as a struct
-       containing an array.  Pull out the array type.  */
-    type = TREE_TYPE (TYPE_FIELDS (TYPE_DEBUG_REPRESENTATION_TYPE (type)));
+      /* If this is a subtype that should not be emitted as a subrange type,
+        use the base type.  */
+      else
+       {
+         type = TREE_TYPE (type);
+         low = TYPE_MIN_VALUE (type);
+         high = TYPE_MAX_VALUE (type);
+       }
+    }
 
   /* If there was an input error and we don't really have a type,
      avoid crashing and write something that is at least valid
 
   /* If there was an input error and we don't really have a type,
      avoid crashing and write something that is at least valid
@@ -1663,8 +1815,7 @@ dbxout_type (tree type, int full)
 
       if (next_type_number == typevec_len)
        {
 
       if (next_type_number == typevec_len)
        {
-         typevec
-           = ggc_realloc (typevec, (typevec_len * 2 * sizeof typevec[0]));
+         typevec = GGC_RESIZEVEC (struct typeinfo, typevec, typevec_len * 2);
          memset (typevec + typevec_len, 0, typevec_len * sizeof typevec[0]);
          typevec_len *= 2;
        }
          memset (typevec + typevec_len, 0, typevec_len * sizeof typevec[0]);
          typevec_len *= 2;
        }
@@ -1793,6 +1944,7 @@ dbxout_type (tree type, int full)
   switch (TREE_CODE (type))
     {
     case VOID_TYPE:
   switch (TREE_CODE (type))
     {
     case VOID_TYPE:
+    case NULLPTR_TYPE:
     case LANG_TYPE:
       /* For a void type, just define it as itself; i.e., "5=5".
         This makes us consider it defined
     case LANG_TYPE:
       /* For a void type, just define it as itself; i.e., "5=5".
         This makes us consider it defined
@@ -1826,13 +1978,12 @@ dbxout_type (tree type, int full)
          if (use_gnu_debug_info_extensions
              && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
            {
          if (use_gnu_debug_info_extensions
              && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
            {
-             have_used_extensions = 1;
              stabstr_S ("@s");
              stabstr_D (TYPE_PRECISION (type));
              stabstr_C (';');
            }
 
              stabstr_S ("@s");
              stabstr_D (TYPE_PRECISION (type));
              stabstr_C (';');
            }
 
-         dbxout_range_type (type);
+         dbxout_range_type (type, low, high);
        }
 
       else
        }
 
       else
@@ -1843,13 +1994,12 @@ dbxout_type (tree type, int full)
          if (use_gnu_debug_info_extensions
              && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
            {
          if (use_gnu_debug_info_extensions
              && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
            {
-             have_used_extensions = 1;
              stabstr_S ("@s");
              stabstr_D (TYPE_PRECISION (type));
              stabstr_C (';');
            }
 
              stabstr_S ("@s");
              stabstr_D (TYPE_PRECISION (type));
              stabstr_C (';');
            }
 
-         if (print_int_cst_bounds_in_octal_p (type))
+         if (print_int_cst_bounds_in_octal_p (type, low, high))
            {
              stabstr_C ('r');
 
            {
              stabstr_C ('r');
 
@@ -1864,20 +2014,21 @@ dbxout_type (tree type, int full)
                 dbxout_type_index (type);
 
              stabstr_C (';');
                 dbxout_type_index (type);
 
              stabstr_C (';');
-             stabstr_O (TYPE_MIN_VALUE (type));
+             stabstr_O (low);
              stabstr_C (';');
              stabstr_C (';');
-             stabstr_O (TYPE_MAX_VALUE (type));
+             stabstr_O (high);
              stabstr_C (';');
            }
 
          else
            /* Output other integer types as subranges of `int'.  */
              stabstr_C (';');
            }
 
          else
            /* Output other integer types as subranges of `int'.  */
-           dbxout_range_type (type);
+           dbxout_range_type (type, low, high);
        }
 
       break;
 
     case REAL_TYPE:
        }
 
       break;
 
     case REAL_TYPE:
+    case FIXED_POINT_TYPE:
       /* This used to say `r1' and we used to take care
         to make sure that `int' was type number 1.  */
       stabstr_C ('r');
       /* This used to say `r1' and we used to take care
         to make sure that `int' was type number 1.  */
       stabstr_C ('r');
@@ -1887,28 +2038,9 @@ dbxout_type (tree type, int full)
       stabstr_S (";0;");
       break;
 
       stabstr_S (";0;");
       break;
 
-    case CHAR_TYPE:
-      if (use_gnu_debug_info_extensions)
-       {
-         have_used_extensions = 1;
-         stabstr_S ("@s");
-         stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type));
-         stabstr_S (";-20;");
-       }
-      else
-       {
-         /* Output the type `char' as a subrange of itself.
-            That is what pcc seems to do.  */
-         stabstr_C ('r');
-         dbxout_type_index (char_type_node);
-         stabstr_S (TYPE_UNSIGNED (type) ? ";0;255;" : ";0;127;");
-       }
-      break;
-
     case BOOLEAN_TYPE:
       if (use_gnu_debug_info_extensions)
        {
     case BOOLEAN_TYPE:
       if (use_gnu_debug_info_extensions)
        {
-         have_used_extensions = 1;
          stabstr_S ("@s");
          stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type));
          stabstr_S (";-16;");
          stabstr_S ("@s");
          stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type));
          stabstr_S (";-16;");
@@ -1917,11 +2049,6 @@ dbxout_type (tree type, int full)
        stabstr_S ("eFalse:0,True:1,;");
       break;
 
        stabstr_S ("eFalse:0,True:1,;");
       break;
 
-    case FILE_TYPE:
-      stabstr_C ('d');
-      dbxout_type (TREE_TYPE (type), 0);
-      break;
-
     case COMPLEX_TYPE:
       /* Differs from the REAL_TYPE by its new data type number.
         R3 is NF_COMPLEX.  We don't try to use any of the other NF_*
     case COMPLEX_TYPE:
       /* Differs from the REAL_TYPE by its new data type number.
         R3 is NF_COMPLEX.  We don't try to use any of the other NF_*
@@ -1955,28 +2082,10 @@ dbxout_type (tree type, int full)
        }
       break;
 
        }
       break;
 
-    case SET_TYPE:
-      if (use_gnu_debug_info_extensions)
-       {
-         have_used_extensions = 1;
-         stabstr_S ("@s");
-         stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type));
-         stabstr_C (';');
-
-         /* Check if a bitstring type, which in Chill is
-            different from a [power]set.  */
-         if (TYPE_STRING_FLAG (type))
-           stabstr_S ("@S;");
-       }
-      stabstr_C ('S');
-      dbxout_type (TYPE_DOMAIN (type), 0);
-      break;
-
     case ARRAY_TYPE:
       /* Make arrays of packed bits look like bitstrings for chill.  */
       if (TYPE_PACKED (type) && use_gnu_debug_info_extensions)
        {
     case ARRAY_TYPE:
       /* Make arrays of packed bits look like bitstrings for chill.  */
       if (TYPE_PACKED (type) && use_gnu_debug_info_extensions)
        {
-         have_used_extensions = 1;
          stabstr_S ("@s");
          stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type));
          stabstr_S (";@S;S");
          stabstr_S ("@s");
          stabstr_D (BITS_PER_UNIT * int_size_in_bytes (type));
          stabstr_S (";@S;S");
@@ -1992,7 +2101,6 @@ dbxout_type (tree type, int full)
         different from an array of characters.  */
       if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions)
        {
         different from an array of characters.  */
       if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions)
        {
-         have_used_extensions = 1;
          stabstr_S ("@S;");
        }
       tem = TYPE_DOMAIN (type);
          stabstr_S ("@S;");
        }
       tem = TYPE_DOMAIN (type);
@@ -2005,12 +2113,28 @@ dbxout_type (tree type, int full)
       else
        {
          stabstr_C ('a');
       else
        {
          stabstr_C ('a');
-         dbxout_range_type (tem);
+         dbxout_range_type (tem, TYPE_MIN_VALUE (tem), TYPE_MAX_VALUE (tem));
        }
 
       dbxout_type (TREE_TYPE (type), 0);
       break;
 
        }
 
       dbxout_type (TREE_TYPE (type), 0);
       break;
 
+    case VECTOR_TYPE:
+      /* Make vectors look like an array.  */
+      if (use_gnu_debug_info_extensions)
+       stabstr_S ("@V;");
+
+      /* Output "a" followed by a range type definition
+        for the index type of the array
+        followed by a reference to the target-type.
+        ar1;0;N;M for a C array of type M and size N+1.  */
+      stabstr_C ('a');
+      dbxout_range_type (integer_type_node, size_zero_node,
+                        size_int (TYPE_VECTOR_SUBPARTS (type) - 1));
+
+      dbxout_type (TREE_TYPE (type), 0);
+      break;
+
     case RECORD_TYPE:
     case UNION_TYPE:
     case QUAL_UNION_TYPE:
     case RECORD_TYPE:
     case UNION_TYPE:
     case QUAL_UNION_TYPE:
@@ -2035,7 +2159,11 @@ dbxout_type (tree type, int full)
               another type's definition; instead, output an xref
               and let the definition come when the name is defined.  */
            stabstr_S ((TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
               another type's definition; instead, output an xref
               and let the definition come when the name is defined.  */
            stabstr_S ((TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
-           if (TYPE_NAME (type) != 0)
+           if (TYPE_NAME (type) != 0
+               /* The C frontend creates for anonymous variable length
+                  records/unions TYPE_NAME with DECL_NAME NULL.  */
+               && (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL
+                   || DECL_NAME (TYPE_NAME (type))))
              dbxout_type_name (type);
            else
              {
              dbxout_type_name (type);
            else
              {
@@ -2056,13 +2184,12 @@ dbxout_type (tree type, int full)
          {
            int i;
            tree child;
          {
            int i;
            tree child;
-           VEC (tree) *accesses = BINFO_BASE_ACCESSES (binfo);
-           
+           VEC(tree,gc) *accesses = BINFO_BASE_ACCESSES (binfo);
+
            if (use_gnu_debug_info_extensions)
              {
                if (BINFO_N_BASE_BINFOS (binfo))
                  {
            if (use_gnu_debug_info_extensions)
              {
                if (BINFO_N_BASE_BINFOS (binfo))
                  {
-                   have_used_extensions = 1;
                    stabstr_C ('!');
                    stabstr_U (BINFO_N_BASE_BINFOS (binfo));
                    stabstr_C (',');
                    stabstr_C ('!');
                    stabstr_U (BINFO_N_BASE_BINFOS (binfo));
                    stabstr_C (',');
@@ -2075,13 +2202,13 @@ dbxout_type (tree type, int full)
 
                if (use_gnu_debug_info_extensions)
                  {
 
                if (use_gnu_debug_info_extensions)
                  {
-                   have_used_extensions = 1;
                    stabstr_C (BINFO_VIRTUAL_P (child) ? '1' : '0');
                    stabstr_C (access == access_public_node ? '2' :
                                   access == access_protected_node
                                   ? '1' :'0');
                    if (BINFO_VIRTUAL_P (child)
                    stabstr_C (BINFO_VIRTUAL_P (child) ? '1' : '0');
                    stabstr_C (access == access_public_node ? '2' :
                                   access == access_protected_node
                                   ? '1' :'0');
                    if (BINFO_VIRTUAL_P (child)
-                       && strcmp (lang_hooks.name, "GNU C++") == 0)
+                       && (strcmp (lang_hooks.name, "GNU C++") == 0
+                           || strcmp (lang_hooks.name, "GNU Objective-C++") == 0))
                      /* For a virtual base, print the (negative)
                         offset within the vtable where we must look
                         to find the necessary adjustment.  */
                      /* For a virtual base, print the (negative)
                         offset within the vtable where we must look
                         to find the necessary adjustment.  */
@@ -2120,7 +2247,6 @@ dbxout_type (tree type, int full)
       dbxout_type_fields (type);
       if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE)
        {
       dbxout_type_fields (type);
       if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE)
        {
-         have_used_extensions = 1;
          dbxout_type_methods (type);
        }
 
          dbxout_type_methods (type);
        }
 
@@ -2130,7 +2256,6 @@ dbxout_type (tree type, int full)
          /* Avoid the ~ if we don't really need it--it confuses dbx.  */
          && TYPE_VFIELD (type))
        {
          /* Avoid the ~ if we don't really need it--it confuses dbx.  */
          && TYPE_VFIELD (type))
        {
-         have_used_extensions = 1;
 
          /* We need to write out info about what field this class
             uses as its "main" vtable pointer field, because if this
 
          /* We need to write out info about what field this class
             uses as its "main" vtable pointer field, because if this
@@ -2161,7 +2286,6 @@ dbxout_type (tree type, int full)
       if (use_gnu_debug_info_extensions
          && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
        {
       if (use_gnu_debug_info_extensions
          && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
        {
-         have_used_extensions = 1;
          stabstr_S ("@s");
          stabstr_D (TYPE_PRECISION (type));
          stabstr_C (';');
          stabstr_S ("@s");
          stabstr_D (TYPE_PRECISION (type));
          stabstr_C (';');
@@ -2170,16 +2294,21 @@ dbxout_type (tree type, int full)
       stabstr_C ('e');
       for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
        {
       stabstr_C ('e');
       for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
        {
+          tree value = TREE_VALUE (tem);
+
          stabstr_I (TREE_PURPOSE (tem));
          stabstr_C (':');
 
          stabstr_I (TREE_PURPOSE (tem));
          stabstr_C (':');
 
-         if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0)
-           stabstr_D (TREE_INT_CST_LOW (TREE_VALUE (tem)));
-         else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1
-                  && (HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0)
-           stabstr_D (TREE_INT_CST_LOW (TREE_VALUE (tem)));
+          if (TREE_CODE (value) == CONST_DECL)
+            value = DECL_INITIAL (value);
+
+         if (TREE_INT_CST_HIGH (value) == 0)
+           stabstr_D (TREE_INT_CST_LOW (value));
+         else if (TREE_INT_CST_HIGH (value) == -1
+                  && (HOST_WIDE_INT) TREE_INT_CST_LOW (value) < 0)
+           stabstr_D (TREE_INT_CST_LOW (value));
          else
          else
-           stabstr_O (TREE_VALUE (tem));
+           stabstr_O (value);
 
          stabstr_C (',');
          if (TREE_CHAIN (tem) != 0)
 
          stabstr_C (',');
          if (TREE_CHAIN (tem) != 0)
@@ -2197,7 +2326,6 @@ dbxout_type (tree type, int full)
     case METHOD_TYPE:
       if (use_gnu_debug_info_extensions)
        {
     case METHOD_TYPE:
       if (use_gnu_debug_info_extensions)
        {
-         have_used_extensions = 1;
          stabstr_C ('#');
 
          /* Write the argument types out longhand.  */
          stabstr_C ('#');
 
          /* Write the argument types out longhand.  */
@@ -2215,7 +2343,6 @@ dbxout_type (tree type, int full)
     case OFFSET_TYPE:
       if (use_gnu_debug_info_extensions)
        {
     case OFFSET_TYPE:
       if (use_gnu_debug_info_extensions)
        {
-         have_used_extensions = 1;
          stabstr_C ('@');
          dbxout_type (TYPE_OFFSET_BASETYPE (type), 0);
          stabstr_C (',');
          stabstr_C ('@');
          dbxout_type (TYPE_OFFSET_BASETYPE (type), 0);
          stabstr_C (',');
@@ -2229,7 +2356,6 @@ dbxout_type (tree type, int full)
     case REFERENCE_TYPE:
       if (use_gnu_debug_info_extensions)
        {
     case REFERENCE_TYPE:
       if (use_gnu_debug_info_extensions)
        {
-         have_used_extensions = 1;
          stabstr_C ('&');
        }
       else
          stabstr_C ('&');
        }
       else
@@ -2251,7 +2377,7 @@ dbxout_type (tree type, int full)
    should be printed in octal format.  */
 
 static bool
    should be printed in octal format.  */
 
 static bool
-print_int_cst_bounds_in_octal_p (tree type)
+print_int_cst_bounds_in_octal_p (tree type, tree low, tree high)
 {
   /* If we can use GDB extensions and the size is wider than a long
      (the size used by GDB to read them) or we may have trouble writing
 {
   /* If we can use GDB extensions and the size is wider than a long
      (the size used by GDB to read them) or we may have trouble writing
@@ -2265,10 +2391,8 @@ print_int_cst_bounds_in_octal_p (tree type)
      can't span same size unsigned types.  */
 
   if (use_gnu_debug_info_extensions
      can't span same size unsigned types.  */
 
   if (use_gnu_debug_info_extensions
-      && TYPE_MIN_VALUE (type) != 0
-      && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
-      && TYPE_MAX_VALUE (type) != 0
-      && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
+      && low && TREE_CODE (low) == INTEGER_CST
+      && high && TREE_CODE (high) == INTEGER_CST
       && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
          || ((TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
              && TYPE_UNSIGNED (type))
       && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
          || ((TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
              && TYPE_UNSIGNED (type))
@@ -2288,7 +2412,7 @@ static void
 dbxout_type_name (tree type)
 {
   tree t = TYPE_NAME (type);
 dbxout_type_name (tree type)
 {
   tree t = TYPE_NAME (type);
-  
+
   gcc_assert (t);
   switch (TREE_CODE (t))
     {
   gcc_assert (t);
   switch (TREE_CODE (t))
     {
@@ -2330,6 +2454,162 @@ dbxout_class_name_qualifiers (tree decl)
     }
 }
 \f
     }
 }
 \f
+/* This is a specialized subset of expand_expr for use by dbxout_symbol in
+   evaluating DECL_VALUE_EXPR.  In particular, we stop if we find decls that
+   haven't been expanded, or if the expression is getting so complex we won't
+   be able to represent it in stabs anyway.  Returns NULL on failure.  */
+
+static rtx
+dbxout_expand_expr (tree expr)
+{
+  switch (TREE_CODE (expr))
+    {
+    case VAR_DECL:
+      /* We can't handle emulated tls variables, because the address is an
+        offset to the return value of __emutls_get_address, and there is no
+        way to express that in stabs.  Also, there are name mangling issues
+        here.  We end up with references to undefined symbols if we don't
+        disable debug info for these variables.  */
+      if (!targetm.have_tls && DECL_THREAD_LOCAL_P (expr))
+       return NULL;
+      if (TREE_STATIC (expr)
+         && !TREE_ASM_WRITTEN (expr)
+         && !DECL_HAS_VALUE_EXPR_P (expr)
+         && !TREE_PUBLIC (expr)
+         && DECL_RTL_SET_P (expr)
+         && MEM_P (DECL_RTL (expr)))
+       {
+         /* If this is a var that might not be actually output,
+            return NULL, otherwise stabs might reference an undefined
+            symbol.  */
+         struct varpool_node *node = varpool_get_node (expr);
+         if (!node || !node->needed)
+           return NULL;
+       }
+      /* FALLTHRU */
+
+    case PARM_DECL:
+    case RESULT_DECL:
+      if (DECL_HAS_VALUE_EXPR_P (expr))
+       return dbxout_expand_expr (DECL_VALUE_EXPR (expr));
+      /* FALLTHRU */
+
+    case CONST_DECL:
+      return DECL_RTL_IF_SET (expr);
+
+    case INTEGER_CST:
+      return expand_expr (expr, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
+
+    case COMPONENT_REF:
+    case ARRAY_REF:
+    case ARRAY_RANGE_REF:
+    case BIT_FIELD_REF:
+      {
+       enum machine_mode mode;
+       HOST_WIDE_INT bitsize, bitpos;
+       tree offset, tem;
+       int volatilep = 0, unsignedp = 0;
+       rtx x;
+
+       tem = get_inner_reference (expr, &bitsize, &bitpos, &offset,
+                                  &mode, &unsignedp, &volatilep, true);
+
+       x = dbxout_expand_expr (tem);
+       if (x == NULL || !MEM_P (x))
+         return NULL;
+       if (offset != NULL)
+         {
+           if (!host_integerp (offset, 0))
+             return NULL;
+           x = adjust_address_nv (x, mode, tree_low_cst (offset, 0));
+         }
+       if (bitpos != 0)
+         x = adjust_address_nv (x, mode, bitpos / BITS_PER_UNIT);
+
+       return x;
+      }
+
+    default:
+      return NULL;
+    }
+}
+
+/* Helper function for output_used_types.  Queue one entry from the
+   used types hash to be output.  */
+
+static int
+output_used_types_helper (void **slot, void *data)
+{
+  tree type = (tree) *slot;
+  VEC(tree, heap) **types_p = (VEC(tree, heap) **) data;
+
+  if ((TREE_CODE (type) == RECORD_TYPE
+       || TREE_CODE (type) == UNION_TYPE
+       || TREE_CODE (type) == QUAL_UNION_TYPE
+       || TREE_CODE (type) == ENUMERAL_TYPE)
+      && TYPE_STUB_DECL (type)
+      && DECL_P (TYPE_STUB_DECL (type))
+      && ! DECL_IGNORED_P (TYPE_STUB_DECL (type)))
+    VEC_quick_push (tree, *types_p, TYPE_STUB_DECL (type));
+  else if (TYPE_NAME (type)
+          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
+    VEC_quick_push (tree, *types_p, TYPE_NAME (type));
+
+  return 1;
+}
+
+/* This is a qsort callback which sorts types and declarations into a
+   predictable order (types, then declarations, sorted by UID
+   within).  */
+
+static int
+output_types_sort (const void *pa, const void *pb)
+{
+  const tree lhs = *((const tree *)pa);
+  const tree rhs = *((const tree *)pb);
+
+  if (TYPE_P (lhs))
+    {
+      if (TYPE_P (rhs))
+       return TYPE_UID (lhs) - TYPE_UID (rhs);
+      else
+       return 1;
+    }
+  else
+    {
+      if (TYPE_P (rhs))
+       return -1;
+      else
+       return DECL_UID (lhs) - DECL_UID (rhs);
+    }
+}
+
+
+/* Force all types used by this function to be output in debug
+   information.  */
+
+static void
+output_used_types (void)
+{
+  if (cfun && cfun->used_types_hash)
+    {
+      VEC(tree, heap) *types;
+      int i;
+      tree type;
+
+      types = VEC_alloc (tree, heap, htab_elements (cfun->used_types_hash));
+      htab_traverse (cfun->used_types_hash, output_used_types_helper, &types);
+
+      /* Sort by UID to prevent dependence on hash table ordering.  */
+      VEC_qsort (tree, types, output_types_sort);
+
+      FOR_EACH_VEC_ELT (tree, types, i, type)
+       debug_queue_symbol (type);
+
+      VEC_free (tree, heap, types);
+    }
+}
+
 /* Output a .stabs for the symbol defined by DECL,
    which must be a ..._DECL node in the normal namespace.
    It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
 /* Output a .stabs for the symbol defined by DECL,
    which must be a ..._DECL node in the normal namespace.
    It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
@@ -2342,6 +2622,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
   tree type = TREE_TYPE (decl);
   tree context = NULL_TREE;
   int result = 0;
   tree type = TREE_TYPE (decl);
   tree context = NULL_TREE;
   int result = 0;
+  rtx decl_rtl;
 
   /* "Intercept" dbxout_symbol() calls like we do all debug_hooks.  */
   ++debug_nesting;
 
   /* "Intercept" dbxout_symbol() calls like we do all debug_hooks.  */
   ++debug_nesting;
@@ -2353,8 +2634,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
     DBXOUT_DECR_NESTING_AND_RETURN (0);
 
   /* If we are to generate only the symbols actually used then such
     DBXOUT_DECR_NESTING_AND_RETURN (0);
 
   /* If we are to generate only the symbols actually used then such
-     symbol nodees are flagged with TREE_USED.  Ignore any that
-     aren't flaged as TREE_USED.  */
+     symbol nodes are flagged with TREE_USED.  Ignore any that
+     aren't flagged as TREE_USED.  */
 
   if (flag_debug_only_used_symbols
       && (!TREE_USED (decl)
 
   if (flag_debug_only_used_symbols
       && (!TREE_USED (decl)
@@ -2426,7 +2707,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
       break;
 
     case FUNCTION_DECL:
       break;
 
     case FUNCTION_DECL:
-      if (DECL_RTL (decl) == 0)
+      decl_rtl = DECL_RTL_IF_SET (decl);
+      if (!decl_rtl)
        DBXOUT_DECR_NESTING_AND_RETURN (0);
       if (DECL_EXTERNAL (decl))
        break;
        DBXOUT_DECR_NESTING_AND_RETURN (0);
       if (DECL_EXTERNAL (decl))
        break;
@@ -2434,9 +2716,15 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
       context = decl_function_context (decl);
       if (context == current_function_decl)
        break;
       context = decl_function_context (decl);
       if (context == current_function_decl)
        break;
-      if (!MEM_P (DECL_RTL (decl))
-         || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
+      /* Don't mention an inline instance of a nested function.  */
+      if (context && DECL_FROM_INLINE (decl))
        break;
        break;
+      if (!MEM_P (decl_rtl)
+         || GET_CODE (XEXP (decl_rtl, 0)) != SYMBOL_REF)
+       break;
+
+      if (flag_debug_only_used_symbols)
+       output_used_types ();
 
       dbxout_begin_complex_stabs ();
       stabstr_I (DECL_ASSEMBLER_NAME (decl));
 
       dbxout_begin_complex_stabs ();
       stabstr_I (DECL_ASSEMBLER_NAME (decl));
@@ -2459,8 +2747,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
          stabstr_I (DECL_NAME (context));
        }
 
          stabstr_I (DECL_NAME (context));
        }
 
-      dbxout_finish_complex_stabs (decl, N_FUN, XEXP (DECL_RTL (decl), 0),
-                                  0, 0);
+      dbxout_finish_complex_stabs (decl, N_FUN, XEXP (decl_rtl, 0), 0, 0);
       break;
 
     case TYPE_DECL:
       break;
 
     case TYPE_DECL:
@@ -2502,7 +2789,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
                 || TREE_CODE (type) == UNION_TYPE
                 || TREE_CODE (type) == QUAL_UNION_TYPE)
                && TYPE_NAME (type) == decl
                 || TREE_CODE (type) == UNION_TYPE
                 || TREE_CODE (type) == QUAL_UNION_TYPE)
                && TYPE_NAME (type) == decl
-               && !(use_gnu_debug_info_extensions && have_used_extensions)
+               && !use_gnu_debug_info_extensions
                && !TREE_ASM_WRITTEN (TYPE_NAME (type))
                /* Distinguish the implicit typedefs of C++
                   from explicit ones that might be found in C.  */
                && !TREE_ASM_WRITTEN (TYPE_NAME (type))
                /* Distinguish the implicit typedefs of C++
                   from explicit ones that might be found in C.  */
@@ -2528,11 +2815,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
 
            dbxout_begin_complex_stabs ();
 
 
            dbxout_begin_complex_stabs ();
 
-           /* Output leading class/struct qualifiers.
-              ??? why not set have_used_extensions here ... because
-              then the test of it below would always be true, I
-              guess.  But it's not clear to me why we shouldn't do
-              that always in extended mode.  */
+           /* Output leading class/struct qualifiers.  */
            if (use_gnu_debug_info_extensions)
              dbxout_class_name_qualifiers (decl);
 
            if (use_gnu_debug_info_extensions)
              dbxout_class_name_qualifiers (decl);
 
@@ -2549,7 +2832,7 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
                   from explicit ones that might be found in C.  */
                && DECL_ARTIFICIAL (decl))
              {
                   from explicit ones that might be found in C.  */
                && DECL_ARTIFICIAL (decl))
              {
-               if (use_gnu_debug_info_extensions && have_used_extensions)
+               if (use_gnu_debug_info_extensions)
                  {
                    stabstr_C ('T');
                    TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1;
                  {
                    stabstr_C ('T');
                    TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1;
@@ -2609,15 +2892,18 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
       }
 
     case PARM_DECL:
       }
 
     case PARM_DECL:
-      /* Parm decls go in their own separate chains
-        and are output by dbxout_reg_parms and dbxout_parms.  */
-      gcc_unreachable ();
+      if (DECL_HAS_VALUE_EXPR_P (decl))
+       decl = DECL_VALUE_EXPR (decl);
+
+      /* PARM_DECLs go in their own separate chain and are output by
+        dbxout_reg_parms and dbxout_parms, except for those that are
+        disguised VAR_DECLs like Out parameters in Ada.  */
+      gcc_assert (TREE_CODE (decl) == VAR_DECL);
+
+      /* ... fall through ...  */
 
     case RESULT_DECL:
 
     case RESULT_DECL:
-      /* Named return value, treat like a VAR_DECL.  */
     case VAR_DECL:
     case VAR_DECL:
-      if (! DECL_RTL_SET_P (decl))
-       DBXOUT_DECR_NESTING_AND_RETURN (0);
       /* Don't mention a variable that is external.
         Let the file that defines it describe it.  */
       if (DECL_EXTERNAL (decl))
       /* Don't mention a variable that is external.
         Let the file that defines it describe it.  */
       if (DECL_EXTERNAL (decl))
@@ -2631,8 +2917,9 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
          && DECL_INITIAL (decl) != 0
          && host_integerp (DECL_INITIAL (decl), 0)
          && ! TREE_ASM_WRITTEN (decl)
          && DECL_INITIAL (decl) != 0
          && host_integerp (DECL_INITIAL (decl), 0)
          && ! TREE_ASM_WRITTEN (decl)
-         && (DECL_CONTEXT (decl) == NULL_TREE
-             || TREE_CODE (DECL_CONTEXT (decl)) == BLOCK)
+         && (DECL_FILE_SCOPE_P (decl)
+             || TREE_CODE (DECL_CONTEXT (decl)) == BLOCK
+             || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
          && TREE_PUBLIC (decl) == 0)
        {
          /* The sun4 assembler does not grok this.  */
          && TREE_PUBLIC (decl) == 0)
        {
          /* The sun4 assembler does not grok this.  */
@@ -2643,8 +2930,8 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
              HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl));
 
              dbxout_begin_complex_stabs ();
              HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl));
 
              dbxout_begin_complex_stabs ();
-             stabstr_I (DECL_NAME (decl));
-             stabstr_S (":c=i");
+             dbxout_symbol_name (decl, NULL, 'c');
+             stabstr_S ("=i");
              stabstr_D (ival);
              dbxout_finish_complex_stabs (0, N_LSYM, 0, 0, 0);
              DBXOUT_DECR_NESTING;
              stabstr_D (ival);
              dbxout_finish_complex_stabs (0, N_LSYM, 0, 0, 0);
              DBXOUT_DECR_NESTING;
@@ -2655,13 +2942,17 @@ dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
        }
       /* else it is something we handle like a normal variable.  */
 
        }
       /* else it is something we handle like a normal variable.  */
 
-      SET_DECL_RTL (decl, eliminate_regs (DECL_RTL (decl), 0, NULL_RTX));
+      decl_rtl = dbxout_expand_expr (decl);
+      if (!decl_rtl)
+       DBXOUT_DECR_NESTING_AND_RETURN (0);
+
+      decl_rtl = eliminate_regs (decl_rtl, VOIDmode, NULL_RTX);
 #ifdef LEAF_REG_REMAP
       if (current_function_uses_only_leaf_regs)
 #ifdef LEAF_REG_REMAP
       if (current_function_uses_only_leaf_regs)
-       leaf_renumber_regs_insn (DECL_RTL (decl));
+       leaf_renumber_regs_insn (decl_rtl);
 #endif
 
 #endif
 
-      result = dbxout_symbol_location (decl, type, 0, DECL_RTL (decl));
+      result = dbxout_symbol_location (decl, type, 0, decl_rtl);
       break;
 
     default:
       break;
 
     default:
@@ -2681,7 +2972,7 @@ static int
 dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 {
   int letter = 0;
 dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 {
   int letter = 0;
-  STAB_CODE_TYPE code;
+  stab_code_type code;
   rtx addr = 0;
   int number = 0;
   int regno = -1;
   rtx addr = 0;
   int number = 0;
   int regno = -1;
@@ -2729,8 +3020,15 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
     {
       if (TREE_PUBLIC (decl))
        {
     {
       if (TREE_PUBLIC (decl))
        {
+         int offs;
          letter = 'G';
          code = N_GSYM;
          letter = 'G';
          code = N_GSYM;
+         if (NULL != dbxout_common_check (decl, &offs))
+           {
+             letter = 'V';
+             addr = 0;
+             number = offs;
+           }
        }
       else
        {
        }
       else
        {
@@ -2738,6 +3036,37 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
 
          letter = decl_function_context (decl) ? 'V' : 'S';
 
 
          letter = decl_function_context (decl) ? 'V' : 'S';
 
+         /* Some ports can transform a symbol ref into a label ref,
+            because the symbol ref is too far away and has to be
+            dumped into a constant pool.  Alternatively, the symbol
+            in the constant pool might be referenced by a different
+            symbol.  */
+         if (GET_CODE (addr) == SYMBOL_REF
+             && CONSTANT_POOL_ADDRESS_P (addr))
+           {
+             bool marked;
+             rtx tmp = get_pool_constant_mark (addr, &marked);
+
+             if (GET_CODE (tmp) == SYMBOL_REF)
+               {
+                 addr = tmp;
+                 if (CONSTANT_POOL_ADDRESS_P (addr))
+                   get_pool_constant_mark (addr, &marked);
+                 else
+                   marked = true;
+               }
+             else if (GET_CODE (tmp) == LABEL_REF)
+               {
+                 addr = tmp;
+                 marked = true;
+               }
+
+             /* If all references to the constant pool were optimized
+                out, we just ignore the symbol.  */
+             if (!marked)
+               return 0;
+           }
+
          /* This should be the same condition as in assemble_variable, but
             we don't have access to dont_output_data here.  So, instead,
             we rely on the fact that error_mark_node initializers always
          /* This should be the same condition as in assemble_variable, but
             we don't have access to dont_output_data here.  So, instead,
             we rely on the fact that error_mark_node initializers always
@@ -2745,47 +3074,26 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
          if (DECL_INITIAL (decl) == 0
              || (!strcmp (lang_hooks.name, "GNU C++")
                  && DECL_INITIAL (decl) == error_mark_node))
          if (DECL_INITIAL (decl) == 0
              || (!strcmp (lang_hooks.name, "GNU C++")
                  && DECL_INITIAL (decl) == error_mark_node))
-           code = N_LCSYM;
+           {
+             int offs;
+             code = N_LCSYM;
+             if (NULL != dbxout_common_check (decl, &offs))
+               {
+                 addr = 0;
+                 number = offs;
+                 letter = 'V';
+                 code = N_GSYM;
+               }
+           }
          else if (DECL_IN_TEXT_SECTION (decl))
            /* This is not quite right, but it's the closest
               of all the codes that Unix defines.  */
            code = DBX_STATIC_CONST_VAR_CODE;
          else
            {
          else if (DECL_IN_TEXT_SECTION (decl))
            /* This is not quite right, but it's the closest
               of all the codes that Unix defines.  */
            code = DBX_STATIC_CONST_VAR_CODE;
          else
            {
-             /* Some ports can transform a symbol ref into a label ref,
-                because the symbol ref is too far away and has to be
-                dumped into a constant pool.  Alternatively, the symbol
-                in the constant pool might be referenced by a different
-                symbol.  */
-             if (GET_CODE (addr) == SYMBOL_REF
-                 && CONSTANT_POOL_ADDRESS_P (addr))
-               {
-                 bool marked;
-                 rtx tmp = get_pool_constant_mark (addr, &marked);
-
-                 if (GET_CODE (tmp) == SYMBOL_REF)
-                   {
-                     addr = tmp;
-                     if (CONSTANT_POOL_ADDRESS_P (addr))
-                       get_pool_constant_mark (addr, &marked);
-                     else
-                       marked = true;
-                   }
-                 else if (GET_CODE (tmp) == LABEL_REF)
-                   {
-                     addr = tmp;
-                     marked = true;
-                   }
-
-                  /* If all references to the constant pool were optimized
-                     out, we just ignore the symbol.  */
-                 if (!marked)
-                   return 0;
-               }
-
              /* Ultrix `as' seems to need this.  */
 #ifdef DBX_STATIC_STAB_DATA_SECTION
              /* Ultrix `as' seems to need this.  */
 #ifdef DBX_STATIC_STAB_DATA_SECTION
-             data_section ();
+             switch_to_section (data_section);
 #endif
              code = N_STSYM;
            }
 #endif
              code = N_STSYM;
            }
@@ -2802,7 +3110,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
               || (REG_P (XEXP (home, 0))
                   && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM
                   && REGNO (XEXP (home, 0)) != STACK_POINTER_REGNUM
               || (REG_P (XEXP (home, 0))
                   && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM
                   && REGNO (XEXP (home, 0)) != STACK_POINTER_REGNUM
-#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+#if !HARD_FRAME_POINTER_IS_ARG_POINTER
                   && REGNO (XEXP (home, 0)) != ARG_POINTER_REGNUM
 #endif
                   )))
                   && REGNO (XEXP (home, 0)) != ARG_POINTER_REGNUM
 #endif
                   )))
@@ -2844,7 +3152,7 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
     }
   else if (MEM_P (home)
           && GET_CODE (XEXP (home, 0)) == PLUS
     }
   else if (MEM_P (home)
           && GET_CODE (XEXP (home, 0)) == PLUS
-          && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT)
+          && CONST_INT_P (XEXP (XEXP (home, 0), 1)))
     {
       code = N_LSYM;
       /* RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
     {
       code = N_LSYM;
       /* RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
@@ -2865,9 +3173,17 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
         variable, thereby avoiding the need for a register.  In such
         cases we're forced to lie to debuggers and tell them that
         this variable was itself `static'.  */
         variable, thereby avoiding the need for a register.  In such
         cases we're forced to lie to debuggers and tell them that
         this variable was itself `static'.  */
+      int offs;
       code = N_LCSYM;
       letter = 'V';
       code = N_LCSYM;
       letter = 'V';
-      addr = XEXP (XEXP (home, 0), 0);
+      if (NULL == dbxout_common_check (decl, &offs))
+        addr = XEXP (XEXP (home, 0), 0);
+      else
+        {
+         addr = 0;
+         number = offs;
+         code = N_GSYM;
+       }
     }
   else if (GET_CODE (home) == CONCAT)
     {
     }
   else if (GET_CODE (home) == CONCAT)
     {
@@ -2901,12 +3217,14 @@ dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
     return 0;
 
   /* Ok, start a symtab entry and output the variable name.  */
     return 0;
 
   /* Ok, start a symtab entry and output the variable name.  */
+  emit_pending_bincls_if_required ();
+  FORCE_TEXT;
 
 #ifdef DBX_STATIC_BLOCK_START
   DBX_STATIC_BLOCK_START (asm_out_file, code);
 #endif
 
 
 #ifdef DBX_STATIC_BLOCK_START
   DBX_STATIC_BLOCK_START (asm_out_file, code);
 #endif
 
-  dbxout_begin_complex_stabs ();
+  dbxout_begin_complex_stabs_noforcetext ();
   dbxout_symbol_name (decl, suffix, letter);
   dbxout_type (type, 0);
   dbxout_finish_complex_stabs (decl, code, addr, 0, number);
   dbxout_symbol_name (decl, suffix, letter);
   dbxout_type (type, 0);
   dbxout_finish_complex_stabs (decl, code, addr, 0, number);
@@ -2925,7 +3243,7 @@ dbxout_symbol_name (tree decl, const char *suffix, int letter)
 {
   tree name;
 
 {
   tree name;
 
-  if (DECL_CONTEXT (decl) 
+  if (DECL_CONTEXT (decl)
       && (TYPE_P (DECL_CONTEXT (decl))
          || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
     /* One slight hitch: if this is a VAR_DECL which is a class member
       && (TYPE_P (DECL_CONTEXT (decl))
          || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
     /* One slight hitch: if this is a VAR_DECL which is a class member
@@ -2950,6 +3268,114 @@ dbxout_symbol_name (tree decl, const char *suffix, int letter)
     stabstr_C (letter);
 }
 
     stabstr_C (letter);
 }
 
+
+/* Output the common block name for DECL in a stabs.
+
+   Symbols in global common (.comm) get wrapped with an N_BCOMM/N_ECOMM pair
+   around each group of symbols in the same .comm area.  The N_GSYM stabs
+   that are emitted only contain the offset in the common area.  This routine
+   emits the N_BCOMM and N_ECOMM stabs.  */
+
+static void
+dbxout_common_name (tree decl, const char *name, stab_code_type op)
+{
+  dbxout_begin_complex_stabs ();
+  stabstr_S (name);
+  dbxout_finish_complex_stabs (decl, op, NULL_RTX, NULL, 0);
+}
+
+/* Check decl to determine whether it is a VAR_DECL destined for storage in a
+   common area.  If it is, the return value will be a non-null string giving
+   the name of the common storage block it will go into.  If non-null, the
+   value is the offset into the common block for that symbol's storage.  */
+
+static const char *
+dbxout_common_check (tree decl, int *value)
+{
+  rtx home;
+  rtx sym_addr;
+  const char *name = NULL;
+
+  /* If the decl isn't a VAR_DECL, or if it isn't static, or if
+     it does not have a value (the offset into the common area), or if it
+     is thread local (as opposed to global) then it isn't common, and shouldn't
+     be handled as such.
+
+     ??? DECL_THREAD_LOCAL_P check prevents problems with improper .stabs
+     for thread-local symbols.  Can be handled via same mechanism as used
+     in dwarf2out.c.  */
+  if (TREE_CODE (decl) != VAR_DECL
+      || !TREE_STATIC(decl)
+      || !DECL_HAS_VALUE_EXPR_P(decl)
+      || DECL_THREAD_LOCAL_P (decl)
+      || !is_fortran ())
+    return NULL;
+
+  home = DECL_RTL (decl);
+  if (home == NULL_RTX || GET_CODE (home) != MEM)
+    return NULL;
+
+  sym_addr = dbxout_expand_expr (DECL_VALUE_EXPR (decl));
+  if (sym_addr == NULL_RTX || GET_CODE (sym_addr) != MEM)
+    return NULL;
+
+  sym_addr = XEXP (sym_addr, 0);
+  if (GET_CODE (sym_addr) == CONST)
+    sym_addr = XEXP (sym_addr, 0);
+  if ((GET_CODE (sym_addr) == SYMBOL_REF || GET_CODE (sym_addr) == PLUS)
+      && DECL_INITIAL (decl) == 0)
+    {
+
+      /* We have a sym that will go into a common area, meaning that it
+         will get storage reserved with a .comm/.lcomm assembler pseudo-op.
+
+         Determine name of common area this symbol will be an offset into,
+         and offset into that area.  Also retrieve the decl for the area
+         that the symbol is offset into.  */
+      tree cdecl = NULL;
+
+      switch (GET_CODE (sym_addr))
+        {
+        case PLUS:
+          if (CONST_INT_P (XEXP (sym_addr, 0)))
+            {
+              name =
+                targetm.strip_name_encoding(XSTR (XEXP (sym_addr, 1), 0));
+              *value = INTVAL (XEXP (sym_addr, 0));
+              cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 1));
+            }
+          else
+            {
+              name =
+                targetm.strip_name_encoding(XSTR (XEXP (sym_addr, 0), 0));
+              *value = INTVAL (XEXP (sym_addr, 1));
+              cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 0));
+            }
+          break;
+
+        case SYMBOL_REF:
+          name = targetm.strip_name_encoding(XSTR (sym_addr, 0));
+          *value = 0;
+          cdecl = SYMBOL_REF_DECL (sym_addr);
+          break;
+
+        default:
+          error ("common symbol debug info is not structured as "
+                 "symbol+offset");
+        }
+
+      /* Check area common symbol is offset into.  If this is not public, then
+         it is not a symbol in a common block.  It must be a .lcomm symbol, not
+         a .comm symbol.  */
+      if (cdecl == NULL || !TREE_PUBLIC(cdecl))
+        name = NULL;
+    }
+  else
+    name = NULL;
+
+  return name;
+}
+
 /* Output definitions of all the decls in a chain. Return nonzero if
    anything was output */
 
 /* Output definitions of all the decls in a chain. Return nonzero if
    anything was output */
 
@@ -2957,11 +3383,38 @@ int
 dbxout_syms (tree syms)
 {
   int result = 0;
 dbxout_syms (tree syms)
 {
   int result = 0;
+  const char *comm_prev = NULL;
+  tree syms_prev = NULL;
+
   while (syms)
     {
   while (syms)
     {
+      int temp, copen, cclos;
+      const char *comm_new;
+
+      /* Check for common symbol, and then progression into a new/different
+         block of common symbols.  Emit closing/opening common bracket if
+         necessary.  */
+      comm_new = dbxout_common_check (syms, &temp);
+      copen = comm_new != NULL
+              && (comm_prev == NULL || strcmp (comm_new, comm_prev));
+      cclos = comm_prev != NULL
+              && (comm_new == NULL || strcmp (comm_new, comm_prev));
+      if (cclos)
+        dbxout_common_name (syms_prev, comm_prev, N_ECOMM);
+      if (copen)
+        {
+          dbxout_common_name (syms, comm_new, N_BCOMM);
+          syms_prev = syms;
+        }
+      comm_prev = comm_new;
+
       result += dbxout_symbol (syms, 1);
       result += dbxout_symbol (syms, 1);
-      syms = TREE_CHAIN (syms);
+      syms = DECL_CHAIN (syms);
     }
     }
+
+  if (comm_prev != NULL)
+    dbxout_common_name (syms_prev, comm_prev, N_ECOMM);
+
   return result;
 }
 \f
   return result;
 }
 \f
@@ -2983,7 +3436,7 @@ dbxout_parms (tree parms)
   ++debug_nesting;
   emit_pending_bincls_if_required ();
 
   ++debug_nesting;
   emit_pending_bincls_if_required ();
 
-  for (; parms; parms = TREE_CHAIN (parms))
+  for (; parms; parms = DECL_CHAIN (parms))
     if (DECL_NAME (parms)
        && TREE_TYPE (parms) != error_mark_node
        && DECL_RTL_SET_P (parms)
     if (DECL_NAME (parms)
        && TREE_TYPE (parms) != error_mark_node
        && DECL_RTL_SET_P (parms)
@@ -2991,14 +3444,15 @@ dbxout_parms (tree parms)
       {
        tree eff_type;
        char letter;
       {
        tree eff_type;
        char letter;
-       STAB_CODE_TYPE code;
+       stab_code_type code;
        int number;
 
        /* Perform any necessary register eliminations on the parameter's rtl,
           so that the debugging output will be accurate.  */
        DECL_INCOMING_RTL (parms)
        int number;
 
        /* Perform any necessary register eliminations on the parameter's rtl,
           so that the debugging output will be accurate.  */
        DECL_INCOMING_RTL (parms)
-         = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
-       SET_DECL_RTL (parms, eliminate_regs (DECL_RTL (parms), 0, NULL_RTX));
+         = eliminate_regs (DECL_INCOMING_RTL (parms), VOIDmode, NULL_RTX);
+       SET_DECL_RTL (parms,
+                     eliminate_regs (DECL_RTL (parms), VOIDmode, NULL_RTX));
 #ifdef LEAF_REG_REMAP
        if (current_function_uses_only_leaf_regs)
          {
 #ifdef LEAF_REG_REMAP
        if (current_function_uses_only_leaf_regs)
          {
@@ -3016,7 +3470,7 @@ dbxout_parms (tree parms)
               If that is not true, we produce meaningless results,
               but do not crash.  */
            if (GET_CODE (inrtl) == PLUS
               If that is not true, we produce meaningless results,
               but do not crash.  */
            if (GET_CODE (inrtl) == PLUS
-               && GET_CODE (XEXP (inrtl, 1)) == CONST_INT)
+               && CONST_INT_P (XEXP (inrtl, 1)))
              number = INTVAL (XEXP (inrtl, 1));
            else
              number = 0;
              number = INTVAL (XEXP (inrtl, 1));
            else
              number = 0;
@@ -3059,6 +3513,8 @@ dbxout_parms (tree parms)
               was passed.  */
            if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
              best_rtl = DECL_RTL (parms);
               was passed.  */
            if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
              best_rtl = DECL_RTL (parms);
+           else if (GET_CODE (DECL_INCOMING_RTL (parms)) == PARALLEL)
+             best_rtl = XEXP (XVECEXP (DECL_INCOMING_RTL (parms), 0, 0), 0);
            else
              best_rtl = DECL_INCOMING_RTL (parms);
 
            else
              best_rtl = DECL_INCOMING_RTL (parms);
 
@@ -3068,7 +3524,7 @@ dbxout_parms (tree parms)
                 && REG_P (XEXP (DECL_RTL (parms), 0))
                 && REGNO (XEXP (DECL_RTL (parms), 0)) != HARD_FRAME_POINTER_REGNUM
                 && REGNO (XEXP (DECL_RTL (parms), 0)) != STACK_POINTER_REGNUM
                 && REG_P (XEXP (DECL_RTL (parms), 0))
                 && REGNO (XEXP (DECL_RTL (parms), 0)) != HARD_FRAME_POINTER_REGNUM
                 && REGNO (XEXP (DECL_RTL (parms), 0)) != STACK_POINTER_REGNUM
-#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+#if !HARD_FRAME_POINTER_IS_ARG_POINTER
                 && REGNO (XEXP (DECL_RTL (parms), 0)) != ARG_POINTER_REGNUM
 #endif
                 )
                 && REGNO (XEXP (DECL_RTL (parms), 0)) != ARG_POINTER_REGNUM
 #endif
                 )
@@ -3077,10 +3533,10 @@ dbxout_parms (tree parms)
               That is, its address was passed in a register.
               Output it as if it lived in that register.
               The debugger will know from the type
               That is, its address was passed in a register.
               Output it as if it lived in that register.
               The debugger will know from the type
-              that it was actually passed by invisible reference. */
+              that it was actually passed by invisible reference.  */
 
            code = DBX_REGPARM_STABS_CODE;
 
            code = DBX_REGPARM_STABS_CODE;
+
            /* GDB likes this marked with a special letter.  */
            letter = (use_gnu_debug_info_extensions
                      ? 'a' : DBX_REGPARM_STABS_LETTER);
            /* GDB likes this marked with a special letter.  */
            letter = (use_gnu_debug_info_extensions
                      ? 'a' : DBX_REGPARM_STABS_LETTER);
@@ -3151,7 +3607,7 @@ dbxout_parms (tree parms)
          continue;
 
        dbxout_begin_complex_stabs ();
          continue;
 
        dbxout_begin_complex_stabs ();
-           
+
        if (DECL_NAME (parms))
          {
            stabstr_I (DECL_NAME (parms));
        if (DECL_NAME (parms))
          {
            stabstr_I (DECL_NAME (parms));
@@ -3182,7 +3638,7 @@ dbxout_reg_parms (tree parms)
 {
   ++debug_nesting;
 
 {
   ++debug_nesting;
 
-  for (; parms; parms = TREE_CHAIN (parms))
+  for (; parms; parms = DECL_CHAIN (parms))
     if (DECL_NAME (parms) && PARM_PASSED_IN_MEMORY (parms))
       {
        /* Report parms that live in registers during the function
     if (DECL_NAME (parms) && PARM_PASSED_IN_MEMORY (parms))
       {
        /* Report parms that live in registers during the function
@@ -3217,6 +3673,8 @@ dbxout_args (tree args)
     }
 }
 \f
     }
 }
 \f
+#if defined (DBX_DEBUGGING_INFO)
+
 /* Subroutine of dbxout_block.  Emit an N_LBRAC stab referencing LABEL.
    BEGIN_LABEL is the name of the beginning of the function, which may
    be required.  */
 /* Subroutine of dbxout_block.  Emit an N_LBRAC stab referencing LABEL.
    BEGIN_LABEL is the name of the beginning of the function, which may
    be required.  */
@@ -3224,15 +3682,11 @@ static void
 dbx_output_lbrac (const char *label,
                  const char *begin_label ATTRIBUTE_UNUSED)
 {
 dbx_output_lbrac (const char *label,
                  const char *begin_label ATTRIBUTE_UNUSED)
 {
-#ifdef DBX_OUTPUT_LBRAC
-  DBX_OUTPUT_LBRAC (asm_out_file, label);
-#else
   dbxout_begin_stabn (N_LBRAC);
   if (DBX_BLOCKS_FUNCTION_RELATIVE)
     dbxout_stab_value_label_diff (label, begin_label);
   else
     dbxout_stab_value_label (label);
   dbxout_begin_stabn (N_LBRAC);
   if (DBX_BLOCKS_FUNCTION_RELATIVE)
     dbxout_stab_value_label_diff (label, begin_label);
   else
     dbxout_stab_value_label (label);
-#endif
 }
 
 /* Subroutine of dbxout_block.  Emit an N_RBRAC stab referencing LABEL.
 }
 
 /* Subroutine of dbxout_block.  Emit an N_RBRAC stab referencing LABEL.
@@ -3242,15 +3696,11 @@ static void
 dbx_output_rbrac (const char *label,
                  const char *begin_label ATTRIBUTE_UNUSED)
 {
 dbx_output_rbrac (const char *label,
                  const char *begin_label ATTRIBUTE_UNUSED)
 {
-#ifdef DBX_OUTPUT_RBRAC
-  DBX_OUTPUT_RBRAC (asm_out_file, label);
-#else
   dbxout_begin_stabn (N_RBRAC);
   if (DBX_BLOCKS_FUNCTION_RELATIVE)
     dbxout_stab_value_label_diff (label, begin_label);
   else
     dbxout_stab_value_label (label);
   dbxout_begin_stabn (N_RBRAC);
   if (DBX_BLOCKS_FUNCTION_RELATIVE)
     dbxout_stab_value_label_diff (label, begin_label);
   else
     dbxout_stab_value_label (label);
-#endif
 }
 
 /* Output everything about a symbol block (a BLOCK node
 }
 
 /* Output everything about a symbol block (a BLOCK node
@@ -3273,8 +3723,9 @@ dbx_output_rbrac (const char *label,
 static void
 dbxout_block (tree block, int depth, tree args)
 {
 static void
 dbxout_block (tree block, int depth, tree args)
 {
-  const char *begin_label
-    = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
+  char begin_label[20];
+  /* Reference current function start using LFBB.  */
+  ASM_GENERATE_INTERNAL_LABEL (begin_label, "LFBB", scope_labelno);
 
   while (block)
     {
 
   while (block)
     {
@@ -3303,7 +3754,7 @@ dbxout_block (tree block, int depth, tree args)
 
              if (depth == 0)
                /* The outermost block doesn't get LBB labels; use
 
              if (depth == 0)
                /* The outermost block doesn't get LBB labels; use
-                  the function symbol.  */
+                  the LFBB local symbol emitted by dbxout_begin_prologue.  */
                scope_start = begin_label;
              else
                {
                scope_start = begin_label;
              else
                {
@@ -3311,20 +3762,6 @@ dbxout_block (tree block, int depth, tree args)
                  scope_start = buf;
                }
 
                  scope_start = buf;
                }
 
-             if (BLOCK_HANDLER_BLOCK (block))
-               {
-                 /* A catch block.  Must precede N_LBRAC.  */
-                 tree decl = BLOCK_VARS (block);
-                 while (decl)
-                   {
-                     dbxout_begin_complex_stabs ();
-                     stabstr_I (DECL_NAME (decl));
-                     stabstr_S (":C1");
-                     dbxout_finish_complex_stabs (0, N_CATCH, 0,
-                                                  scope_start, 0);
-                     decl = TREE_CHAIN (decl);
-                   }
-               }
              dbx_output_lbrac (scope_start, begin_label);
            }
 
              dbx_output_lbrac (scope_start, begin_label);
            }
 
@@ -3354,11 +3791,12 @@ dbxout_block (tree block, int depth, tree args)
    Usually this follows the function's code,
    but on some systems, it comes before.  */
 
    Usually this follows the function's code,
    but on some systems, it comes before.  */
 
-#if defined (DBX_DEBUGGING_INFO)
 static void
 dbxout_begin_function (tree decl)
 {
 static void
 dbxout_begin_function (tree decl)
 {
-  int saved_tree_used1 = TREE_USED (decl);
+  int saved_tree_used1;
+
+  saved_tree_used1 = TREE_USED (decl);
   TREE_USED (decl) = 1;
   if (DECL_NAME (DECL_RESULT (decl)) != 0)
     {
   TREE_USED (decl) = 1;
   if (DECL_NAME (DECL_RESULT (decl)) != 0)
     {