OSDN Git Service

PR target/36684
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2out.c
index 49c13d2..80bdc0a 100644 (file)
@@ -315,6 +315,14 @@ static GTY(()) unsigned fde_table_in_use;
    fde_table.  */
 #define FDE_TABLE_INCREMENT 256
 
+/* Get the current fde_table entry we should use.  */
+
+static inline dw_fde_ref
+current_fde (void)
+{
+  return fde_table_in_use ? &fde_table[fde_table_in_use - 1] : NULL;
+}
+
 /* A list of call frame insns for the CIE.  */
 static GTY(()) dw_cfi_ref cie_cfi_head;
 
@@ -598,7 +606,7 @@ dwarf_cfi_name (unsigned int cfi_opc)
 static inline dw_cfi_ref
 new_cfi (void)
 {
-  dw_cfi_ref cfi = ggc_alloc (sizeof (dw_cfi_node));
+  dw_cfi_ref cfi = GGC_NEW (dw_cfi_node);
 
   cfi->dw_cfi_next = NULL;
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0;
@@ -641,7 +649,9 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi)
 {
   if (label)
     {
-      dw_fde_ref fde = &fde_table[fde_table_in_use - 1];
+      dw_fde_ref fde = current_fde ();
+
+      gcc_assert (fde != NULL);
 
       if (*label == 0)
        label = dwarf2out_cfi_label ();
@@ -713,6 +723,7 @@ static void
 lookup_cfa (dw_cfa_location *loc)
 {
   dw_cfi_ref cfi;
+  dw_fde_ref fde;
 
   loc->reg = INVALID_REGNUM;
   loc->offset = 0;
@@ -722,12 +733,10 @@ lookup_cfa (dw_cfa_location *loc)
   for (cfi = cie_cfi_head; cfi; cfi = cfi->dw_cfi_next)
     lookup_cfa_1 (cfi, loc);
 
-  if (fde_table_in_use)
-    {
-      dw_fde_ref fde = &fde_table[fde_table_in_use - 1];
-      for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next)
-       lookup_cfa_1 (cfi, loc);
-    }
+  fde = current_fde ();
+  if (fde)
+    for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next)
+      lookup_cfa_1 (cfi, loc);
 }
 
 /* The current rule for calculating the DWARF2 canonical frame address.  */
@@ -1242,7 +1251,7 @@ queue_reg_save (const char *label, rtx reg, rtx sreg, HOST_WIDE_INT offset)
 
   if (q == NULL)
     {
-      q = ggc_alloc (sizeof (*q));
+      q = GGC_NEW (struct queued_reg_save);
       q->next = queued_reg_saves;
       queued_reg_saves = q;
     }
@@ -2634,8 +2643,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   if (fde_table_in_use == fde_table_allocated)
     {
       fde_table_allocated += FDE_TABLE_INCREMENT;
-      fde_table = ggc_realloc (fde_table,
-                              fde_table_allocated * sizeof (dw_fde_node));
+      fde_table = GGC_RESIZEVEC (dw_fde_node, fde_table, fde_table_allocated);
       memset (fde_table + fde_table_in_use, 0,
              FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
     }
@@ -2657,8 +2665,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;
 
@@ -2686,7 +2694,8 @@ dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
   ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
                               current_function_funcdef_no);
   ASM_OUTPUT_LABEL (asm_out_file, label);
-  fde = &fde_table[fde_table_in_use - 1];
+  fde = current_fde ();
+  gcc_assert (fde != NULL);
   fde->dw_fde_end = xstrdup (label);
 }
 
@@ -2694,7 +2703,7 @@ void
 dwarf2out_frame_init (void)
 {
   /* Allocate the initial hunk of the fde_table.  */
-  fde_table = ggc_alloc_cleared (FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
+  fde_table = GGC_CNEWVEC (dw_fde_node, FDE_TABLE_INCREMENT);
   fde_table_allocated = FDE_TABLE_INCREMENT;
   fde_table_in_use = 0;
 
@@ -2739,11 +2748,10 @@ dwarf2out_note_section_used (void)
 void
 dwarf2out_switch_text_section (void)
 {
-  dw_fde_ref fde;
+  dw_fde_ref fde = current_fde ();
 
-  gcc_assert (cfun);
+  gcc_assert (cfun && fde);
 
-  fde = &fde_table[fde_table_in_use - 1];
   fde->dw_fde_switched_sections = true;
   fde->dw_fde_hot_section_label = crtl->subsections.hot_section_label;
   fde->dw_fde_hot_section_end_label = crtl->subsections.hot_section_end_label;
@@ -3219,7 +3227,7 @@ static inline dw_loc_descr_ref
 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));
+  dw_loc_descr_ref descr = GGC_CNEW (dw_loc_descr_node);
 
   descr->dw_loc_opc = op;
   descr->dw_loc_oprnd1.val_class = dw_val_class_unsigned_const;
@@ -3837,7 +3845,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;
@@ -4272,7 +4280,7 @@ static int type_is_enum (const_tree);
 static unsigned int dbx_reg_number (const_rtx);
 static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
 static dw_loc_descr_ref reg_loc_descriptor (rtx, enum var_init_status);
-static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int, 
+static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int,
                                                enum var_init_status);
 static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx,
                                                     enum var_init_status);
@@ -5738,7 +5746,7 @@ splice_child_die (dw_die_ref parent, dw_die_ref child)
 static inline dw_die_ref
 new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
 {
-  dw_die_ref die = ggc_alloc_cleared (sizeof (die_node));
+  dw_die_ref die = GGC_CNEW (die_node);
 
   die->die_tag = tag_value;
 
@@ -5748,7 +5756,7 @@ new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
     {
       limbo_die_node *limbo_node;
 
-      limbo_node = ggc_alloc_cleared (sizeof (limbo_die_node));
+      limbo_node = GGC_CNEW (limbo_die_node);
       limbo_node->die = die;
       limbo_node->created_for = t;
       limbo_node->next = limbo_die_list;
@@ -5795,7 +5803,7 @@ decl_die_table_eq (const void *x, const void *y)
 static inline dw_die_ref
 lookup_decl_die (tree decl)
 {
-  return htab_find_with_hash (decl_die_table, decl, DECL_UID (decl));
+  return (dw_die_ref) htab_find_with_hash (decl_die_table, decl, DECL_UID (decl));
 }
 
 /* Returns a hash value for X (which really is a var_loc_list).  */
@@ -5820,7 +5828,8 @@ decl_loc_table_eq (const void *x, const void *y)
 static inline var_loc_list *
 lookup_decl_loc (const_tree decl)
 {
-  return htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
+  return (var_loc_list *)
+    htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
 }
 
 /* Equate a DIE to a particular declaration.  */
@@ -5848,12 +5857,12 @@ add_var_loc_to_decl (tree decl, struct var_loc_node *loc)
   slot = htab_find_slot_with_hash (decl_loc_table, decl, decl_id, INSERT);
   if (*slot == NULL)
     {
-      temp = ggc_alloc_cleared (sizeof (var_loc_list));
+      temp = GGC_CNEW (var_loc_list);
       temp->decl_id = decl_id;
       *slot = temp;
     }
   else
-    temp = *slot;
+    temp = (var_loc_list *) *slot;
 
   if (temp->last)
     {
@@ -6345,7 +6354,7 @@ compute_section_prefix (dw_die_ref unit_die)
 {
   const char *die_name = get_AT_string (unit_die, DW_AT_name);
   const char *base = die_name ? lbasename (die_name) : "anonymous";
-  char *name = alloca (strlen (base) + 64);
+  char *name = XALLOCAVEC (char, strlen (base) + 64);
   char *p;
   int i, mark;
   unsigned char checksum[16];
@@ -6467,7 +6476,7 @@ assign_symbol_names (dw_die_ref die)
     {
       if (comdat_symbol_id)
        {
-         char *p = alloca (strlen (comdat_symbol_id) + 64);
+         char *p = XALLOCAVEC (char, strlen (comdat_symbol_id) + 64);
 
          sprintf (p, "%s.%s.%x", DIE_LABEL_PREFIX,
                   comdat_symbol_id, comdat_symbol_number++);
@@ -6491,7 +6500,8 @@ struct cu_hash_table_entry
 static hashval_t
 htab_cu_hash (const void *of)
 {
-  const struct cu_hash_table_entry *entry = of;
+  const struct cu_hash_table_entry *const entry =
+    (const struct cu_hash_table_entry *) of;
 
   return htab_hash_string (entry->cu->die_symbol);
 }
@@ -6499,8 +6509,9 @@ htab_cu_hash (const void *of)
 static int
 htab_cu_eq (const void *of1, const void *of2)
 {
-  const struct cu_hash_table_entry *entry1 = of1;
-  const struct die_struct *entry2 = of2;
+  const struct cu_hash_table_entry *const entry1 =
+    (const struct cu_hash_table_entry *) of1;
+  const struct die_struct *const entry2 = (const struct die_struct *) of2;
 
   return !strcmp (entry1->cu->die_symbol, entry2->die_symbol);
 }
@@ -6508,7 +6519,8 @@ htab_cu_eq (const void *of1, const void *of2)
 static void
 htab_cu_del (void *what)
 {
-  struct cu_hash_table_entry *next, *entry = what;
+  struct cu_hash_table_entry *next,
+    *entry = (struct cu_hash_table_entry *) what;
 
   while (entry)
     {
@@ -6728,8 +6740,8 @@ build_abbrev_table (dw_die_ref die)
       if (abbrev_die_table_in_use >= abbrev_die_table_allocated)
        {
          n_alloc = abbrev_die_table_allocated + ABBREV_DIE_TABLE_INCREMENT;
-         abbrev_die_table = ggc_realloc (abbrev_die_table,
-                                         sizeof (dw_die_ref) * n_alloc);
+         abbrev_die_table = GGC_RESIZEVEC (dw_die_ref, abbrev_die_table,
+                                           n_alloc);
 
          memset (&abbrev_die_table[abbrev_die_table_allocated], 0,
                 (n_alloc - abbrev_die_table_allocated) * sizeof (dw_die_ref));
@@ -7119,7 +7131,7 @@ static inline dw_loc_list_ref
 new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end,
              const char *section, unsigned int gensym)
 {
-  dw_loc_list_ref retlist = ggc_alloc_cleared (sizeof (dw_loc_list_node));
+  dw_loc_list_ref retlist = GGC_CNEW (dw_loc_list_node);
 
   retlist->begin = begin;
   retlist->end = end;
@@ -7449,7 +7461,7 @@ output_comp_unit (dw_die_ref die, int output_if_empty)
   oldsym = die->die_symbol;
   if (oldsym)
     {
-      tmp = alloca (strlen (oldsym) + 24);
+      tmp = XALLOCAVEC (char, strlen (oldsym) + 24);
 
       sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym);
       secname = tmp;
@@ -7593,9 +7605,8 @@ add_arange (tree decl, dw_die_ref die)
   if (arange_table_in_use == arange_table_allocated)
     {
       arange_table_allocated += ARANGE_TABLE_INCREMENT;
-      arange_table = ggc_realloc (arange_table,
-                                 (arange_table_allocated
-                                  * sizeof (dw_die_ref)));
+      arange_table = GGC_RESIZEVEC (dw_die_ref, arange_table,
+                                   arange_table_allocated);
       memset (arange_table + arange_table_in_use, 0,
              ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref));
     }
@@ -7706,9 +7717,8 @@ add_ranges_num (int num)
   if (in_use == ranges_table_allocated)
     {
       ranges_table_allocated += RANGES_TABLE_INCREMENT;
-      ranges_table
-       = ggc_realloc (ranges_table, (ranges_table_allocated
-                                     * sizeof (struct dw_ranges_struct)));
+      ranges_table = GGC_RESIZEVEC (struct dw_ranges_struct, ranges_table,
+                                   ranges_table_allocated);
       memset (ranges_table + ranges_table_in_use, 0,
              RANGES_TABLE_INCREMENT * sizeof (struct dw_ranges_struct));
     }
@@ -7739,10 +7749,9 @@ add_ranges_by_labels (const char *begin, const char *end)
   if (in_use == ranges_by_label_allocated)
     {
       ranges_by_label_allocated += RANGES_TABLE_INCREMENT;
-      ranges_by_label
-       = ggc_realloc (ranges_by_label,
-                      (ranges_by_label_allocated
-                       * sizeof (struct dw_ranges_by_label_struct)));
+      ranges_by_label = GGC_RESIZEVEC (struct dw_ranges_by_label_struct,
+                                      ranges_by_label,
+                                      ranges_by_label_allocated);
       memset (ranges_by_label + ranges_by_label_in_use, 0,
              RANGES_TABLE_INCREMENT
              * sizeof (struct dw_ranges_by_label_struct));
@@ -7867,8 +7876,8 @@ struct dir_info
 static int
 file_info_cmp (const void *p1, const void *p2)
 {
-  const struct file_info *s1 = p1;
-  const struct file_info *s2 = p2;
+  const struct file_info *const s1 = (const struct file_info *) p1;
+  const struct file_info *const s2 = (const struct file_info *) p2;
   const unsigned char *cp1;
   const unsigned char *cp2;
 
@@ -7911,8 +7920,8 @@ struct file_name_acquire_data
 static int
 file_name_acquire (void ** slot, void *data)
 {
-  struct file_name_acquire_data *fnad = data;
-  struct dwarf_file_data *d = *slot;
+  struct file_name_acquire_data *fnad = (struct file_name_acquire_data *) data;
+  struct dwarf_file_data *d = (struct dwarf_file_data *) *slot;
   struct file_info *fi;
   const char *f;
 
@@ -7982,8 +7991,8 @@ output_file_names (void)
   numfiles = last_emitted_file->emitted_number;
 
   /* Allocate the various arrays we need.  */
-  files = alloca (numfiles * sizeof (struct file_info));
-  dirs = alloca (numfiles * sizeof (struct dir_info));
+  files = XALLOCAVEC (struct file_info, numfiles);
+  dirs = XALLOCAVEC (struct dir_info, numfiles);
 
   fnad.files = files;
   fnad.used_files = 0;
@@ -8041,8 +8050,8 @@ output_file_names (void)
      where we would have to check out every combination of every single
      possible prefix.  Instead we use a heuristic which provides nearly optimal
      results in most cases and never is much off.  */
-  saved = alloca (ndirs * sizeof (int));
-  savehere = alloca (ndirs * sizeof (int));
+  saved = XALLOCAVEC (int, ndirs);
+  savehere = XALLOCAVEC (int, ndirs);
 
   memset (saved, '\0', ndirs * sizeof (saved[0]));
   for (i = 0; i < ndirs; i++)
@@ -8108,7 +8117,7 @@ output_file_names (void)
   /* We have to emit them in the order of emitted_number since that's
      used in the debug info generation.  To do this efficiently we
      generate a back-mapping of the indices first.  */
-  backmap = alloca (numfiles * sizeof (int));
+  backmap = XALLOCAVEC (int, numfiles);
   for (i = 0; i < numfiles; i++)
     backmap[files[i].file_idx->emitted_number - 1] = i;
 
@@ -8901,7 +8910,7 @@ one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
    designates a value that spans more than one register.  */
 
 static dw_loc_descr_ref
-multiple_reg_loc_descriptor (rtx rtl, rtx regs, 
+multiple_reg_loc_descriptor (rtx rtl, rtx regs,
                             enum var_init_status initialized)
 {
   int nregs, size, i;
@@ -9289,7 +9298,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
       break;
 
     case CONCATN:
-      mem_loc_result = concatn_mem_loc_descriptor (rtl, mode, 
+      mem_loc_result = concatn_mem_loc_descriptor (rtl, mode,
                                                   VAR_INIT_STATUS_INITIALIZED);
       break;
 
@@ -9494,15 +9503,32 @@ 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)
@@ -9514,11 +9540,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;
@@ -9581,9 +9607,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:
@@ -10269,7 +10293,7 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
        if (SCALAR_FLOAT_MODE_P (mode))
          {
            unsigned int length = GET_MODE_SIZE (mode);
-           unsigned char *array = ggc_alloc (length);
+           unsigned char *array = GGC_NEWVEC (unsigned char, length);
 
            insert_float (rtl, array);
            add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
@@ -10290,7 +10314,7 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
        enum machine_mode mode = GET_MODE (rtl);
        unsigned int elt_size = GET_MODE_UNIT_SIZE (mode);
        unsigned int length = CONST_VECTOR_NUNITS (rtl);
-       unsigned char *array = ggc_alloc (length * elt_size);
+       unsigned char *array = GGC_NEWVEC (unsigned char, length * elt_size);
        unsigned int i;
        unsigned char *p;
 
@@ -10511,63 +10535,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
@@ -10804,86 +10771,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;
 }
 
 
@@ -10956,7 +10887,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
            enum var_init_status initialized =
              NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
            varloc = NOTE_VAR_LOCATION (node->var_loc_note);
-           add_loc_descr_to_loc_list (&list, 
+           add_loc_descr_to_loc_list (&list,
                                       loc_descriptor (varloc, initialized),
                                       node->label, node->next->label, secname);
          }
@@ -10978,7 +10909,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
                                           current_function_funcdef_no);
              endname = ggc_strdup (label_id);
            }
-         add_loc_descr_to_loc_list (&list, 
+         add_loc_descr_to_loc_list (&list,
                                     loc_descriptor (varloc, initialized),
                                     node->label, endname, secname);
        }
@@ -11063,7 +10994,8 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
   dw_cfa_location last_cfa, next_cfa;
   const char *start_label, *last_label, *section;
 
-  fde = &fde_table[fde_table_in_use - 1];
+  fde = current_fde ();
+  gcc_assert (fde != NULL);
 
   section = secname_for_decl (current_function_decl);
   list_tail = &list;
@@ -11210,9 +11142,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;
@@ -11896,8 +11826,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))
@@ -12430,7 +12359,7 @@ premark_used_types_helper (void **slot, void *data ATTRIBUTE_UNUSED)
   tree type;
   dw_die_ref die;
 
-  type = *slot;
+  type = (tree) *slot;
   die = lookup_type_die (type);
   if (die != NULL)
     die->die_perennial_p = 1;
@@ -12629,7 +12558,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_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
+             hot section and one 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);
@@ -12785,7 +12714,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);
@@ -12811,31 +12740,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;
     }
@@ -14225,13 +14154,13 @@ static void
 dwarf2out_global_decl (tree decl)
 {
   /* Output DWARF2 information for file-scope tentative data object
-     declarations, file-scope (extern) function declarations (which had no
-     corresponding body) and file-scope tagged type declarations and
-     definitions which have not yet been forced out.
+     declarations, file-scope (extern) function declarations (which
+     had no corresponding body) and file-scope tagged type declarations
+     and definitions which have not yet been forced out.
 
-     Ignore the global decl of any Fortran COMMON blocks which also wind up here
-     though they have already been described in the local scope for the 
-     procedures using them.  */
+     Ignore the global decl of any Fortran COMMON blocks which also
+     wind up here though they have already been described in the local
+     scope for the procedures using them.  */
   if (TREE_CODE (decl) == VAR_DECL
       && TREE_PUBLIC (decl) && TREE_STATIC (decl) && is_fortran ())
     return;
@@ -14494,15 +14423,16 @@ dwarf2out_ignore_block (const_tree block)
 static int
 file_table_eq (const void *p1_p, const void *p2_p)
 {
-  const struct dwarf_file_data * p1 = p1_p;
-  const char * p2 = p2_p;
+  const struct dwarf_file_data *const p1 =
+    (const struct dwarf_file_data *) p1_p;
+  const char *const p2 = (const char *) p2_p;
   return strcmp (p1->filename, p2) == 0;
 }
 
 static hashval_t
 file_table_hash (const void *p_p)
 {
-  const struct dwarf_file_data * p = p_p;
+  const struct dwarf_file_data *const p = (const struct dwarf_file_data *) p_p;
   return htab_hash_string (p->filename);
 }
 
@@ -14534,9 +14464,9 @@ lookup_filename (const char *file_name)
   slot = htab_find_slot_with_hash (file_table, file_name,
                                   htab_hash_string (file_name), INSERT);
   if (*slot)
-    return *slot;
+    return (struct dwarf_file_data *) *slot;
 
-  created = ggc_alloc (sizeof (struct dwarf_file_data));
+  created = GGC_NEW (struct dwarf_file_data);
   created->filename = file_name;
   created->emitted_number = 0;
   *slot = created;
@@ -14590,7 +14520,7 @@ dwarf2out_var_location (rtx loc_note)
     return;
   prev_insn = PREV_INSN (loc_note);
 
-  newloc = ggc_alloc_cleared (sizeof (struct var_loc_node));
+  newloc = GGC_CNEW (struct var_loc_node);
   /* If the insn we processed last time is the previous insn
      and it is also a var location note, use the label we emitted
      last time.  */
@@ -14678,9 +14608,9 @@ dwarf2out_source_line (unsigned int line, const char *filename)
            {
              separate_line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
              separate_line_info_table
-               = ggc_realloc (separate_line_info_table,
-                              separate_line_info_table_allocated
-                              * sizeof (dw_separate_line_info_entry));
+               = GGC_RESIZEVEC (dw_separate_line_info_entry,
+                                separate_line_info_table,
+                                separate_line_info_table_allocated);
              memset (separate_line_info_table
                       + separate_line_info_table_in_use,
                      0,
@@ -14707,9 +14637,8 @@ dwarf2out_source_line (unsigned int line, const char *filename)
            {
              line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
              line_info_table
-               = ggc_realloc (line_info_table,
-                              (line_info_table_allocated
-                               * sizeof (dw_line_info_entry)));
+               = GGC_RESIZEVEC (dw_line_info_entry, line_info_table,
+                                line_info_table_allocated);
              memset (line_info_table + line_info_table_in_use, 0,
                      LINE_INFO_TABLE_INCREMENT * sizeof (dw_line_info_entry));
            }
@@ -14820,15 +14749,13 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
   decl_scope_table = VEC_alloc (tree, gc, 256);
 
   /* Allocate the initial hunk of the abbrev_die_table.  */
-  abbrev_die_table = ggc_alloc_cleared (ABBREV_DIE_TABLE_INCREMENT
-                                       * sizeof (dw_die_ref));
+  abbrev_die_table = GGC_CNEWVEC (dw_die_ref, ABBREV_DIE_TABLE_INCREMENT);
   abbrev_die_table_allocated = ABBREV_DIE_TABLE_INCREMENT;
   /* Zero-th entry is allocated, but unused.  */
   abbrev_die_table_in_use = 1;
 
   /* Allocate the initial hunk of the line_info_table.  */
-  line_info_table = ggc_alloc_cleared (LINE_INFO_TABLE_INCREMENT
-                                      * sizeof (dw_line_info_entry));
+  line_info_table = GGC_CNEWVEC (dw_line_info_entry, LINE_INFO_TABLE_INCREMENT);
   line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
 
   /* Zero-th entry is allocated, but unused.  */
@@ -15192,8 +15119,8 @@ prune_unused_types (void)
 static int
 file_table_relative_p (void ** slot, void *param)
 {
-  bool *p = param;
-  struct dwarf_file_data *d = *slot;
+  bool *p = (bool *) param;
+  struct dwarf_file_data *d = (struct dwarf_file_data *) *slot;
   if (!IS_ABSOLUTE_PATH (d->filename))
     {
       *p = true;