OSDN Git Service

Avoid emitting bogus debug info that confuses gdb.
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 0ad5ce3..c32c545 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, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2005 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).
@@ -253,6 +253,11 @@ typedef struct dw_fde_struct GTY(())
   const char *dw_fde_begin;
   const char *dw_fde_current_label;
   const char *dw_fde_end;
+  const char *dw_fde_hot_section_label;
+  const char *dw_fde_hot_section_end_label;
+  const char *dw_fde_unlikely_section_label;
+  const char *dw_fde_unlikely_section_end_label;
+  bool dw_fde_switched_sections;
   dw_cfi_ref dw_fde_cfi;
   unsigned funcdef_number;
   unsigned all_throwers_are_sibcalls : 1;
@@ -2273,17 +2278,57 @@ output_call_frame_info (int for_eh)
          dw2_asm_output_encoded_addr_rtx (fde_encoding,
                                           sym_ref,
                                           "FDE initial location");
-         dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
-                               fde->dw_fde_end, fde->dw_fde_begin,
-                               "FDE address range");
+         if (fde->dw_fde_switched_sections)
+           {
+             rtx sym_ref2 = gen_rtx_SYMBOL_REF (Pmode, 
+                                     fde->dw_fde_unlikely_section_label);
+             rtx sym_ref3= gen_rtx_SYMBOL_REF (Pmode, 
+                                     fde->dw_fde_hot_section_label);
+             SYMBOL_REF_FLAGS (sym_ref2) |= SYMBOL_FLAG_LOCAL;
+             SYMBOL_REF_FLAGS (sym_ref3) |= SYMBOL_FLAG_LOCAL;
+             dw2_asm_output_encoded_addr_rtx (fde_encoding, sym_ref3,
+                                              "FDE initial location");
+             dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
+                                   fde->dw_fde_hot_section_end_label,
+                                   fde->dw_fde_hot_section_label,
+                                   "FDE address range");
+             dw2_asm_output_encoded_addr_rtx (fde_encoding, sym_ref2,
+                                              "FDE initial location");
+             dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
+                                   fde->dw_fde_unlikely_section_end_label,
+                                   fde->dw_fde_unlikely_section_label,
+                                   "FDE address range");
+           }
+         else
+           dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
+                                 fde->dw_fde_end, fde->dw_fde_begin,
+                                 "FDE address range");
        }
       else
        {
          dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin,
                               "FDE initial location");
-         dw2_asm_output_delta (DWARF2_ADDR_SIZE,
-                               fde->dw_fde_end, fde->dw_fde_begin,
-                               "FDE address range");
+         if (fde->dw_fde_switched_sections)
+           {
+             dw2_asm_output_addr (DWARF2_ADDR_SIZE,
+                                  fde->dw_fde_hot_section_label,
+                                  "FDE initial location");
+             dw2_asm_output_delta (DWARF2_ADDR_SIZE,
+                                   fde->dw_fde_hot_section_end_label,
+                                   fde->dw_fde_hot_section_label,
+                                   "FDE address range");
+             dw2_asm_output_addr (DWARF2_ADDR_SIZE,
+                                  fde->dw_fde_unlikely_section_label,
+                                  "FDE initial location");
+             dw2_asm_output_delta (DWARF2_ADDR_SIZE, 
+                                   fde->dw_fde_unlikely_section_end_label,
+                                   fde->dw_fde_unlikely_section_label,
+                                   "FDE address range");
+           }
+         else
+           dw2_asm_output_delta (DWARF2_ADDR_SIZE,
+                                 fde->dw_fde_end, fde->dw_fde_begin,
+                                 "FDE address range");
        }
 
       if (augmentation[0])
@@ -2409,6 +2454,11 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   fde->decl = current_function_decl;
   fde->dw_fde_begin = dup_label;
   fde->dw_fde_current_label = NULL;
+  fde->dw_fde_hot_section_label = NULL;
+  fde->dw_fde_hot_section_end_label = NULL;
+  fde->dw_fde_unlikely_section_label = NULL;
+  fde->dw_fde_unlikely_section_end_label = NULL;
+  fde->dw_fde_switched_sections = false;
   fde->dw_fde_end = NULL;
   fde->dw_fde_cfi = NULL;
   fde->funcdef_number = current_function_funcdef_no;
@@ -2468,7 +2518,12 @@ void
 dwarf2out_frame_finish (void)
 {
   /* Output call frame information.  */
-  if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
+  if (write_symbols == DWARF2_DEBUG
+      || write_symbols == VMS_AND_DWARF2_DEBUG
+#ifdef DWARF2_FRAME_INFO
+      || DWARF2_FRAME_INFO
+#endif
+      )
     output_call_frame_info (0);
 
 #ifndef TARGET_UNWIND_INFO
@@ -3413,6 +3468,7 @@ static void dwarf2out_imported_module_or_decl (tree, tree);
 static void dwarf2out_abstract_function (tree);
 static void dwarf2out_var_location (rtx);
 static void dwarf2out_begin_function (tree);
+static void dwarf2out_switch_text_section (void);
 
 /* The debug hooks structure.  */
 
@@ -3444,7 +3500,9 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
   dwarf2out_abstract_function, /* outlining_inline_function */
   debug_nothing_rtx,           /* label */
   debug_nothing_int,           /* handle_pch */
-  dwarf2out_var_location
+  dwarf2out_var_location,
+  dwarf2out_switch_text_section,
+  1                             /* start_end_main_source_file */
 };
 #endif
 \f
@@ -3645,6 +3703,7 @@ struct var_loc_node GTY ((chain_next ("%h.next")))
 {
   rtx GTY (()) var_loc_note;
   const char * GTY (()) label;
+  const char * GTY (()) section_label;
   struct var_loc_node * GTY (()) next;
 };
 
@@ -3778,9 +3837,6 @@ static int is_tagged_type (tree);
 static const char *dwarf_tag_name (unsigned);
 static const char *dwarf_attr_name (unsigned);
 static const char *dwarf_form_name (unsigned);
-#if 0
-static const char *dwarf_type_encoding_name (unsigned);
-#endif
 static tree decl_ultimate_origin (tree);
 static tree block_ultimate_origin (tree);
 static tree decl_class_context (tree);
@@ -4117,7 +4173,7 @@ static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES];
 #endif
 \f
 /* We allow a language front-end to designate a function that is to be
-   called to "demangle" any name before it it put into a DIE.  */
+   called to "demangle" any name before it is put into a DIE.  */
 
 static const char *(*demangle_name_func) (const char *);
 
@@ -4548,36 +4604,6 @@ dwarf_form_name (unsigned int form)
       return "DW_FORM_<unknown>";
     }
 }
-
-/* Convert a DWARF type code into its string name.  */
-
-#if 0
-static const char *
-dwarf_type_encoding_name (unsigned enc)
-{
-  switch (enc)
-    {
-    case DW_ATE_address:
-      return "DW_ATE_address";
-    case DW_ATE_boolean:
-      return "DW_ATE_boolean";
-    case DW_ATE_complex_float:
-      return "DW_ATE_complex_float";
-    case DW_ATE_float:
-      return "DW_ATE_float";
-    case DW_ATE_signed:
-      return "DW_ATE_signed";
-    case DW_ATE_signed_char:
-      return "DW_ATE_signed_char";
-    case DW_ATE_unsigned:
-      return "DW_ATE_unsigned";
-    case DW_ATE_unsigned_char:
-      return "DW_ATE_unsigned_char";
-    default:
-      return "DW_ATE_<unknown>";
-    }
-}
-#endif
 \f
 /* Determine the "ultimate origin" of a decl.  The decl may be an inlined
    instance of an inlined instance of a decl which is local to an inline
@@ -6769,6 +6795,20 @@ add_loc_descr_to_loc_list (dw_loc_list_ref *list_head, dw_loc_descr_ref descr,
   *d = new_loc_list (descr, begin, end, section, 0);
 }
 
+static void
+dwarf2out_switch_text_section (void)
+{
+  dw_fde_ref fde;
+
+  fde = &fde_table[fde_table_in_use - 1];
+  fde->dw_fde_switched_sections = true;
+  fde->dw_fde_hot_section_label = xstrdup (hot_section_label);
+  fde->dw_fde_hot_section_end_label = xstrdup (hot_section_end_label);
+  fde->dw_fde_unlikely_section_label = xstrdup (unlikely_section_label);
+  fde->dw_fde_unlikely_section_end_label = xstrdup (cold_section_end_label);
+  separate_line_info_table_in_use++;
+}
+
 /* Output the location list given to us.  */
 
 static void
@@ -7195,8 +7235,14 @@ output_aranges (void)
     }
 
   dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_section_label, "Address");
-  dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
-                       text_section_label, "Length");
+  if (last_text_section == in_unlikely_executed_text
+      || (last_text_section == in_named
+         && last_text_section_name == unlikely_text_section_name))
+    dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
+                         unlikely_section_label, "Length");
+  else
+    dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
+                         text_section_label, "Length");
 
   for (i = 0; i < arange_table_in_use; i++)
     {
@@ -7286,11 +7332,24 @@ output_ranges (void)
             base of the text section.  */
          if (separate_line_info_table_in_use == 0)
            {
-             dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
-                                   text_section_label,
-                                   fmt, i * 2 * DWARF2_ADDR_SIZE);
-             dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
-                                   text_section_label, NULL);
+             if (last_text_section == in_unlikely_executed_text
+                 || (last_text_section == in_named
+                     && last_text_section_name == unlikely_text_section_name))
+               {
+                 dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
+                                       unlikely_section_label,
+                                       fmt, i * 2 * DWARF2_ADDR_SIZE);
+                 dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
+                                       unlikely_section_label, NULL);
+               }
+             else
+               {
+                 dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
+                                       text_section_label,
+                                       fmt, i * 2 * DWARF2_ADDR_SIZE);
+                 dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
+                                       text_section_label, NULL);
+               }
            }
 
          /* Otherwise, we add a DW_AT_entry_pc attribute to force the
@@ -7675,7 +7734,13 @@ output_line_info (void)
      a series of state machine operations.  */
   current_file = 1;
   current_line = 1;
-  strcpy (prev_line_label, text_section_label);
+  
+  if (last_text_section == in_unlikely_executed_text
+      || (last_text_section == in_named
+         && last_text_section_name == unlikely_text_section_name))
+    strcpy (prev_line_label, unlikely_section_label);
+  else
+    strcpy (prev_line_label, text_section_label);
   for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
     {
       dw_line_info_ref line_info = &line_info_table[lt_index];
@@ -8048,7 +8113,6 @@ is_base_type (tree type)
     case METHOD_TYPE:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
-    case FILE_TYPE:
     case OFFSET_TYPE:
     case LANG_TYPE:
     case VECTOR_TYPE:
@@ -8714,8 +8778,8 @@ static dw_loc_descr_ref
 concat_loc_descriptor (rtx x0, rtx x1)
 {
   dw_loc_descr_ref cc_loc_result = NULL;
-  dw_loc_descr_ref x0_ref = loc_descriptor (x0, true);
-  dw_loc_descr_ref x1_ref = loc_descriptor (x1, true);
+  dw_loc_descr_ref x0_ref = loc_descriptor (x0, false);
+  dw_loc_descr_ref x1_ref = loc_descriptor (x1, false);
 
   if (x0_ref == 0 || x1_ref == 0)
     return 0;
@@ -8934,7 +8998,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
 
            /* Certain constructs can only be represented at top-level.  */
            if (want_address == 2)
-             return loc_descriptor (rtl, true);
+             return loc_descriptor (rtl, false);
 
            mode = GET_MODE (rtl);
            if (MEM_P (rtl))
@@ -8942,7 +9006,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
                rtl = XEXP (rtl, 0);
                have_address = 1;
              }
-           ret = mem_loc_descriptor (rtl, mode, true);
+           ret = mem_loc_descriptor (rtl, mode, false);
          }
       }
       break;
@@ -9021,7 +9085,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
          return 0;
        mode = GET_MODE (rtl);
        rtl = XEXP (rtl, 0);
-       ret = mem_loc_descriptor (rtl, mode, true);
+       ret = mem_loc_descriptor (rtl, mode, false);
        have_address = 1;
        break;
       }
@@ -9729,6 +9793,53 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
 
 }
 
+/* Generate an RTL constant from a decl initializer INIT with decl type TYPE,
+   for use in a later add_const_value_attribute call.  */
+
+static rtx
+rtl_for_decl_init (tree init, tree type)
+{
+  rtx rtl = NULL_RTX;
+
+  /* If a variable is initialized with a string constant without embedded
+     zeros, build CONST_STRING.  */
+  if (TREE_CODE (init) == STRING_CST && TREE_CODE (type) == ARRAY_TYPE)
+    {
+      tree enttype = TREE_TYPE (type);
+      tree domain = TYPE_DOMAIN (type);
+      enum machine_mode mode = TYPE_MODE (enttype);
+
+      if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) == 1
+         && domain
+         && integer_zerop (TYPE_MIN_VALUE (domain))
+         && compare_tree_int (TYPE_MAX_VALUE (domain),
+                              TREE_STRING_LENGTH (init) - 1) == 0
+         && ((size_t) TREE_STRING_LENGTH (init)
+             == strlen (TREE_STRING_POINTER (init)) + 1))
+       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
+     tends to produce unresolved symbols; see debug/5770 and c++/6381.  */
+  /* Aggregate, vector, and complex types may contain constructors that may
+     result in code being generated when expand_expr is called, so we can't
+     handle them here.  Integer and float are useful and safe types to handle
+     here.  */
+  else if ((INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type))
+          && initializer_constant_valid_p (init, type) == null_pointer_node)
+    {
+      rtl = expand_expr (init, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
+
+      /* If expand_expr returns a MEM, it wasn't immediate.  */
+      gcc_assert (!rtl || !MEM_P (rtl));
+    }
+
+  return rtl;
+}
+
+/* Generate RTL for the variable DECL to represent its location.  */
+
 static rtx
 rtl_for_decl_location (tree decl)
 {
@@ -9924,40 +10035,7 @@ rtl_for_decl_location (tree decl)
      and will have been substituted directly into all expressions that use it.
      C does not have such a concept, but C++ and other languages do.  */
   else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
-    {
-      /* If a variable is initialized with a string constant without embedded
-        zeros, build CONST_STRING.  */
-      if (TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
-         && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
-       {
-         tree arrtype = TREE_TYPE (decl);
-         tree enttype = TREE_TYPE (arrtype);
-         tree domain = TYPE_DOMAIN (arrtype);
-         tree init = DECL_INITIAL (decl);
-         enum machine_mode mode = TYPE_MODE (enttype);
-
-         if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE_SIZE (mode) == 1
-             && domain
-             && integer_zerop (TYPE_MIN_VALUE (domain))
-             && compare_tree_int (TYPE_MAX_VALUE (domain),
-                                  TREE_STRING_LENGTH (init) - 1) == 0
-             && ((size_t) TREE_STRING_LENGTH (init)
-                 == strlen (TREE_STRING_POINTER (init)) + 1))
-           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
-        tends to produce unresolved symbols; see debug/5770 and c++/6381.  */
-      else if (TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST
-              || TREE_CODE (DECL_INITIAL (decl)) == REAL_CST)
-       {
-         rtl = expand_expr (DECL_INITIAL (decl), NULL_RTX, VOIDmode,
-                            EXPAND_INITIALIZER);
-         /* If expand_expr returns a MEM, it wasn't immediate.  */
-         gcc_assert (!rtl || !MEM_P (rtl));
-       }
-    }
+    rtl = rtl_for_decl_init (DECL_INITIAL (decl), TREE_TYPE (decl));
 
   if (rtl)
     rtl = targetm.delegitimize_address (rtl);
@@ -9971,6 +10049,29 @@ rtl_for_decl_location (tree decl)
   return rtl;
 }
 
+/* Return true if DECL's containing function has a frame base attribute.
+   Return false otherwise.  */
+
+static bool
+containing_function_has_frame_base (tree decl)
+{
+  tree declcontext = decl_function_context (decl);
+  dw_die_ref context;
+  dw_attr_ref attr;
+  
+  if (!declcontext)
+    return false;
+
+  context = lookup_decl_die (declcontext);
+  if (!context)
+    return false;
+
+  for (attr = context->die_attr; attr; attr = attr->dw_attr_next)
+    if (attr->dw_attr == DW_AT_frame_base)
+      return true;
+  return false;
+}
+  
 /* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
    data attribute for a variable or a parameter.  We generate the
    DW_AT_const_value attribute only in those cases where the given variable
@@ -9989,12 +10090,15 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
   rtx rtl;
   dw_loc_descr_ref descr;
   var_loc_list *loc_list;
-
+  bool can_use_fb;
+  struct var_loc_node *node;
   if (TREE_CODE (decl) == ERROR_MARK)
     return;
 
   gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
              || TREE_CODE (decl) == RESULT_DECL);
+            
+  can_use_fb = containing_function_has_frame_base (decl);
 
   /* See if we possibly have multiple locations for this variable.  */
   loc_list = lookup_decl_loc (decl);
@@ -10007,7 +10111,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
       const char *endname;
       dw_loc_list_ref list;
       rtx varloc;
-      struct var_loc_node *node;
+
 
       /* We need to figure out what section we should use as the base
         for the address ranges where a given location is valid.
@@ -10030,6 +10134,10 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
          tree sectree = DECL_SECTION_NAME (current_function_decl);
          secname = TREE_STRING_POINTER (sectree);
        }
+      else if (last_text_section == in_unlikely_executed_text
+              || (last_text_section == in_named
+                  && last_text_section_name == unlikely_text_section_name))
+       secname = unlikely_section_label;
       else
        secname = text_section_label;
 
@@ -10046,7 +10154,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
 
       node = loc_list->first;
       varloc = NOTE_VAR_LOCATION (node->var_loc_note);
-      list = new_loc_list (loc_descriptor (varloc, attr != DW_AT_frame_base),
+      list = new_loc_list (loc_descriptor (varloc, can_use_fb),
                           node->label, node->next->label, secname, 1);
       node = node->next;
 
@@ -10058,7 +10166,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
            varloc = NOTE_VAR_LOCATION (node->var_loc_note);
            add_loc_descr_to_loc_list (&list,
                                       loc_descriptor (varloc,
-                                                      attr != DW_AT_frame_base),
+                                                      can_use_fb),
                                       node->label, node->next->label, secname);
          }
 
@@ -10079,7 +10187,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
            }
          add_loc_descr_to_loc_list (&list,
                                     loc_descriptor (varloc,
-                                                    attr != DW_AT_frame_base),
+                                                    can_use_fb),
                                     node->label, endname, secname);
        }
 
@@ -10088,16 +10196,36 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
       return;
     }
 
+  /* Try to get some constant RTL for this decl, and use that as the value of
+     the location.  */
+  
   rtl = rtl_for_decl_location (decl);
   if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING))
     {
       add_const_value_attribute (die, rtl);
       return;
     }
-
+  
+  /* We couldn't get any rtl, and we had no >1 element location list, so try
+     directly generating the location description from the tree.  */
   descr = loc_descriptor_from_tree (decl);
   if (descr)
-    add_AT_location_description (die, attr, descr);
+    {
+      add_AT_location_description (die, attr, descr);
+      return;
+    }
+  
+  /* Lastly, if we have tried to generate the location otherwise, and it
+     didn't work out (we wouldn't be here if we did), and we have a one entry
+     location list, try generating a location from that.  */
+  if (loc_list && loc_list->first)
+    {
+      node = loc_list->first;
+      descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note), 
+                             can_use_fb);
+      if (descr)
+       add_AT_location_description (die, attr, descr);
+    }
 }
 
 /* If we don't have a copy of this variable in memory for some reason (such
@@ -10109,27 +10237,16 @@ tree_add_const_value_attribute (dw_die_ref var_die, tree decl)
 {
   tree init = DECL_INITIAL (decl);
   tree type = TREE_TYPE (decl);
+  rtx rtl;
 
-  if (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl) && init
-      && initializer_constant_valid_p (init, type) == null_pointer_node)
+  if (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl) && init)
     /* OK */;
   else
     return;
 
-  switch (TREE_CODE (type))
-    {
-    case INTEGER_TYPE:
-      if (host_integerp (init, 0))
-       add_AT_unsigned (var_die, DW_AT_const_value,
-                        tree_low_cst (init, 0));
-      else
-       add_AT_long_long (var_die, DW_AT_const_value,
-                         TREE_INT_CST_HIGH (init),
-                         TREE_INT_CST_LOW (init));
-      break;
-
-    default:;
-    }
+  rtl = rtl_for_decl_init (init, type);
+  if (rtl)
+    add_const_value_attribute (var_die, rtl);
 }
 
 /* Generate a DW_AT_name attribute given some string value to be included as
@@ -10451,7 +10568,7 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin)
 
       if (TYPE_P (fn))
        fn = TYPE_STUB_DECL (fn);
-
+      
       fn = decl_function_context (fn);
       if (fn)
        dwarf2out_abstract_function (fn);
@@ -10462,9 +10579,17 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin)
   else if (TYPE_P (origin))
     origin_die = lookup_type_die (origin);
 
-  gcc_assert (origin_die);
+  /* XXX: Functions that are never lowered don't always have correct block
+     trees (in the case of java, they simply have no block tree, in some other
+     languages).  For these functions, there is nothing we can really do to
+     output correct debug info for inlined functions in all cases.  Rather
+     than abort, we'll just produce deficient debug info now, in that we will
+     have variables without a proper abstract origin.  In the future, when all
+     functions are lowered, we should re-add a gcc_assert (origin_die)
+     here.  */
 
-  add_AT_die_ref (die, DW_AT_abstract_origin, origin_die);
+  if (origin_die)
+      add_AT_die_ref (die, DW_AT_abstract_origin, origin_die);
 }
 
 /* We do not currently support the pure_virtual attribute.  */
@@ -11094,13 +11219,27 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
   if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))
       && ! lookup_decl_die (member))
     {
+      dw_die_ref type_die;
       gcc_assert (!decl_ultimate_origin (member));
 
       push_decl_scope (type);
+      type_die = lookup_type_die (type);
       if (TREE_CODE (member) == FUNCTION_DECL)
-       gen_subprogram_die (member, lookup_type_die (type));
+       gen_subprogram_die (member, type_die);
+      else if (TREE_CODE (member) == FIELD_DECL)
+       {
+         /* Ignore the nameless fields that are used to skip bits but handle
+            C++ anonymous unions and structs.  */
+         if (DECL_NAME (member) != NULL_TREE
+             || TREE_CODE (TREE_TYPE (member)) == UNION_TYPE
+             || TREE_CODE (TREE_TYPE (member)) == RECORD_TYPE)
+           {
+             gen_type_die (member_declared_type (member), type_die);
+             gen_field_die (member, type_die);
+           }
+       }
       else
-       gen_variable_die (member, lookup_type_die (type));
+       gen_variable_die (member, type_die);
 
       pop_decl_scope ();
     }
@@ -11199,12 +11338,8 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
             It seems reasonable to use AT_specification in this case.  */
          && !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,
-            we should detect this case and ignore it.  For now, if we have
-            already reported an error, any error at all, then assume that
-            we got here because of an input error, not a dwarf2 bug.  */
-         gcc_assert (errorcount);
+         /* Detect and ignore this case, where we are trying to output
+            something we have already output.  */
          return;
        }
 
@@ -11308,15 +11443,33 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
       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,
-                                  current_function_funcdef_no);
-      add_AT_lbl_id (subr_die, DW_AT_low_pc, label_id);
-      ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
-                                  current_function_funcdef_no);
-      add_AT_lbl_id (subr_die, DW_AT_high_pc, label_id);
-
-      add_pubname (decl, subr_die);
-      add_arange (decl, subr_die);
+      if (!flag_reorder_blocks_and_partition)
+       {
+         ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_BEGIN_LABEL,
+                                      current_function_funcdef_no);
+         add_AT_lbl_id (subr_die, DW_AT_low_pc, label_id);
+         ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
+                                      current_function_funcdef_no);
+         add_AT_lbl_id (subr_die, DW_AT_high_pc, label_id);
+         
+         add_pubname (decl, subr_die);
+         add_arange (decl, subr_die);
+       }
+      else
+       {  /* Do nothing for now; maybe need to duplicate die, one for
+             hot section and ond for cold section, then use the hot/cold
+             section begin/end labels to generate the aranges...  */
+         /*
+           add_AT_lbl_id (subr_die, DW_AT_low_pc, hot_section_label);
+           add_AT_lbl_id (subr_die, DW_AT_high_pc, hot_section_end_label);
+           add_AT_lbl_id (subr_die, DW_AT_lo_user, unlikely_section_label);
+           add_AT_lbl_id (subr_die, DW_AT_hi_user, cold_section_end_label);
+
+           add_pubname (decl, subr_die);
+           add_arange (decl, subr_die);
+           add_arange (decl, subr_die);
+          */
+       }
 
 #ifdef MIPS_DEBUGGING_INFO
       /* Add a reference to the FDE for this routine.  */
@@ -11462,8 +11615,13 @@ gen_variable_die (tree decl, dw_die_ref context_die)
      copy decls and set the DECL_ABSTRACT flag on them instead of
      sharing them.
 
-     ??? Duplicated blocks have been rewritten to use .debug_ranges.  */
-  else if (old_die && TREE_STATIC (decl)
+     ??? Duplicated blocks have been rewritten to use .debug_ranges.
+
+     ??? The declare_in_namespace support causes us to get two DIEs for one
+     variable, both of which are declarations.  We want to avoid considering
+     one to be a specification, so we must test that this DIE is not a
+     declaration.  */
+  else if (old_die && TREE_STATIC (decl) && ! declaration
           && get_AT_flag (old_die, DW_AT_declaration) == 1)
     {
       /* This is a definition of a C++ class level static.  */
@@ -11557,41 +11715,49 @@ gen_label_die (tree decl, dw_die_ref context_die)
     }
 }
 
-/* Generate a DIE for a lexical block.  */
+/* A helper function for gen_lexical_block_die and gen_inlined_subroutine_die.
+   Add low_pc and high_pc attributes to the DIE for a block STMT.  */
 
-static void
-gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
+static inline void
+add_high_low_attributes (tree stmt, dw_die_ref die)
 {
-  dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
-  if (! BLOCK_ABSTRACT (stmt))
+  if (BLOCK_FRAGMENT_CHAIN (stmt))
     {
-      if (BLOCK_FRAGMENT_CHAIN (stmt))
-       {
-         tree chain;
+      tree chain;
 
-         add_AT_range_list (stmt_die, DW_AT_ranges, add_ranges (stmt));
+      add_AT_range_list (die, DW_AT_ranges, add_ranges (stmt));
 
-         chain = BLOCK_FRAGMENT_CHAIN (stmt);
-         do
-           {
-             add_ranges (chain);
-             chain = BLOCK_FRAGMENT_CHAIN (chain);
-           }
-         while (chain);
-         add_ranges (NULL);
-       }
-      else
+      chain = BLOCK_FRAGMENT_CHAIN (stmt);
+      do
        {
-         ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
-                                      BLOCK_NUMBER (stmt));
-         add_AT_lbl_id (stmt_die, DW_AT_low_pc, label);
-         ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL,
-                                      BLOCK_NUMBER (stmt));
-         add_AT_lbl_id (stmt_die, DW_AT_high_pc, label);
+         add_ranges (chain);
+         chain = BLOCK_FRAGMENT_CHAIN (chain);
        }
+      while (chain);
+      add_ranges (NULL);
+    }
+  else
+    {
+      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
+                                  BLOCK_NUMBER (stmt));
+      add_AT_lbl_id (die, DW_AT_low_pc, label);
+      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL,
+                                  BLOCK_NUMBER (stmt));
+      add_AT_lbl_id (die, DW_AT_high_pc, label);
     }
+}
+
+/* Generate a DIE for a lexical block.  */
+
+static void
+gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
+{
+  dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
+
+  if (! BLOCK_ABSTRACT (stmt))
+    add_high_low_attributes (stmt, stmt_die);
 
   decls_for_scope (stmt, stmt_die, depth);
 }
@@ -11613,15 +11779,10 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
     {
       dw_die_ref subr_die
        = new_die (DW_TAG_inlined_subroutine, context_die, stmt);
-      char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
       add_abstract_origin_attribute (subr_die, decl);
-      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
-                                  BLOCK_NUMBER (stmt));
-      add_AT_lbl_id (subr_die, DW_AT_low_pc, label);
-      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL,
-                                  BLOCK_NUMBER (stmt));
-      add_AT_lbl_id (subr_die, DW_AT_high_pc, label);
+      add_high_low_attributes (stmt, subr_die);
+
       decls_for_scope (stmt, subr_die, depth);
       current_function_has_inlines = 1;
     }
@@ -12088,12 +12249,6 @@ gen_type_die (tree type, dw_die_ref context_die)
       gen_ptr_to_mbr_type_die (type, context_die);
       break;
 
-    case FILE_TYPE:
-      gen_type_die (TREE_TYPE (type), context_die);
-      /* No way to represent these in Dwarf yet!  */
-      gcc_unreachable ();
-      break;
-
     case FUNCTION_TYPE:
       /* Force out return type (in case it wasn't forced out already).  */
       gen_type_die (TREE_TYPE (type), context_die);
@@ -12234,9 +12389,8 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
   tree decl;
   enum tree_code origin_code;
 
-  /* Ignore blocks never really used to make RTL.  */
-  if (stmt == NULL_TREE || !TREE_USED (stmt)
-      || (!TREE_ASM_WRITTEN (stmt) && !BLOCK_ABSTRACT (stmt)))
+  /* Ignore blocks that are NULL.  */
+  if (stmt == NULL_TREE)
     return;
 
   /* If the block is one fragment of a non-contiguous block, do not
@@ -12282,7 +12436,10 @@ gen_block_die (tree stmt, dw_die_ref context_die, int depth)
          if (debug_info_level > DINFO_LEVEL_TERSE)
            /* We are not in terse mode so *any* local declaration counts
               as being a "significant" one.  */
-           must_output_die = (BLOCK_VARS (stmt) != NULL);
+           must_output_die = (BLOCK_VARS (stmt) != NULL 
+                              && (TREE_USED (stmt) 
+                                  || TREE_ASM_WRITTEN (stmt)
+                                  || BLOCK_ABSTRACT (stmt)));
          else
            /* We are in terse mode, so only local (nested) function
               definitions count as "significant" local declarations.  */
@@ -12324,29 +12481,32 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
   tree decl;
   tree subblocks;
 
-  /* Ignore blocks never really used to make RTL.  */
-  if (stmt == NULL_TREE || ! TREE_USED (stmt))
+  /* Ignore NULL blocks.  */
+  if (stmt == NULL_TREE)
     return;
 
-  /* Output the DIEs to represent all of the data objects and typedefs
-     declared directly within this block but not within any nested
-     sub-blocks.  Also, nested function and tag DIEs have been
-     generated with a parent of NULL; fix that up now.  */
-  for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
+  if (TREE_USED (stmt))
     {
-      dw_die_ref die;
-
-      if (TREE_CODE (decl) == FUNCTION_DECL)
-       die = lookup_decl_die (decl);
-      else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
-       die = lookup_type_die (TREE_TYPE (decl));
-      else
-       die = NULL;
-
-      if (die != NULL && die->die_parent == NULL)
-       add_child_die (context_die, die);
-      else
-       gen_decl_die (decl, context_die);
+      /* Output the DIEs to represent all of the data objects and typedefs
+        declared directly within this block but not within any nested
+        sub-blocks.  Also, nested function and tag DIEs have been
+        generated with a parent of NULL; fix that up now.  */
+      for (decl = BLOCK_VARS (stmt); decl != NULL; decl = TREE_CHAIN (decl))
+       {
+         dw_die_ref die;
+         
+         if (TREE_CODE (decl) == FUNCTION_DECL)
+           die = lookup_decl_die (decl);
+         else if (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl))
+           die = lookup_type_die (TREE_TYPE (decl));
+         else
+           die = NULL;
+         
+         if (die != NULL && die->die_parent == NULL)
+           add_child_die (context_die, die);
+         else
+           gen_decl_die (decl, context_die);
+       }
     }
 
   /* If we're at -g1, we're not interested in subblocks.  */
@@ -12498,6 +12658,12 @@ declare_in_namespace (tree thing, dw_die_ref context_die)
   if (debug_info_level <= DINFO_LEVEL_TERSE)
     return;
 
+  /* If this decl is from an inlined function, then don't try to emit it in its
+     namespace, as we will get confused.  It would have already been emitted
+     when the abstract instance of the inline function was emitted anyways.  */
+  if (DECL_P (thing) && DECL_ABSTRACT_ORIGIN (thing))
+    return;
+
   ns_context = setup_namespace_context (thing, context_die);
 
   if (ns_context != context_die)
@@ -12785,7 +12951,29 @@ dwarf2out_imported_module_or_decl (tree decl, tree context)
   if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL)
     at_import_die = force_type_die (TREE_TYPE (decl));
   else
-    at_import_die = force_decl_die (decl);
+    {
+      at_import_die = lookup_decl_die (decl);
+      if (!at_import_die)
+       {
+         /* If we're trying to avoid duplicate debug info, we may not have
+            emitted the member decl for this field.  Emit it now.  */
+         if (TREE_CODE (decl) == FIELD_DECL)
+           {
+             tree type = DECL_CONTEXT (decl);
+             dw_die_ref type_context_die;
+
+             if (TYPE_CONTEXT (type))
+               if (TYPE_P (TYPE_CONTEXT (type)))
+                 type_context_die = force_type_die (TYPE_CONTEXT (type));
+             else
+               type_context_die = force_decl_die (TYPE_CONTEXT (type));
+             else
+               type_context_die = comp_unit_die;
+             gen_type_die_for_member (type, decl, type_context_die);
+           }
+         at_import_die = force_decl_die (decl);
+       }
+    }
 
   /* OK, now we have DIEs for decl as well as scope. Emit imported die.  */
   if (TREE_CODE (decl) == NAMESPACE_DECL)
@@ -12922,7 +13110,7 @@ static void
 dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
                       unsigned int blocknum)
 {
-  function_section (current_function_decl);
+  current_function_section (current_function_decl);
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
 }
 
@@ -12932,7 +13120,7 @@ dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
 static void
 dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
 {
-  function_section (current_function_decl);
+  current_function_section (current_function_decl);
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
 }
 
@@ -13073,11 +13261,19 @@ dwarf2out_var_location (rtx loc_note)
   newloc->var_loc_note = loc_note;
   newloc->next = NULL;
 
+  if (last_text_section == in_unlikely_executed_text
+      || (last_text_section == in_named
+         && last_text_section_name == unlikely_text_section_name))
+    newloc->section_label = unlikely_section_label;
+  else
+    newloc->section_label = text_section_label;
+
   last_insn = loc_note;
   last_label = newloc->label;
   decl = NOTE_VAR_LOCATION_DECL (loc_note);
-  if (DECL_DEBUG_ALIAS_OF (decl))
-    decl = DECL_DEBUG_ALIAS_OF (decl); 
+  if (DECL_DEBUG_EXPR (decl) && DECL_DEBUG_EXPR_IS_FROM (decl)
+      && DECL_P (DECL_DEBUG_EXPR (decl)))
+    decl = DECL_DEBUG_EXPR (decl); 
   add_var_loc_to_decl (decl, newloc);
 }
 
@@ -13102,7 +13298,7 @@ dwarf2out_source_line (unsigned int line, const char *filename)
   if (debug_info_level >= DINFO_LEVEL_NORMAL
       && line != 0)
     {
-      function_section (current_function_decl);
+      current_function_section (current_function_decl);
 
       /* If requested, emit something human-readable.  */
       if (flag_debug_asm)
@@ -13739,11 +13935,10 @@ dwarf2out_finish (const char *filename)
       output_ranges ();
     }
 
-  /* Have to end the primary source file.  */
+  /* Have to end the macro section.  */
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
       named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
-      dw2_asm_output_data (1, DW_MACINFO_end_file, "End file");
       dw2_asm_output_data (1, 0, "End compilation unit");
     }