OSDN Git Service

2008-05-23 Rafael Espindola <espindola@google.com>
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index f54f34a..145b8fe 100644 (file)
@@ -2116,7 +2116,8 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
     dw2_asm_output_data (1, (cfi->dw_cfi_opc
                             | (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)),
                         "DW_CFA_advance_loc " HOST_WIDE_INT_PRINT_HEX,
-                        cfi->dw_cfi_oprnd1.dw_cfi_offset);
+                        ((unsigned HOST_WIDE_INT)
+                         cfi->dw_cfi_oprnd1.dw_cfi_offset));
   else if (cfi->dw_cfi_opc == DW_CFA_offset)
     {
       r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
@@ -2656,8 +2657,8 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   fde->dw_fde_cfi = NULL;
   fde->funcdef_number = current_function_funcdef_no;
   fde->nothrow = TREE_NOTHROW (current_function_decl);
-  fde->uses_eh_lsda = cfun->uses_eh_lsda;
-  fde->all_throwers_are_sibcalls = cfun->all_throwers_are_sibcalls;
+  fde->uses_eh_lsda = crtl->uses_eh_lsda;
+  fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
 
   args_size = old_args_size = 0;
 
@@ -2744,10 +2745,10 @@ dwarf2out_switch_text_section (void)
 
   fde = &fde_table[fde_table_in_use - 1];
   fde->dw_fde_switched_sections = true;
-  fde->dw_fde_hot_section_label = cfun->hot_section_label;
-  fde->dw_fde_hot_section_end_label = cfun->hot_section_end_label;
-  fde->dw_fde_unlikely_section_label = cfun->cold_section_label;
-  fde->dw_fde_unlikely_section_end_label = cfun->cold_section_end_label;
+  fde->dw_fde_hot_section_label = crtl->subsections.hot_section_label;
+  fde->dw_fde_hot_section_end_label = crtl->subsections.hot_section_end_label;
+  fde->dw_fde_unlikely_section_label = crtl->subsections.cold_section_label;
+  fde->dw_fde_unlikely_section_end_label = crtl->subsections.cold_section_end_label;
   have_multiple_function_sections = true;
 
   /* Reset the current label on switching text sections, so that we
@@ -3836,7 +3837,7 @@ DEF_VEC_ALLOC_O(dw_attr_node,gc);
    The children of each node form a circular list linked by
    die_sib.  die_child points to the node *before* the "first" child node.  */
 
-typedef struct die_struct GTY(())
+typedef struct die_struct GTY((chain_circular ("%h.die_sib")))
 {
   enum dwarf_tag die_tag;
   char *die_symbol;
@@ -8222,7 +8223,7 @@ output_line_info (void)
   current_line = 1;
 
   if (cfun && in_cold_section_p)
-    strcpy (prev_line_label, cfun->cold_section_label);
+    strcpy (prev_line_label, crtl->subsections.cold_section_label);
   else
     strcpy (prev_line_label, text_section_label);
   for (lt_index = 1; lt_index < line_info_table_in_use; ++lt_index)
@@ -9493,16 +9494,33 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
       if (DECL_THREAD_LOCAL_P (loc))
        {
          rtx rtl;
+         unsigned first_op;
+         unsigned second_op;
 
-         /* If this is not defined, we have no way to emit the data.  */
-         if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel)
-           return 0;
-
-         /* The way DW_OP_GNU_push_tls_address is specified, we can only
-            look up addresses of objects in the current module.  */
-         if (DECL_EXTERNAL (loc))
-           return 0;
-
+         if (targetm.have_tls)
+           {
+             /* If this is not defined, we have no way to emit the
+                data.  */
+             if (!targetm.asm_out.output_dwarf_dtprel)
+               return 0;
+
+              /* The way DW_OP_GNU_push_tls_address is specified, we
+                 can only look up addresses of objects in the current
+                 module.  */
+             if (DECL_EXTERNAL (loc))
+               return 0;
+             first_op = INTERNAL_DW_OP_tls_addr;
+             second_op = DW_OP_GNU_push_tls_address;
+           }
+         else
+           {
+             if (!targetm.emutls.debug_form_tls_address)
+               return 0;
+             loc = emutls_decl (loc);
+             first_op = DW_OP_addr;
+             second_op = DW_OP_form_tls_address;
+           }
+         
          rtl = rtl_for_decl_location (loc);
          if (rtl == NULL_RTX)
            return 0;
@@ -9513,11 +9531,11 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
          if (! CONSTANT_P (rtl))
            return 0;
 
-         ret = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0);
+         ret = new_loc_descr (first_op, 0, 0);
          ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
          ret->dw_loc_oprnd1.v.val_addr = rtl;
-
-         ret1 = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
+         
+         ret1 = new_loc_descr (second_op, 0, 0);
          add_loc_descr (&ret, ret1);
 
          have_address = 1;
@@ -9580,9 +9598,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
     case COMPOUND_EXPR:
       return loc_descriptor_from_tree_1 (TREE_OPERAND (loc, 1), want_address);
 
-    case NOP_EXPR:
-    case CONVERT_EXPR:
-    case NON_LVALUE_EXPR:
+    CASE_CONVERT:
     case VIEW_CONVERT_EXPR:
     case SAVE_EXPR:
     case GIMPLE_MODIFY_STMT:
@@ -10510,63 +10526,6 @@ rtl_for_decl_init (tree init, tree type)
   return rtl;
 }
 
-/* This is a specialized subset of expand_expr to evaluate a DECL_VALUE_EXPR.
-   We stop if we find decls that haven't been expanded, or if the expression is
-   getting so complex we won't be able to represent it anyway.  Returns NULL on
-   failure.  */
-
-static rtx
-dw_expand_expr (tree expr)
-{
-  switch (TREE_CODE (expr))
-  {
-  case VAR_DECL:
-  case PARM_DECL:
-    if (DECL_HAS_VALUE_EXPR_P (expr))
-      return dw_expand_expr (DECL_VALUE_EXPR (expr));
-    /* FALLTHRU */
-  case CONST_DECL:
-  case RESULT_DECL:
-    return DECL_RTL_IF_SET (expr);
-  case INTEGER_CST:
-    return expand_expr (expr, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
-
-  case COMPONENT_REF:
-  case ARRAY_REF:
-  case ARRAY_RANGE_REF:
-  case BIT_FIELD_REF:
-  {
-    enum machine_mode mode;
-    HOST_WIDE_INT bitsize, bitpos;
-    tree offset, tem;
-    int volatilep = 0, unsignedp = 0;
-    rtx x;
-
-    tem = get_inner_reference (expr, &bitsize, &bitpos, &offset,
-                               &mode, &unsignedp, &volatilep, true);
-    x = dw_expand_expr (tem);
-    if (x == NULL || !MEM_P (x))
-       return NULL;
-    if (offset != NULL)
-      {
-        if (!host_integerp (offset, 0))
-          return NULL;
-        x = adjust_address_nv (x, mode, tree_low_cst (offset, 0));
-      }
-    if (bitpos != 0)
-      x = adjust_address_nv (x, mode, bitpos / BITS_PER_UNIT);
-
-    return x;
-  }
-  default:
-    return NULL;
-  }
-}
-
 /* Generate RTL for the variable DECL to represent its location.  */
 
 static rtx
@@ -10792,7 +10751,7 @@ secname_for_decl (const_tree decl)
       secname = TREE_STRING_POINTER (sectree);
     }
   else if (cfun && in_cold_section_p)
-    secname = cfun->cold_section_label;
+    secname = crtl->subsections.cold_section_label;
   else
     secname = text_section_label;
 
@@ -10803,86 +10762,50 @@ secname_for_decl (const_tree decl)
    If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the
    value is the offset into the common block for the symbol.  */
 
-static rtx
-common_check (tree decl, HOST_WIDE_INT *value)
+static tree
+fortran_common (tree decl, HOST_WIDE_INT *value)
 {
-  rtx home;
-  rtx sym_addr;
-  rtx res = NULL_RTX;
+  tree val_expr, cvar;
+  enum machine_mode mode;
+  HOST_WIDE_INT bitsize, bitpos;
+  tree offset;
+  int volatilep = 0, unsignedp = 0;
+
   /* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
      it does not have a value (the offset into the common area), or if it
      is thread local (as opposed to global) then it isn't common, and shouldn't
      be handled as such.  */
   if (TREE_CODE (decl) != VAR_DECL
-      || !TREE_PUBLIC(decl)
-      || !TREE_STATIC(decl)
-      || !DECL_HAS_VALUE_EXPR_P(decl)
-      || DECL_THREAD_LOCAL_P (decl)
-      || !is_fortran())
-    return NULL;
-
-  home = DECL_RTL (decl);
-  if (home == NULL_RTX || GET_CODE (home) != MEM)
-    return NULL;
-
-  sym_addr = dw_expand_expr (DECL_VALUE_EXPR (decl));
-  if (sym_addr == NULL_RTX || GET_CODE (sym_addr) != MEM)
-    return NULL;
+      || !TREE_PUBLIC (decl)
+      || !TREE_STATIC (decl)
+      || !DECL_HAS_VALUE_EXPR_P (decl)
+      || !is_fortran ())
+    return NULL_TREE;
 
-  sym_addr = XEXP (sym_addr, 0);
-  if (GET_CODE (sym_addr) == CONST)
-    sym_addr = XEXP (sym_addr, 0);
-  if ((GET_CODE (sym_addr) == SYMBOL_REF || GET_CODE (sym_addr) == PLUS)
-      && DECL_INITIAL (decl) == 0)
-    {
-      /* We have a sym that will go into a common area, meaning that it
-         will get storage reserved with a .comm/.lcomm assembler pseudo-op.
+  val_expr = DECL_VALUE_EXPR (decl);
+  if (TREE_CODE (val_expr) != COMPONENT_REF)
+    return NULL_TREE;
 
-         Determine name of common area this symbol will be an offset into,
-         and offset into that area.  Also retrieve the decl for the area
-         that the symbol is offset into.  */
-      tree cdecl = NULL;
+  cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset,
+                             &mode, &unsignedp, &volatilep, true);
 
-      switch (GET_CODE (sym_addr))
-        {
-        case PLUS:
-          if (GET_CODE (XEXP (sym_addr, 0)) == CONST_INT)
-            {
-              res = XEXP (sym_addr, 1);
-              *value = INTVAL (XEXP (sym_addr, 0));
-              cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 1));
-            }
-          else
-            {
-              res = XEXP (sym_addr, 0);
-              *value = INTVAL (XEXP (sym_addr, 1));
-              cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 0));
-             }
-          break;
-
-        case SYMBOL_REF:
-          res = sym_addr;
-          *value = 0;
-          cdecl = SYMBOL_REF_DECL (sym_addr);
-          break;
-
-        default:
-          error ("common symbol debug info is not structured as "
-                 "symbol+offset");
-        }
+  if (cvar == NULL_TREE
+      || TREE_CODE (cvar) != VAR_DECL
+      || DECL_ARTIFICIAL (cvar)
+      || !TREE_PUBLIC (cvar))
+    return NULL_TREE;
 
-      /* Check area common symbol is offset into.  If this is not public, then
-         it is not a symbol in a common block.  It must be a .lcomm symbol, not
-         a .comm symbol.  */
-      if (cdecl == NULL || !TREE_PUBLIC(cdecl))
-        res = NULL_RTX;
+  *value = 0;
+  if (offset != NULL)
+    {
+      if (!host_integerp (offset, 0))
+       return NULL_TREE;
+      *value = tree_low_cst (offset, 0);
     }
-  else
-    res = NULL_RTX;
+  if (bitpos != 0)
+    *value += bitpos / BITS_PER_UNIT;
 
-  return res;
+  return cvar;
 }
 
 
@@ -11209,9 +11132,7 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b
        add_AT_unsigned (subrange_die, bound_attr, tree_low_cst (bound, 0));
       break;
 
-    case CONVERT_EXPR:
-    case NOP_EXPR:
-    case NON_LVALUE_EXPR:
+    CASE_CONVERT:
     case VIEW_CONVERT_EXPR:
       add_bound_info (subrange_die, bound_attr, TREE_OPERAND (bound, 0));
       break;
@@ -11895,8 +11816,7 @@ descr_info_loc (tree val, tree base_decl)
 
   switch (TREE_CODE (val))
     {
-    case NOP_EXPR:
-    case CONVERT_EXPR:
+    CASE_CONVERT:
       return descr_info_loc (TREE_OPERAND (val, 0), base_decl);
     case INTEGER_CST:
       if (host_integerp (val, 0))
@@ -12784,7 +12704,7 @@ static void
 gen_variable_die (tree decl, dw_die_ref context_die)
 {
   HOST_WIDE_INT off;
-  rtx csym;
+  tree com_decl;
   dw_die_ref var_die;
   tree origin = decl_ultimate_origin (decl);
   dw_die_ref old_die = lookup_decl_die (decl);
@@ -12810,31 +12730,31 @@ gen_variable_die (tree decl, dw_die_ref context_die)
                         && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
                     || class_or_namespace_scope_p (context_die));
 
-  csym = common_check (decl, &off);
+  com_decl = fortran_common (decl, &off);
 
   /* Symbol in common gets emitted as a child of the common block, in the form
      of a data member.
 
      ??? This creates a new common block die for every common block symbol.
      Better to share same common block die for all symbols in that block.  */
-  if (csym)
+  if (com_decl)
     {
-      tree blok;
+      tree field;
       dw_die_ref com_die;
-      const char *cnam = targetm.strip_name_encoding(XSTR (csym, 0));
-      dw_loc_descr_ref loc = mem_loc_descriptor (csym, dw_val_class_addr,
-                                                 VAR_INIT_STATUS_INITIALIZED);
+      const char *cnam = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
+      dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
 
-      blok = (tree) TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
+      field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
       var_die = new_die (DW_TAG_common_block, context_die, decl);
-      add_name_and_src_coords_attributes (var_die, blok);
+      add_name_and_src_coords_attributes (var_die, field);
       add_AT_flag (var_die, DW_AT_external, 1);
       add_AT_loc (var_die, DW_AT_location, loc);
       com_die = new_die (DW_TAG_member, var_die, decl);
       add_name_and_src_coords_attributes (com_die, decl);
       add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
-      TREE_THIS_VOLATILE (decl), context_die);
-      add_AT_loc (com_die, DW_AT_data_member_location, int_loc_descriptor(off));
+                         TREE_THIS_VOLATILE (decl), context_die);
+      add_AT_loc (com_die, DW_AT_data_member_location,
+                 int_loc_descriptor (off));
       add_pubname_string (cnam, var_die); /* ??? needed? */
       return;
     }
@@ -14611,7 +14531,7 @@ dwarf2out_var_location (rtx loc_note)
   newloc->next = NULL;
 
   if (cfun && in_cold_section_p)
-    newloc->section_label = cfun->cold_section_label;
+    newloc->section_label = crtl->subsections.cold_section_label;
   else
     newloc->section_label = text_section_label;