OSDN Git Service

* config/xtensa/xtensa.c (function_arg): Generalize logic so that it
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index f22ca50..7dca634 100644 (file)
@@ -1,6 +1,6 @@
 /* Output Dwarf2 format symbol table information from GCC.
    Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003 Free Software Foundation, Inc.
+   2003, 2004 Free Software Foundation, Inc.
    Contributed by Gary Funck (gary@intrepid.com).
    Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
    Extensively modified by Jason Merrill (jason@cygnus.com).
@@ -64,6 +64,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "target.h"
 #include "langhooks.h"
 #include "hashtab.h"
+#include "cgraph.h"
 
 #ifdef DWARF2_DEBUGGING_INFO
 static void dwarf2out_source_line (unsigned int, const char *);
@@ -203,7 +204,7 @@ enum dw_cfi_oprnd_type {
 typedef union dw_cfi_oprnd_struct GTY(())
 {
   unsigned long GTY ((tag ("dw_cfi_oprnd_reg_num"))) dw_cfi_reg_num;
-  long int GTY ((tag ("dw_cfi_oprnd_offset"))) dw_cfi_offset;
+  HOST_WIDE_INT GTY ((tag ("dw_cfi_oprnd_offset"))) dw_cfi_offset;
   const char * GTY ((tag ("dw_cfi_oprnd_addr"))) dw_cfi_addr;
   struct dw_loc_descr_struct * GTY ((tag ("dw_cfi_oprnd_loc"))) dw_cfi_loc;
 }
@@ -228,8 +229,8 @@ dw_cfi_node;
 typedef struct cfa_loc GTY(())
 {
   unsigned long reg;
-  long offset;
-  long base_offset;
+  HOST_WIDE_INT offset;
+  HOST_WIDE_INT base_offset;
   int indirect;            /* 1 if CFA is accessed via a dereference.  */
 } dw_cfa_location;
 
@@ -349,13 +350,13 @@ static void add_cfi (dw_cfi_ref *, dw_cfi_ref);
 static void add_fde_cfi (const char *, dw_cfi_ref);
 static void lookup_cfa_1 (dw_cfi_ref, dw_cfa_location *);
 static void lookup_cfa (dw_cfa_location *);
-static void reg_save (const char *, unsigned, unsigned, long);
+static void reg_save (const char *, unsigned, unsigned, HOST_WIDE_INT);
 static void initial_return_save (rtx);
-static long stack_adjust_offset (rtx);
+static HOST_WIDE_INT stack_adjust_offset (rtx);
 static void output_cfi (dw_cfi_ref, dw_fde_ref, int);
 static void output_call_frame_info (int);
 static void dwarf2out_stack_adjust (rtx);
-static void queue_reg_save (const char *, rtx, long);
+static void queue_reg_save (const char *, rtx, HOST_WIDE_INT);
 static void flush_queued_reg_saves (void);
 static bool clobbers_queued_reg_save (rtx);
 static void dwarf2out_frame_debug_expr (rtx, const char *);
@@ -482,10 +483,20 @@ expand_builtin_init_dwarf_reg_sizes (tree address)
 
        emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
       }
+
+#ifdef DWARF_ALT_FRAME_RETURN_COLUMN
+  if (! wrote_return_column)
+    abort ();
+  i = DWARF_ALT_FRAME_RETURN_COLUMN;
+  wrote_return_column = false;
+#else
+  i = DWARF_FRAME_RETURN_COLUMN;
+#endif
+
   if (! wrote_return_column)
     {
       enum machine_mode save_mode = Pmode;
-      HOST_WIDE_INT offset = DWARF_FRAME_RETURN_COLUMN * GET_MODE_SIZE (mode);
+      HOST_WIDE_INT offset = i * GET_MODE_SIZE (mode);
       HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
       emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
     }
@@ -694,17 +705,17 @@ static dw_cfa_location cfa;
 static dw_cfa_location cfa_store;
 
 /* The running total of the size of arguments pushed onto the stack.  */
-static long args_size;
+static HOST_WIDE_INT args_size;
 
 /* The last args_size we actually output.  */
-static long old_args_size;
+static HOST_WIDE_INT old_args_size;
 
 /* Entry point to update the canonical frame address (CFA).
    LABEL is passed to add_fde_cfi.  The value of CFA is now to be
    calculated from REG+OFFSET.  */
 
 void
-dwarf2out_def_cfa (const char *label, unsigned int reg, long int offset)
+dwarf2out_def_cfa (const char *label, unsigned int reg, HOST_WIDE_INT offset)
 {
   dw_cfa_location loc;
   loc.indirect = 0;
@@ -791,7 +802,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
    otherwise it is saved in SREG.  */
 
 static void
-reg_save (const char *label, unsigned int reg, unsigned int sreg, long int offset)
+reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
 {
   dw_cfi_ref cfi = new_cfi ();
 
@@ -814,7 +825,7 @@ reg_save (const char *label, unsigned int reg, unsigned int sreg, long int offse
           DWARF_CIE_DATA_ALIGNMENT, there is either a bug in the
           definition of DWARF_CIE_DATA_ALIGNMENT, or a bug in the machine
           description.  */
-       long check_offset = offset / DWARF_CIE_DATA_ALIGNMENT;
+       HOST_WIDE_INT check_offset = offset / DWARF_CIE_DATA_ALIGNMENT;
 
        if (check_offset * DWARF_CIE_DATA_ALIGNMENT != offset)
          abort ();
@@ -858,7 +869,7 @@ dwarf2out_window_save (const char *label)
    pushed onto the stack.  */
 
 void
-dwarf2out_args_size (const char *label, long int size)
+dwarf2out_args_size (const char *label, HOST_WIDE_INT size)
 {
   dw_cfi_ref cfi;
 
@@ -877,7 +888,7 @@ dwarf2out_args_size (const char *label, long int size)
    number.  LABEL and OFFSET are passed to reg_save.  */
 
 void
-dwarf2out_reg_save (const char *label, unsigned int reg, long int offset)
+dwarf2out_reg_save (const char *label, unsigned int reg, HOST_WIDE_INT offset)
 {
   reg_save (label, DWARF_FRAME_REGNUM (reg), -1, offset);
 }
@@ -886,7 +897,7 @@ dwarf2out_reg_save (const char *label, unsigned int reg, long int offset)
    LABEL and OFFSET are passed to reg_save.  */
 
 void
-dwarf2out_return_save (const char *label, long int offset)
+dwarf2out_return_save (const char *label, HOST_WIDE_INT offset)
 {
   reg_save (label, DWARF_FRAME_RETURN_COLUMN, -1, offset);
 }
@@ -964,7 +975,7 @@ initial_return_save (rtx rtl)
 /* Given a SET, calculate the amount of stack adjustment it
    contains.  */
 
-static long
+static HOST_WIDE_INT
 stack_adjust_offset (rtx pattern)
 {
   rtx src = SET_SRC (pattern);
@@ -1046,6 +1057,13 @@ dwarf2out_stack_adjust (rtx insn)
   const char *label;
   int i;
 
+  /* Don't handle epilogues at all.  Certainly it would be wrong to do so
+     with this function.  Proper support would require all frame-related
+     insns to be marked, and to be able to handle saving state around
+     epilogues textually in the middle of the function.  */
+  if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn))
+    return;
+
   if (!flag_asynchronous_unwind_tables && GET_CODE (insn) == CALL_INSN)
     {
       /* Extract the size of the args from the CALL rtx itself.  */
@@ -1120,7 +1138,7 @@ struct queued_reg_save GTY(())
 {
   struct queued_reg_save *next;
   rtx reg;
-  long cfa_offset;
+  HOST_WIDE_INT cfa_offset;
 };
 
 static GTY(()) struct queued_reg_save *queued_reg_saves;
@@ -1129,7 +1147,7 @@ static GTY(()) struct queued_reg_save *queued_reg_saves;
 static const char *last_reg_save_label;
 
 static void
-queue_reg_save (const char *label, rtx reg, long int offset)
+queue_reg_save (const char *label, rtx reg, HOST_WIDE_INT offset)
 {
   struct queued_reg_save *q = ggc_alloc (sizeof (*q));
 
@@ -1772,29 +1790,37 @@ dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi)
 
 #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
 
+/* Map register numbers held in the call frame info that gcc has
+   collected using DWARF_FRAME_REGNUM to those that should be output in
+   .debug_frame and .eh_frame.  */
+#ifndef DWARF2_FRAME_REG_OUT
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
+#endif
+
 /* Output a Call Frame Information opcode and its operand(s).  */
 
 static void
 output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
 {
+  unsigned long r;
   if (cfi->dw_cfi_opc == DW_CFA_advance_loc)
     dw2_asm_output_data (1, (cfi->dw_cfi_opc
                             | (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)),
-                        "DW_CFA_advance_loc 0x%lx",
+                        "DW_CFA_advance_loc " HOST_WIDE_INT_PRINT_HEX,
                         cfi->dw_cfi_oprnd1.dw_cfi_offset);
   else if (cfi->dw_cfi_opc == DW_CFA_offset)
     {
-      dw2_asm_output_data (1, (cfi->dw_cfi_opc
-                              | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
-                          "DW_CFA_offset, column 0x%lx",
-                          cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+      dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+                          "DW_CFA_offset, column 0x%lx", r);
       dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
     }
   else if (cfi->dw_cfi_opc == DW_CFA_restore)
-    dw2_asm_output_data (1, (cfi->dw_cfi_opc
-                            | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
-                        "DW_CFA_restore, column 0x%lx",
-                        cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+    {
+      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+      dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+                          "DW_CFA_restore, column 0x%lx", r);
+    }
   else
     {
       dw2_asm_output_data (1, cfi->dw_cfi_opc,
@@ -1839,15 +1865,15 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
 
        case DW_CFA_offset_extended:
        case DW_CFA_def_cfa:
-         dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
-                                      NULL);
+         r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+         dw2_asm_output_data_uleb128 (r, NULL);
          dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
          break;
 
        case DW_CFA_offset_extended_sf:
        case DW_CFA_def_cfa_sf:
-         dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
-                                      NULL);
+         r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+         dw2_asm_output_data_uleb128 (r, NULL);
          dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
          break;
 
@@ -1855,15 +1881,15 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
        case DW_CFA_undefined:
        case DW_CFA_same_value:
        case DW_CFA_def_cfa_register:
-         dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
-                                      NULL);
+         r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+         dw2_asm_output_data_uleb128 (r, NULL);
          break;
 
        case DW_CFA_register:
-         dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
-                                      NULL);
-         dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_reg_num,
-                                      NULL);
+         r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+         dw2_asm_output_data_uleb128 (r, NULL);
+         r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, for_eh);
+         dw2_asm_output_data_uleb128 (r, NULL);
          break;
 
        case DW_CFA_def_cfa_offset:
@@ -1893,7 +1919,7 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
     }
 }
 
-/* Output the call frame information used to used to record information
+/* Output the call frame information used to record information
    that relates to calculating the frame pointer, and records the
    location of saved registers.  */
 
@@ -2354,11 +2380,11 @@ typedef struct dw_val_struct GTY(())
   union dw_val_struct_union
     {
       rtx GTY ((tag ("dw_val_class_addr"))) val_addr;
-      long unsigned GTY ((tag ("dw_val_class_offset"))) val_offset;
+      unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset"))) val_offset;
       dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list"))) val_loc_list;
       dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc;
-      long int GTY ((default (""))) val_int;
-      long unsigned GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
+      HOST_WIDE_INT GTY ((default (""))) val_int;
+      unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
       dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long;
       dw_float_const GTY ((tag ("dw_val_class_float"))) val_float;
       struct dw_val_die_union
@@ -2406,7 +2432,7 @@ typedef struct dw_loc_list_struct GTY(())
 
 static const char *dwarf_stack_op_name (unsigned);
 static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom,
-                                      unsigned long, unsigned long);
+                                      unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
 static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref);
 static unsigned long size_of_loc_descr (dw_loc_descr_ref);
 static unsigned long size_of_locs (dw_loc_descr_ref);
@@ -2731,8 +2757,8 @@ dwarf_stack_op_name (unsigned int op)
    together to form more complicated location (address) descriptions.  */
 
 static inline dw_loc_descr_ref
-new_loc_descr (enum dwarf_location_atom op, long unsigned int oprnd1,
-              long unsigned int oprnd2)
+new_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1,
+              unsigned HOST_WIDE_INT oprnd2)
 {
   dw_loc_descr_ref descr = ggc_alloc_cleared (sizeof (dw_loc_descr_node));
 
@@ -3321,6 +3347,7 @@ typedef struct die_struct GTY(())
   dw_die_ref die_parent;
   dw_die_ref die_child;
   dw_die_ref die_sib;
+  dw_die_ref die_definition; /* ref from a specification to its definition */
   dw_offset die_offset;
   unsigned long die_abbrev;
   int die_mark;
@@ -3433,12 +3460,6 @@ static unsigned long next_die_offset;
 /* Record the root of the DIE's built for the current compilation unit.  */
 static GTY(()) dw_die_ref comp_unit_die;
 
-#ifdef DWARF2_DEBUGGING_INFO
-/* We need special handling in dwarf2out_start_source_file if it is
-   first one.  */
-static int is_main_source;
-#endif
-
 /* A list of DIEs with a NULL parent waiting to be relocated.  */
 static GTY(()) limbo_die_node *limbo_die_list;
 
@@ -3581,10 +3602,10 @@ static void add_dwarf_attr (dw_die_ref, dw_attr_ref);
 static inline enum dw_val_class AT_class (dw_attr_ref);
 static void add_AT_flag (dw_die_ref, enum dwarf_attribute, unsigned);
 static inline unsigned AT_flag (dw_attr_ref);
-static void add_AT_int (dw_die_ref, enum dwarf_attribute, long);
-static inline long int AT_int (dw_attr_ref);
-static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned long);
-static inline unsigned long AT_unsigned (dw_attr_ref);
+static void add_AT_int (dw_die_ref, enum dwarf_attribute, HOST_WIDE_INT);
+static inline HOST_WIDE_INT AT_int (dw_attr_ref);
+static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WIDE_INT);
+static inline unsigned HOST_WIDE_INT AT_unsigned (dw_attr_ref);
 static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long,
                              unsigned long);
 static void add_AT_float (dw_die_ref, enum dwarf_attribute, unsigned, long *);
@@ -3594,6 +3615,7 @@ static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
 static inline const char *AT_string (dw_attr_ref);
 static int AT_string_form (dw_attr_ref);
 static void add_AT_die_ref (dw_die_ref, enum dwarf_attribute, dw_die_ref);
+static void add_AT_specification (dw_die_ref, dw_die_ref);
 static inline dw_die_ref AT_ref (dw_attr_ref);
 static inline int AT_ref_external (dw_attr_ref);
 static inline void set_AT_ref_external (dw_attr_ref, int);
@@ -3607,7 +3629,8 @@ static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx);
 static inline rtx AT_addr (dw_attr_ref);
 static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
 static void add_AT_lbl_offset (dw_die_ref, enum dwarf_attribute, const char *);
-static void add_AT_offset (dw_die_ref, enum dwarf_attribute, unsigned long);
+static void add_AT_offset (dw_die_ref, enum dwarf_attribute,
+                          unsigned HOST_WIDE_INT);
 static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
                               unsigned long);
 static inline const char *AT_lbl (dw_attr_ref);
@@ -3688,8 +3711,8 @@ static void output_file_names (void);
 static dw_die_ref base_type_die (tree);
 static tree root_type (tree);
 static int is_base_type (tree);
-static bool is_ada_subrange_type (tree);
-static dw_die_ref subrange_type_die (tree);
+static bool is_subrange_type (tree);
+static dw_die_ref subrange_type_die (tree, dw_die_ref);
 static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
 static int type_is_enum (tree);
 static unsigned int reg_number (rtx);
@@ -3697,7 +3720,7 @@ static dw_loc_descr_ref reg_loc_descriptor (rtx);
 static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
 static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
 static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
-static dw_loc_descr_ref based_loc_descr (unsigned, long);
+static dw_loc_descr_ref based_loc_descr (unsigned, HOST_WIDE_INT);
 static int is_based_loc (rtx);
 static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
 static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
@@ -3732,7 +3755,7 @@ static void push_decl_scope (tree);
 static void pop_decl_scope (void);
 static dw_die_ref scope_die_for (tree, dw_die_ref);
 static inline int local_scope_p (dw_die_ref);
-static inline int class_scope_p (dw_die_ref);
+static inline int class_or_namespace_scope_p (dw_die_ref);
 static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref);
 static const char *type_tag (tree);
 static tree member_declared_type (tree);
@@ -3747,7 +3770,7 @@ static void gen_entry_point_die (tree, dw_die_ref);
 static void gen_inlined_enumeration_type_die (tree, dw_die_ref);
 static void gen_inlined_structure_type_die (tree, dw_die_ref);
 static void gen_inlined_union_type_die (tree, dw_die_ref);
-static void gen_enumeration_type_die (tree, dw_die_ref);
+static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
 static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref);
 static void gen_unspecified_parameters_die (tree, dw_die_ref);
 static void gen_formal_types_die (tree, dw_die_ref);
@@ -3770,7 +3793,11 @@ static void gen_tagged_type_instantiation_die (tree, dw_die_ref);
 static void gen_block_die (tree, dw_die_ref, int);
 static void decls_for_scope (tree, dw_die_ref, int);
 static int is_redundant_typedef (tree);
+static void gen_namespace_die (tree);
 static void gen_decl_die (tree, dw_die_ref);
+static dw_die_ref force_namespace_die (tree);
+static dw_die_ref setup_namespace_context (tree, dw_die_ref);
+static void declare_in_namespace (tree, dw_die_ref);
 static unsigned lookup_filename (const char *);
 static void init_file_table (void);
 static void retry_incomplete_types (void);
@@ -3860,7 +3887,7 @@ static int maybe_emit_file (int);
 
 /* Definitions of defaults for formats and names of various special
    (artificial) labels which may be generated within this file (when the -g
-   options is used and DWARF_DEBUGGING_INFO is in effect.
+   options is used and DWARF2_DEBUGGING_INFO is in effect.
    If necessary, these may be overridden from within the tm.h file, but
    typically, overriding these defaults is unnecessary.  */
 
@@ -4026,6 +4053,8 @@ dwarf_tag_name (unsigned int tag)
       return "DW_TAG_namelist";
     case DW_TAG_namelist_item:
       return "DW_TAG_namelist_item";
+    case DW_TAG_namespace:
+      return "DW_TAG_namespace";
     case DW_TAG_packed_type:
       return "DW_TAG_packed_type";
     case DW_TAG_subprogram:
@@ -4475,7 +4504,7 @@ AT_flag (dw_attr_ref a)
 /* Add a signed integer attribute value to a DIE.  */
 
 static inline void
-add_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, long int int_val)
+add_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, HOST_WIDE_INT int_val)
 {
   dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
@@ -4486,7 +4515,7 @@ add_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, long int int_val)
   add_dwarf_attr (die, attr);
 }
 
-static inline long int
+static inline HOST_WIDE_INT
 AT_int (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_const)
@@ -4499,7 +4528,7 @@ AT_int (dw_attr_ref a)
 
 static inline void
 add_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind,
-                long unsigned int unsigned_val)
+                unsigned HOST_WIDE_INT unsigned_val)
 {
   dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
@@ -4510,7 +4539,7 @@ add_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind,
   add_dwarf_attr (die, attr);
 }
 
-static inline unsigned long
+static inline unsigned HOST_WIDE_INT
 AT_unsigned (dw_attr_ref a)
 {
   if (a && AT_class (a) == dw_val_class_unsigned_const)
@@ -4658,6 +4687,18 @@ add_AT_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, dw_die_ref targ_
   add_dwarf_attr (die, attr);
 }
 
+/* Add an AT_specification attribute to a DIE, and also make the back
+   pointer from the specification to the definition.  */
+
+static inline void
+add_AT_specification (dw_die_ref die, dw_die_ref targ_die)
+{
+  add_AT_die_ref (die, DW_AT_specification, targ_die);
+  if (targ_die->die_definition)
+    abort ();
+  targ_die->die_definition = die;
+}
+
 static inline dw_die_ref
 AT_ref (dw_attr_ref a)
 {
@@ -4798,7 +4839,8 @@ add_AT_lbl_offset (dw_die_ref die, enum dwarf_attribute attr_kind, const char *l
 /* Add an offset attribute value to a DIE.  */
 
 static inline void
-add_AT_offset (dw_die_ref die, enum dwarf_attribute attr_kind, long unsigned int offset)
+add_AT_offset (dw_die_ref die, enum dwarf_attribute attr_kind,
+              unsigned HOST_WIDE_INT offset)
 {
   dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
@@ -4836,7 +4878,7 @@ AT_lbl (dw_attr_ref a)
 
 /* Get the attribute of type attr_kind.  */
 
-static inline dw_attr_ref
+static dw_attr_ref
 get_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
 {
   dw_attr_ref a;
@@ -5227,10 +5269,10 @@ print_die (dw_die_ref die, FILE *outfile)
          fprintf (outfile, "range list");
          break;
        case dw_val_class_const:
-         fprintf (outfile, "%ld", AT_int (a));
+         fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, AT_int (a));
          break;
        case dw_val_class_unsigned_const:
-         fprintf (outfile, "%lu", AT_unsigned (a));
+         fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, AT_unsigned (a));
          break;
        case dw_val_class_long_long:
          fprintf (outfile, "constant (%lu,%lu)",
@@ -6549,7 +6591,8 @@ output_die (dw_die_ref die)
          {
            char *p = strchr (ranges_section_label, '\0');
 
-           sprintf (p, "+0x%lx", a->dw_attr_val.v.val_offset);
+           sprintf (p, "+" HOST_WIDE_INT_PRINT_HEX,
+                    a->dw_attr_val.v.val_offset);
            dw2_asm_output_offset (DWARF_OFFSET_SIZE, ranges_section_label,
                                   "%s", name);
            *p = '\0';
@@ -7777,33 +7820,56 @@ simple_type_size_in_bits (tree type)
    emitted as a subrange type.  */
 
 static inline bool
-is_ada_subrange_type (tree type)
+is_subrange_type (tree type)
 {
-  /* We do this for INTEGER_TYPEs that have names, parent types, and when
-     we are compiling Ada code.  */
-  return (TREE_CODE (type) == INTEGER_TYPE
-         && TYPE_NAME (type) != 0 && TREE_TYPE (type) != 0
-         && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE
-         && TREE_UNSIGNED (TREE_TYPE (type)) && is_ada ());
+  tree subtype = TREE_TYPE (type);
+
+  if (TREE_CODE (type) == INTEGER_TYPE
+      && subtype != NULL_TREE)
+    {
+      if (TREE_CODE (subtype) == INTEGER_TYPE)
+        return true;
+      if (TREE_CODE (subtype) == ENUMERAL_TYPE)
+        return true;
+    }
+  return false;
 }
 
 /*  Given a pointer to a tree node for a subrange type, return a pointer
     to a DIE that describes the given type.  */
 
 static dw_die_ref
-subrange_type_die (tree type)
+subrange_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref subtype_die;
   dw_die_ref subrange_die;
   tree name = TYPE_NAME (type);
+  const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type);
 
-  subtype_die = base_type_die (TREE_TYPE (type));
+  if (context_die == NULL)
+    context_die = comp_unit_die;
 
-  if (TREE_CODE (name) == TYPE_DECL)
-    name = DECL_NAME (name);
+  if (TREE_CODE (TREE_TYPE (type)) == ENUMERAL_TYPE)
+    subtype_die = gen_enumeration_type_die (TREE_TYPE (type), context_die);
+  else
+    subtype_die = base_type_die (TREE_TYPE (type));
+
+  subrange_die = new_die (DW_TAG_subrange_type, context_die, type);
+
+  if (name != NULL)
+    {
+      if (TREE_CODE (name) == TYPE_DECL)
+        name = DECL_NAME (name);
+      add_name_attribute (subrange_die, IDENTIFIER_POINTER (name));
+    }
+
+  if (int_size_in_bytes (TREE_TYPE (type)) != size_in_bytes)
+    {
+      /* The size of the subrange type and its base type do not match,
+         so we need to generate a size attribute for the subrange type.  */
+      add_AT_unsigned (subrange_die, DW_AT_byte_size, size_in_bytes);
+    }
 
-  subrange_die = new_die (DW_TAG_subrange_type, comp_unit_die, type);
-  add_name_attribute (subrange_die, IDENTIFIER_POINTER (name));
   if (TYPE_MIN_VALUE (type) != NULL)
     add_bound_info (subrange_die, DW_AT_lower_bound,
                     TYPE_MIN_VALUE (type));
@@ -7906,8 +7972,8 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
 #endif
          item_type = TREE_TYPE (type);
        }
-      else if (is_ada_subrange_type (type))
-        mod_type_die = subrange_type_die (type);
+      else if (is_subrange_type (type))
+        mod_type_die = subrange_type_die (type, context_die);
       else if (is_base_type (type))
        mod_type_die = base_type_die (type);
       else
@@ -8101,7 +8167,7 @@ int_loc_descriptor (HOST_WIDE_INT i)
 /* Return a location descriptor that designates a base+offset location.  */
 
 static dw_loc_descr_ref
-based_loc_descr (unsigned int reg, long int offset)
+based_loc_descr (unsigned int reg, HOST_WIDE_INT offset)
 {
   dw_loc_descr_ref loc_result;
   /* For the "frame base", we use the frame pointer or stack pointer
@@ -8475,7 +8541,7 @@ loc_descriptor_from_tree (tree loc, int addressp)
          indirect_p = 1;
          break;
        }
-      /* FALLTHRU */
+      /* Fall through.  */
 
     case PARM_DECL:
       {
@@ -8995,7 +9061,7 @@ add_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind,
 static void
 add_data_member_location_attribute (dw_die_ref die, tree decl)
 {
-  long offset;
+  HOST_WIDE_INT offset;
   dw_loc_descr_ref loc_descr = 0;
 
   if (TREE_CODE (decl) == TREE_VEC)
@@ -9081,28 +9147,13 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
   switch (GET_CODE (rtl))
     {
     case CONST_INT:
-      /* Note that a CONST_INT rtx could represent either an integer
-        or a floating-point constant.  A CONST_INT is used whenever
-        the constant will fit into a single word.  In all such
-        cases, the original mode of the constant value is wiped
-        out, and the CONST_INT rtx is assigned VOIDmode.  */
       {
        HOST_WIDE_INT val = INTVAL (rtl);
 
-       /* ??? We really should be using HOST_WIDE_INT throughout.  */
-       if (val < 0 && (long) val == val)
-         add_AT_int (die, DW_AT_const_value, (long) val);
-       else if ((unsigned long) val == (unsigned HOST_WIDE_INT) val)
-         add_AT_unsigned (die, DW_AT_const_value, (unsigned long) val);
-       else
-         {
-#if HOST_BITS_PER_LONG * 2 == HOST_BITS_PER_WIDE_INT
-           add_AT_long_long (die, DW_AT_const_value,
-                             val >> HOST_BITS_PER_LONG, val);
-#else
-           abort ();
-#endif
-         }
+       if (val < 0)
+         add_AT_int (die, DW_AT_const_value, val);
+       else 
+         add_AT_unsigned (die, DW_AT_const_value, (unsigned HOST_WIDE_INT) val);
       }
       break;
 
@@ -9353,7 +9404,8 @@ rtl_for_decl_location (tree decl)
                                   TREE_STRING_LENGTH (init) - 1) == 0
              && ((size_t) TREE_STRING_LENGTH (init)
                  == strlen (TREE_STRING_POINTER (init)) + 1))
-           rtl = gen_rtx_CONST_STRING (VOIDmode, TREE_STRING_POINTER (init));
+           rtl = gen_rtx_CONST_STRING (VOIDmode,
+                                       ggc_strdup (TREE_STRING_POINTER (init)));
        }
       /* If the initializer is something that we know will expand into an
         immediate RTL constant, expand it now.  Expanding anything else
@@ -9444,6 +9496,33 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl)
       add_AT_location_description (die, DW_AT_location, descr);
       break;
 
+    case PARALLEL:
+      {
+       rtvec par_elems = XVEC (rtl, 0);
+       int num_elem = GET_NUM_ELEM (par_elems);
+       enum machine_mode mode;
+       int i;
+
+       /* Create the first one, so we have something to add to.  */
+       descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
+       mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
+       add_loc_descr (&descr,
+                      new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
+       for (i = 1; i < num_elem; i++)
+         {
+           dw_loc_descr_ref temp;
+
+           temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
+           add_loc_descr (&descr, temp);
+           mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
+           add_loc_descr (&descr,
+                          new_loc_descr (DW_OP_piece,
+                                         GET_MODE_SIZE (mode), 0));
+         }
+      }
+      add_AT_location_description (die, DW_AT_location, descr);
+      break;
+
     default:
       abort ();
     }
@@ -9981,9 +10060,14 @@ scope_die_for (tree t, dw_die_ref context_die)
 
   containing_scope = TYPE_CONTEXT (t);
 
-  /* Ignore namespaces for the moment.  */
+  /* Use the containing namespace if it was passed in (for a declaration).  */
   if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
-    containing_scope = NULL_TREE;
+    {
+      if (context_die == lookup_decl_die (containing_scope))
+       /* OK */;
+      else
+       containing_scope = NULL_TREE;
+    }
 
   /* Ignore function type "scopes" from the C frontend.  They mean that
      a tagged type is local to a parmlist of a function declarator, but
@@ -10033,14 +10117,16 @@ local_scope_p (dw_die_ref context_die)
   return 0;
 }
 
-/* Returns nonzero if CONTEXT_DIE is a class.  */
+/* Returns nonzero if CONTEXT_DIE is a class or namespace, for deciding
+   whether or not to treat a DIE in this context as a declaration.  */
 
 static inline int
-class_scope_p (dw_die_ref context_die)
+class_or_namespace_scope_p (dw_die_ref context_die)
 {
   return (context_die
          && (context_die->die_tag == DW_TAG_structure_type
-             || context_die->die_tag == DW_TAG_union_type));
+             || context_die->die_tag == DW_TAG_union_type
+             || context_die->die_tag == DW_TAG_namespace));
 }
 
 /* Many forms of DIEs require a "type description" attribute.  This
@@ -10188,7 +10274,7 @@ gen_array_type_die (tree type, dw_die_ref context_die)
   /* The SGI compilers handle arrays of unknown bound by setting
      AT_declaration and not emitting any subrange DIEs.  */
   if (! TYPE_DOMAIN (type))
-    add_AT_unsigned (array_die, DW_AT_declaration, 1);
+    add_AT_flag (array_die, DW_AT_declaration, 1);
   else
 #endif
     add_subscript_info (array_die, type);
@@ -10296,7 +10382,7 @@ gen_inlined_union_type_die (tree type, dw_die_ref context_die)
    enumerated type name/value is listed as a child of the enumerated type
    DIE.  */
 
-static void
+static dw_die_ref
 gen_enumeration_type_die (tree type, dw_die_ref context_die)
 {
   dw_die_ref type_die = lookup_type_die (type);
@@ -10309,7 +10395,7 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
       add_name_attribute (type_die, type_tag (type));
     }
   else if (! TYPE_SIZE (type))
-    return;
+    return type_die;
   else
     remove_AT (type_die, DW_AT_declaration);
 
@@ -10352,6 +10438,8 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
     }
   else
     add_AT_flag (type_die, DW_AT_declaration, 1);
+
+  return type_die;
 }
 
 /* Generate a DIE to represent either a real live formal parameter decl or to
@@ -10520,7 +10608,7 @@ dwarf2out_abstract_function (tree decl)
   decl = DECL_ORIGIN (decl);
 
   old_die = lookup_decl_die (decl);
-  if (old_die && get_AT_unsigned (old_die, DW_AT_inline))
+  if (old_die && get_AT (old_die, DW_AT_inline))
     /* We've already generated the abstract instance.  */
     return;
 
@@ -10560,7 +10648,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
   tree outer_scope;
   dw_die_ref old_die = lookup_decl_die (decl);
   int declaration = (current_function_decl != decl
-                    || class_scope_p (context_die));
+                    || class_or_namespace_scope_p (context_die));
 
   /* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we
      started to generate the abstract instance of an inline, decided to output
@@ -10569,7 +10657,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
      we'll get back to the abstract instance when done with the class.  */
 
   /* The class-scope declaration DIE must be the primary DIE.  */
-  if (origin && declaration && class_scope_p (context_die))
+  if (origin && declaration && class_or_namespace_scope_p (context_die))
     {
       origin = NULL;
       if (old_die)
@@ -10597,7 +10685,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
          /* We can have a normal definition following an inline one in the
             case of redefinition of GNU C extern inlines.
             It seems reasonable to use AT_specification in this case.  */
-         && !get_AT_unsigned (old_die, DW_AT_inline))
+         && !get_AT (old_die, DW_AT_inline))
        {
          /* ??? This can happen if there is a bug in the program, for
             instance, if it has duplicate function definitions.  Ideally,
@@ -10631,7 +10719,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
       else
        {
          subr_die = new_die (DW_TAG_subprogram, context_die, decl);
-         add_AT_die_ref (subr_die, DW_AT_specification, old_die);
+         add_AT_specification (subr_die, old_die);
          if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index)
            add_AT_unsigned (subr_die, DW_AT_decl_file, file_index);
          if (get_AT_unsigned (old_die, DW_AT_decl_line)
@@ -10667,7 +10755,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
 
   if (declaration)
     {
-      if (!old_die || !get_AT_unsigned (old_die, DW_AT_inline))
+      if (!old_die || !get_AT (old_die, DW_AT_inline))
        {
          add_AT_flag (subr_die, DW_AT_declaration, 1);
 
@@ -10681,26 +10769,26 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
     }
   else if (DECL_ABSTRACT (decl))
     {
-      if (DECL_INLINE (decl) && !flag_no_inline)
+      if (DECL_DECLARED_INLINE_P (decl))
        {
-         /* ??? Checking DECL_DEFER_OUTPUT is correct for static
-            inline functions, but not for extern inline functions.
-            We can't get this completely correct because information
-            about whether the function was declared inline is not
-            saved anywhere.  */
-         if (DECL_DEFER_OUTPUT (decl))
+          if (cgraph_function_possibly_inlined_p (decl))
            add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_inlined);
          else
-           add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined);
+           add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
        }
       else
-       add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
+       {
+         if (cgraph_function_possibly_inlined_p (decl))
+            add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined);
+         else
+            add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_not_inlined);
+       }
 
       equate_decl_number_to_die (decl, subr_die);
     }
   else if (!DECL_EXTERNAL (decl))
     {
-      if (!old_die || !get_AT_unsigned (old_die, DW_AT_inline))
+      if (!old_die || !get_AT (old_die, DW_AT_inline))
        equate_decl_number_to_die (decl, subr_die);
 
       ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_BEGIN_LABEL,
@@ -10834,7 +10922,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
 
   dw_die_ref old_die = lookup_decl_die (decl);
   int declaration = (DECL_EXTERNAL (decl)
-                    || class_scope_p (context_die));
+                    || class_or_namespace_scope_p (context_die));
 
   if (origin != NULL)
     add_abstract_origin_attribute (var_die, origin);
@@ -10851,7 +10939,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
           && get_AT_flag (old_die, DW_AT_declaration) == 1)
     {
       /* This is a definition of a C++ class level static.  */
-      add_AT_die_ref (var_die, DW_AT_specification, old_die);
+      add_AT_specification (var_die, old_die);
       if (DECL_NAME (decl))
        {
          unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
@@ -10887,7 +10975,7 @@ gen_variable_die (tree decl, dw_die_ref context_die)
   if (declaration)
     add_AT_flag (var_die, DW_AT_declaration, 1);
 
-  if (class_scope_p (context_die) || DECL_ABSTRACT (decl))
+  if (class_or_namespace_scope_p (context_die) || DECL_ABSTRACT (decl))
     equate_decl_number_to_die (decl, var_die);
 
   if (! declaration && ! DECL_ABSTRACT (decl))
@@ -10918,14 +11006,15 @@ gen_label_die (tree decl, dw_die_ref context_die)
     equate_decl_number_to_die (decl, lbl_die);
   else
     {
-      insn = DECL_RTL (decl);
+      insn = DECL_RTL_IF_SET (decl);
 
       /* Deleted labels are programmer specified labels which have been
         eliminated because of various optimizations.  We still emit them
         here so that it is possible to put breakpoints on them.  */
-      if (GET_CODE (insn) == CODE_LABEL
-         || ((GET_CODE (insn) == NOTE
-              && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
+      if (insn
+         && (GET_CODE (insn) == CODE_LABEL
+             || ((GET_CODE (insn) == NOTE
+                  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))))
        {
          /* When optimization is enabled (via -O) some parts of the compiler
             (e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which
@@ -11276,12 +11365,14 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
   int complete = (TYPE_SIZE (type)
                  && (! TYPE_STUB_DECL (type)
                      || ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
+  int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace);
 
   if (type_die && ! complete)
     return;
 
   if (TYPE_CONTEXT (type) != NULL_TREE
-      && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)))
+      && (AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
+         || TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL))
     nested = 1;
 
   scope_die = scope_die_for (type, context_die);
@@ -11296,7 +11387,7 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
                          scope_die, type);
       equate_type_number_to_die (type, type_die);
       if (old_die)
-       add_AT_die_ref (type_die, DW_AT_specification, old_die);
+       add_AT_specification (type_die, old_die);
       else
        add_name_attribute (type_die, type_tag (type));
     }
@@ -11305,7 +11396,7 @@ gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
 
   /* If this type has been completed, then give it a byte_size attribute and
      then give a list of members.  */
-  if (complete)
+  if (complete && !ns_decl)
     {
       /* Prevent infinite recursion in cases where the type of some member of
         this type is expressed in terms of this type itself.  */
@@ -11530,7 +11621,10 @@ gen_type_die (tree type, dw_die_ref context_die)
          need_pop = 1;
        }
       else
-       need_pop = 0;
+       {
+         declare_in_namespace (type, context_die);
+         need_pop = 0;
+       }
 
       if (TREE_CODE (type) == ENUMERAL_TYPE)
        gen_enumeration_type_die (type, context_die);
@@ -11763,6 +11857,98 @@ is_redundant_typedef (tree decl)
   return 0;
 }
 
+/* Returns the DIE for namespace NS or aborts.
+
+   Note that namespaces don't really have a lexical context, so there's no
+   need to pass in a context_die.  They always go inside their containing
+   namespace, or comp_unit_die if none.  */
+
+static dw_die_ref
+force_namespace_die (tree ns)
+{
+  dw_die_ref ns_die;
+
+  dwarf2out_decl (ns);
+  ns_die = lookup_decl_die (ns);
+  if (!ns_die)
+    abort();
+
+  return ns_die;
+}
+
+/* Force out any required namespaces to be able to output DECL,
+   and return the new context_die for it, if it's changed.  */
+
+static dw_die_ref
+setup_namespace_context (tree thing, dw_die_ref context_die)
+{
+  tree context = DECL_P (thing) ? DECL_CONTEXT (thing) : TYPE_CONTEXT (thing);
+  if (context && TREE_CODE (context) == NAMESPACE_DECL)
+    /* Force out the namespace.  */
+    context_die = force_namespace_die (context);
+
+  return context_die;
+}
+
+/* Emit a declaration DIE for THING (which is either a DECL or a tagged
+   type) within its namespace, if appropriate.
+
+   For compatibility with older debuggers, namespace DIEs only contain
+   declarations; all definitions are emitted at CU scope.  */
+
+static void
+declare_in_namespace (tree thing, dw_die_ref context_die)
+{
+  dw_die_ref ns_context;
+
+  if (debug_info_level <= DINFO_LEVEL_TERSE)
+    return;
+
+  ns_context = setup_namespace_context (thing, context_die);
+
+  if (ns_context != context_die)
+    {
+      if (DECL_P (thing))
+       gen_decl_die (thing, ns_context);
+      else
+       gen_type_die (thing, ns_context);
+    }
+}
+
+/* Generate a DIE for a namespace or namespace alias.  */
+
+static void
+gen_namespace_die (tree decl)
+{
+  dw_die_ref context_die = setup_namespace_context (decl, comp_unit_die);
+
+  /* Namespace aliases have a DECL_ABSTRACT_ORIGIN of the namespace
+     they are an alias of.  */
+  if (DECL_ABSTRACT_ORIGIN (decl) == NULL)
+    {
+      /* Output a real namespace.  */
+      dw_die_ref namespace_die
+       = new_die (DW_TAG_namespace, context_die, decl);
+      add_name_and_src_coords_attributes (namespace_die, decl);
+      equate_decl_number_to_die (decl, namespace_die);
+    }
+  else
+    {
+      /* Output a namespace alias.  */
+
+      /* Force out the namespace we are an alias of, if necessary.  */
+      dw_die_ref origin_die
+       = force_namespace_die (DECL_ABSTRACT_ORIGIN (decl));
+
+      /* Now create the namespace alias DIE.  */
+      dw_die_ref namespace_die
+       = new_die (DW_TAG_imported_declaration, context_die, decl);
+      add_name_and_src_coords_attributes (namespace_die, decl);
+      add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
+      equate_decl_number_to_die (decl, namespace_die);
+    }
+}
+
 /* Generate Dwarf debug information for a decl described by DECL.  */
 
 static void
@@ -11796,8 +11982,9 @@ gen_decl_die (tree decl, dw_die_ref context_die)
 
       /* If we're emitting an out-of-line copy of an inline function,
         emit info for the abstract instance and set up to refer to it.  */
-      else if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl)
-              && ! class_scope_p (context_die)
+      else if (cgraph_function_possibly_inlined_p (decl)
+              && ! DECL_ABSTRACT (decl)
+              && ! class_or_namespace_scope_p (context_die)
               /* dwarf2out_abstract_function won't emit a die if this is just
                  a declaration.  We must avoid setting DECL_ABSTRACT_ORIGIN in
                  that case, because that works only if we have a die.  */
@@ -11822,6 +12009,9 @@ gen_decl_die (tree decl, dw_die_ref context_die)
          origin = decl_class_context (decl);
          if (origin != NULL_TREE)
            gen_type_die_for_member (origin, decl, context_die);
+
+         /* And its containing namespace.  */
+         declare_in_namespace (decl, context_die);
        }
 
       /* Now output a DIE to represent the function itself.  */
@@ -11873,6 +12063,9 @@ gen_decl_die (tree decl, dw_die_ref context_die)
       if (origin != NULL_TREE)
        gen_type_die_for_member (origin, decl, context_die);
 
+      /* And its containing namespace.  */
+      declare_in_namespace (decl, context_die);
+
       /* Now output the DIE to represent the data object itself.  This gets
         complicated because of the possibility that the VAR_DECL really
         represents an inlined instance of a formal parameter for an inline
@@ -11901,7 +12094,7 @@ gen_decl_die (tree decl, dw_die_ref context_die)
       break;
 
     case NAMESPACE_DECL:
-      /* Ignore for now.  */
+      gen_namespace_die (decl);
       break;
 
     default:
@@ -12024,6 +12217,13 @@ dwarf2out_decl (tree decl)
        return;
       break;
 
+    case NAMESPACE_DECL:
+      if (debug_info_level <= DINFO_LEVEL_TERSE)
+       return;
+      if (lookup_decl_die (decl) != NULL)
+        return;
+      break;
+
     case TYPE_DECL:
       /* Don't emit stubs for types unless they are needed by other DIEs.  */
       if (TYPE_DECL_SUPPRESS_DEBUG (decl))
@@ -12275,7 +12475,7 @@ dwarf2out_source_line (unsigned int line, const char *filename)
 static void
 dwarf2out_start_source_file (unsigned int lineno, const char *filename)
 {
-  if (flag_eliminate_dwarf2_dups && !is_main_source)
+  if (flag_eliminate_dwarf2_dups)
     {
       /* Record the beginning of the file for break_out_includes.  */
       dw_die_ref bincl_die;
@@ -12284,8 +12484,6 @@ dwarf2out_start_source_file (unsigned int lineno, const char *filename)
       add_AT_string (bincl_die, DW_AT_name, filename);
     }
 
-  is_main_source = 0;
-
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
       named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
@@ -12386,7 +12584,6 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
      invoked when the given (base) source file was compiled.  We will fill
      in this value in dwarf2out_finish.  */
   comp_unit_die = gen_compile_unit_die (NULL);
-  is_main_source = 1;
 
   VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
 
@@ -12507,6 +12704,11 @@ prune_unused_types_mark (dw_die_ref die, int dokids)
 
       /* Mark any referenced nodes.  */
       prune_unused_types_walk_attribs (die);
+
+      /* If this node is a specification,
+         also mark the definition, if it exists.  */
+      if (get_AT_flag (die, DW_AT_declaration) && die->die_definition)
+        prune_unused_types_mark (die->die_definition, 1);
     }
 
   if (dokids && die->die_mark != 2)