OSDN Git Service

* ira-build.c (ira_create_object): New arg SUBWORD; all callers changed.
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 3faa175..ce35c91 100644 (file)
@@ -4928,10 +4928,28 @@ output_loc_operands (dw_loc_descr_ref loc)
       dw2_asm_output_data (2, val1->v.val_int, NULL);
       break;
     case DW_OP_const4u:
+      if (loc->dtprel)
+       {
+         gcc_assert (targetm.asm_out.output_dwarf_dtprel);
+         targetm.asm_out.output_dwarf_dtprel (asm_out_file, 4,
+                                              val1->v.val_addr);
+         fputc ('\n', asm_out_file);
+         break;
+       }
+      /* FALLTHRU */
     case DW_OP_const4s:
       dw2_asm_output_data (4, val1->v.val_int, NULL);
       break;
     case DW_OP_const8u:
+      if (loc->dtprel)
+       {
+         gcc_assert (targetm.asm_out.output_dwarf_dtprel);
+         targetm.asm_out.output_dwarf_dtprel (asm_out_file, 8,
+                                              val1->v.val_addr);
+         fputc ('\n', asm_out_file);
+         break;
+       }
+      /* FALLTHRU */
     case DW_OP_const8s:
       gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
       dw2_asm_output_data (8, val1->v.val_int, NULL);
@@ -6385,11 +6403,6 @@ static void gen_remaining_tmpl_value_param_die_attribute (void);
 #define DEBUG_MACINFO_SECTION_LABEL     "Ldebug_macinfo"
 #endif
 
-/* Mangled name attribute to use.  This used to be a vendor extension
-   until DWARF 4 standardized it.  */
-#define AT_linkage_name \
-  (dwarf_version >= 4 ? DW_AT_linkage_name : DW_AT_MIPS_linkage_name)
-
 
 /* Definitions of defaults for formats and names of various special
    (artificial) labels which may be generated within this file (when the -g
@@ -11238,17 +11251,20 @@ dwarf2_name (tree decl, int scope)
 static void
 add_pubname_string (const char *str, dw_die_ref die)
 {
-  pubname_entry e;
+  if (targetm.want_debug_pub_sections)
+    {
+      pubname_entry e;
 
-  e.die = die;
-  e.name = xstrdup (str);
-  VEC_safe_push (pubname_entry, gc, pubname_table, &e);
+      e.die = die;
+      e.name = xstrdup (str);
+      VEC_safe_push (pubname_entry, gc, pubname_table, &e);
+    }
 }
 
 static void
 add_pubname (tree decl, dw_die_ref die)
 {
-  if (TREE_PUBLIC (decl))
+  if (targetm.want_debug_pub_sections && TREE_PUBLIC (decl))
     {
       const char *name = dwarf2_name (decl, 1);
       if (name)
@@ -11263,6 +11279,9 @@ add_pubtype (tree decl, dw_die_ref die)
 {
   pubname_entry e;
 
+  if (!targetm.want_debug_pub_sections)
+    return;
+
   e.name = NULL;
   if ((TREE_PUBLIC (decl)
        || die->die_parent == comp_unit_die)
@@ -12999,6 +13018,26 @@ reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
   if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
     return 0;
 
+  /* We only use "frame base" when we're sure we're talking about the
+     post-prologue local stack frame.  We do this by *not* running
+     register elimination until this point, and recognizing the special
+     argument pointer and soft frame pointer rtx's.
+     Use DW_OP_fbreg offset DW_OP_stack_value in this case.  */
+  if ((rtl == arg_pointer_rtx || rtl == frame_pointer_rtx)
+      && eliminate_regs (rtl, VOIDmode, NULL_RTX) != rtl)
+    {
+      dw_loc_descr_ref result = NULL;
+
+      if (dwarf_version >= 4 || !dwarf_strict)
+       {
+         result = mem_loc_descriptor (rtl, VOIDmode, initialized);
+         if (result)
+           add_loc_descr (&result,
+                          new_loc_descr (DW_OP_stack_value, 0, 0));
+       }
+      return result;
+    }
+
   regs = targetm.dwarf_register_span (rtl);
 
   if (hard_regno_nregs[REGNO (rtl)][GET_MODE (rtl)] > 1 || regs)
@@ -13565,7 +13604,11 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
          if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel)
            break;
 
-         temp = new_loc_descr (DW_OP_addr, 0, 0);
+         /* We used to emit DW_OP_addr here, but that's wrong, since
+            DW_OP_addr should be relocated by the debug info consumer,
+            while DW_OP_GNU_push_tls_address operand should not.  */
+         temp = new_loc_descr (DWARF2_ADDR_SIZE == 4
+                               ? DW_OP_const4u : DW_OP_const8u, 0, 0);
          temp->dw_loc_oprnd1.val_class = dw_val_class_addr;
          temp->dw_loc_oprnd1.v.val_addr = rtl;
          temp->dtprel = true;
@@ -14211,11 +14254,6 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
       loc_result = reg_loc_descriptor (rtl, initialized);
       break;
 
-    case SIGN_EXTEND:
-    case ZERO_EXTEND:
-      loc_result = loc_descriptor (XEXP (rtl, 0), mode, initialized);
-      break;
-
     case MEM:
       loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
                                       initialized);
@@ -15050,10 +15088,13 @@ loc_list_from_tree (tree loc, int want_address)
 
               /* The way DW_OP_GNU_push_tls_address is specified, we
                  can only look up addresses of objects in the current
-                 module.  */
+                 module.  We used DW_OP_addr as first op, but that's
+                 wrong, because DW_OP_addr is relocated by the debug
+                 info consumer, while DW_OP_GNU_push_tls_address
+                 operand shouldn't be.  */
              if (DECL_EXTERNAL (loc) && !targetm.binds_local_p (loc))
                return 0;
-             first_op = DW_OP_addr;
+             first_op = DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u;
              dtprel = true;
              second_op = DW_OP_GNU_push_tls_address;
            }
@@ -15166,7 +15207,6 @@ loc_list_from_tree (tree loc, int want_address)
        return 0;
       /* Fallthru.  */
     case INDIRECT_REF:
-    case ALIGN_INDIRECT_REF:
     case MISALIGNED_INDIRECT_REF:
       list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0);
       have_address = 1;
@@ -15726,7 +15766,7 @@ field_byte_offset (const_tree decl)
         where the lowest addressed bit of the containing object must
         be.  */
       object_offset_in_bits
-       = double_int_add (deepest_bitpos, double_int_neg (type_size_in_bits));
+       = double_int_sub (deepest_bitpos, type_size_in_bits);
 
       /* Round up to type_align by default.  This works best for
         bitfields.  */
@@ -15736,8 +15776,7 @@ field_byte_offset (const_tree decl)
       if (double_int_ucmp (object_offset_in_bits, bitpos_int) > 0)
        {
          object_offset_in_bits
-           = double_int_add (deepest_bitpos,
-                             double_int_neg (type_size_in_bits));
+           = double_int_sub (deepest_bitpos, type_size_in_bits);
 
          /* Round up to decl_align instead.  */
          object_offset_in_bits
@@ -16694,7 +16733,7 @@ native_encode_initializer (tree init, unsigned char *array, int size)
 
          for (cnt = 0;
               VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (init), cnt, ce);
-              cnt++, field = field ? TREE_CHAIN (field) : 0)
+              cnt++, field = field ? DECL_CHAIN (field) : 0)
            {
              tree val = ce->value;
              int pos, fieldsize;
@@ -17360,6 +17399,25 @@ add_pure_or_virtual_attribute (dw_die_ref die, tree func_decl)
     }
 }
 \f
+/* Add a DW_AT_linkage_name or DW_AT_MIPS_linkage_name attribute for the
+   given decl.  This used to be a vendor extension until after DWARF 4
+   standardized it.  */
+
+static void
+add_linkage_attr (dw_die_ref die, tree decl)
+{
+  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+  /* Mimic what assemble_name_raw does with a leading '*'.  */
+  if (name[0] == '*')
+    name = &name[1];
+
+  if (dwarf_version >= 4)
+    add_AT_string (die, DW_AT_linkage_name, name);
+  else
+    add_AT_string (die, DW_AT_MIPS_linkage_name, name);
+}
+
 /* Add source coordinate attributes for the given decl.  */
 
 static void
@@ -17394,8 +17452,7 @@ add_linkage_name (dw_die_ref die, tree decl)
          deferred_asm_name = asm_name;
        }
       else if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
-       add_AT_string (die, AT_linkage_name,
-                      IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+       add_linkage_attr (die, decl);
     }
 }
 
@@ -18233,7 +18290,7 @@ gen_formal_parameter_pack_die  (tree parm_pack,
   parm_pack_die = new_die (DW_TAG_GNU_formal_parameter_pack, subr_die, parm_pack);
   add_src_coords_attributes (parm_pack_die, parm_pack);
 
-  for (arg = pack_arg; arg; arg = TREE_CHAIN (arg))
+  for (arg = pack_arg; arg; arg = DECL_CHAIN (arg))
     {
       if (! lang_hooks.decls.function_parm_expanded_from_pack_p (arg,
                                                                 parm_pack))
@@ -18300,7 +18357,7 @@ gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
 
       link = TREE_CHAIN (link);
       if (arg)
-       arg = TREE_CHAIN (arg);
+       arg = DECL_CHAIN (arg);
     }
 
   /* If this function type has an ellipsis, add a
@@ -18809,11 +18866,11 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
          else if (parm)
            {
              gen_decl_die (parm, NULL, subr_die);
-             parm = TREE_CHAIN (parm);
+             parm = DECL_CHAIN (parm);
            }
 
          if (generic_decl_parm)
-           generic_decl_parm = TREE_CHAIN (generic_decl_parm);
+           generic_decl_parm = DECL_CHAIN (generic_decl_parm);
        }
 
       /* Decide whether we need an unspecified_parameters DIE at the end.
@@ -19515,7 +19572,7 @@ gen_member_die (tree type, dw_die_ref context_die)
     }
 
   /* Now output info about the data members and type members.  */
-  for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member))
+  for (member = TYPE_FIELDS (type); member; member = DECL_CHAIN (member))
     {
       /* If we thought we were generating minimal debug info for TYPE
         and then changed our minds, some of the member declarations
@@ -19530,7 +19587,7 @@ gen_member_die (tree type, dw_die_ref context_die)
     }
 
   /* Now output info about the function members (if any).  */
-  for (member = TYPE_METHODS (type); member; member = TREE_CHAIN (member))
+  for (member = TYPE_METHODS (type); member; member = DECL_CHAIN (member))
     {
       /* Don't include clones in the member list.  */
       if (DECL_ABSTRACT_ORIGIN (member))
@@ -20096,7 +20153,7 @@ decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
      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))
+  for (decl = BLOCK_VARS (stmt); decl != NULL; decl = DECL_CHAIN (decl))
     process_scope_var (stmt, decl, NULL_TREE, context_die);
   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
     process_scope_var (stmt, NULL, BLOCK_NONLOCALIZED_VAR (stmt, i),
@@ -20877,7 +20934,7 @@ dwarf2out_ignore_block (const_tree block)
   tree decl;
   unsigned int i;
 
-  for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
+  for (decl = BLOCK_VARS (block); decl; decl = DECL_CHAIN (decl))
     if (TREE_CODE (decl) == FUNCTION_DECL
        || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
       return 0;
@@ -21993,7 +22050,8 @@ move_linkage_attr (dw_die_ref die)
   unsigned ix = VEC_length (dw_attr_node, die->die_attr);
   dw_attr_node linkage = *VEC_index (dw_attr_node, die->die_attr, ix - 1);
 
-  gcc_assert (linkage.dw_attr == AT_linkage_name);
+  gcc_assert (linkage.dw_attr == DW_AT_linkage_name
+             || linkage.dw_attr == DW_AT_MIPS_linkage_name);
 
   while (--ix > 0)
     {
@@ -22055,7 +22113,7 @@ static bool
 resolve_addr_in_expr (dw_loc_descr_ref loc)
 {
   for (; loc; loc = loc->dw_loc_next)
-    if ((loc->dw_loc_opc == DW_OP_addr
+    if (((loc->dw_loc_opc == DW_OP_addr || loc->dtprel)
         && resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr, NULL))
        || (loc->dw_loc_opc == DW_OP_implicit_value
            && loc->dw_loc_oprnd2.val_class == dw_val_class_addr
@@ -22226,8 +22284,7 @@ dwarf2out_finish (const char *filename)
       tree decl = node->created_for;
       if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
        {
-         add_AT_string (node->die, AT_linkage_name,
-                        IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+         add_linkage_attr (node->die, decl);
          move_linkage_attr (node->die);
        }
     }