OSDN Git Service

* c-lex.c (read_escape, read_ucs): Delete.
[pf3gnuchains/gcc-fork.git] / gcc / varasm.c
index b87d9be..3e7b295 100644 (file)
@@ -37,7 +37,6 @@ Boston, MA 02111-1307, USA.  */
 #include "expr.h"
 #include "hard-reg-set.h"
 #include "regs.h"
-#include "defaults.h"
 #include "output.h"
 #include "real.h"
 #include "toplev.h"
@@ -62,15 +61,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 /* Define the prefix to use when check_memory_usage_flag is enable.  */
-#ifdef NO_DOLLAR_IN_LABEL
-#ifdef NO_DOT_IN_LABEL
-#define CHKR_PREFIX "chkr_prefix_"
-#else /* !NO_DOT_IN_LABEL */
-#define CHKR_PREFIX "chkr."
-#endif 
-#else /* !NO_DOLLAR_IN_LABEL */
-#define CHKR_PREFIX "chkr$"
-#endif
+#define CHKR_PREFIX "_CHKR_"
 #define CHKR_PREFIX_SIZE (sizeof (CHKR_PREFIX) - 1)
 
 /* File in which assembler code is being written.  */
@@ -108,7 +99,7 @@ struct varasm_status
   struct pool_constant *x_first_pool, *x_last_pool;
 
   /* Current offset in constant pool (does not include any machine-specific
-     header.  */
+     header).  */
   int x_pool_offset;
 
   /* Chain of all CONST_DOUBLE rtx's constructed for the current function.
@@ -169,9 +160,10 @@ static struct constant_descriptor *record_constant_rtx PARAMS ((enum machine_mod
 static struct pool_constant *find_pool_constant PARAMS ((struct function *, rtx));
 static void mark_constant_pool         PARAMS ((void));
 static void mark_constants             PARAMS ((rtx));
+static int mark_constant               PARAMS ((rtx *current_rtx, void *data));
 static int output_addressed_constants  PARAMS ((tree));
 static void output_after_function_constants PARAMS ((void));
-static int array_size_for_constructor  PARAMS ((tree));
+static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
 static void output_constructor         PARAMS ((tree, int));
 #ifdef ASM_WEAKEN_LABEL
 static void remove_from_pending_weak_list      PARAMS ((const char *));
@@ -325,30 +317,6 @@ named_section (decl, name, reloc)
     }
 }
 
-#ifdef ASM_OUTPUT_SECTION_NAME
-#ifndef UNIQUE_SECTION
-#define UNIQUE_SECTION(DECL,RELOC)                             \
-do {                                                           \
-  int len;                                                     \
-  const char *name;                                            \
-  char *string;                                                        \
-                                                               \
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL));      \
-  /* Strip off any encoding in name.  */                       \
-  STRIP_NAME_ENCODING (name, name);                            \
-                                                               \
-  len = strlen (name) + 1;                                     \
-  string = alloca (len + 1);                                   \
-  sprintf (string, ".%s", name);                               \
-                                                               \
-  DECL_SECTION_NAME (DECL) = build_string (len, string);       \
-} while (0)
-#endif
-#ifndef UNIQUE_SECTION_P
-#define UNIQUE_SECTION_P(DECL) 0
-#endif
-#endif
-
 #ifdef BSS_SECTION_ASM_OP
 
 /* Tell the assembler to switch to the bss section.  */
@@ -514,83 +482,6 @@ exception_section ()
 #endif
 }
 \f
-/* Create the rtl to represent a function, for a function definition.
-   DECL is a FUNCTION_DECL node which describes which function.
-   The rtl is stored into DECL.  */
-
-void
-make_function_rtl (decl)
-     tree decl;
-{
-  const char *name;
-  const char *new_name;
-
-  if (DECL_RTL (decl) != 0)
-    {
-      /* ??? Another way to do this would be to do what halfpic.c does
-        and maintain a hashed table of such critters.  */
-      /* ??? Another way to do this would be to pass a flag bit to
-        ENCODE_SECTION_INFO saying whether this is a new decl or not.  */
-      /* Let the target reassign the RTL if it wants.
-        This is necessary, for example, when one machine specific
-        decl attribute overrides another.  */
-#ifdef REDO_SECTION_INFO_P
-      if (REDO_SECTION_INFO_P (decl))
-       ENCODE_SECTION_INFO (decl);
-#endif
-      return;
-    }
-
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  new_name = name;
-
-  /* Rename a nested function to avoid conflicts, unless it's a member of
-     a local class, in which case the class name is already unique.  */
-  if (decl_function_context (decl) != 0
-      && ! TYPE_P (DECL_CONTEXT (decl))
-      && DECL_INITIAL (decl) != 0
-      && DECL_RTL (decl) == 0)
-    {
-      char *label;
-      ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
-      var_labelno++;
-      new_name = label;
-    }
-  /* When -fprefix-function-name is used, every function name is
-     prefixed.  Even static functions are prefixed because they
-     could be declared latter.  Note that a nested function name
-     is not prefixed.  */
-  else if (flag_prefix_function_name)
-    {
-      size_t name_len = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
-      char *pname;
-
-      pname = alloca (name_len + CHKR_PREFIX_SIZE + 1);
-      memcpy (pname, CHKR_PREFIX, CHKR_PREFIX_SIZE);
-      memcpy (pname + CHKR_PREFIX_SIZE, name, name_len + 1);
-      new_name = pname;
-    }
-
-  if (name != new_name)
-    {
-      DECL_ASSEMBLER_NAME (decl) = get_identifier (new_name);
-      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-    }
-
-  DECL_RTL (decl)
-    = gen_rtx_MEM (DECL_MODE (decl),
-                  gen_rtx_SYMBOL_REF (Pmode, name));
-
-  /* Optionally set flags or add text to the name to record
-     information such as that it is a function name.  If the name
-     is changed, the macro ASM_OUTPUT_LABELREF will have to know
-     how to strip this information.  */
-#ifdef ENCODE_SECTION_INFO
-  ENCODE_SECTION_INFO (decl);
-#endif
-}
-
-
 /* Given NAME, a putative register name, discard any customary prefixes.  */
 
 static const char *
@@ -666,27 +557,46 @@ decode_reg_name (asmspec)
   return -1;
 }
 \f
-/* Create the DECL_RTL for a declaration for a static or external variable
-   or static or external function.
-   ASMSPEC, if not 0, is the string which the user specified
-   as the assembler symbol name.
-   TOP_LEVEL is nonzero if this is a file-scope variable.
+/* Create the DECL_RTL for a VAR_DECL or FUNCTION_DECL.  DECL should
+   have static storage duration.  In other words, it should not be an
+   automatic variable, including PARM_DECLs.
+
+   There is, however, one exception: this function handles variables
+   explicitly placed in a particular register by the user.
+
+   ASMSPEC, if not 0, is the string which the user specified as the
+   assembler symbol name.
 
    This is never called for PARM_DECL nodes.  */
 
 void
-make_decl_rtl (decl, asmspec, top_level)
+make_decl_rtl (decl, asmspec)
      tree decl;
      const char *asmspec;
-     int top_level;
 {
+  int top_level = (DECL_CONTEXT (decl) == NULL_TREE);
   const char *name = 0;
   const char *new_name = 0;
   int reg_number;
 
+  /* Check that we are not being given an automatic variable.  */
+  /* A weak alias has TREE_PUBLIC set but not the other bits.  */
+  if (TREE_CODE (decl) == PARM_DECL
+      || TREE_CODE (decl) == RESULT_DECL
+      || (TREE_CODE (decl) == VAR_DECL
+         && !TREE_STATIC (decl)
+         && !TREE_PUBLIC (decl)
+         && !DECL_EXTERNAL (decl)
+         && !DECL_REGISTER (decl)))
+    abort ();
+  /* And that we were not given a type or a label.  */
+  else if (TREE_CODE (decl) == TYPE_DECL 
+          || TREE_CODE (decl) == LABEL_DECL)
+    abort ();
+
   /* For a duplicate declaration, we can be called twice on the
      same DECL node.  Don't discard the RTL already made.  */
-  if (DECL_RTL (decl) != 0)
+  if (DECL_RTL_SET_P (decl))
     {
       /* If the old RTL had the wrong mode, fix the mode.  */
       if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
@@ -740,7 +650,7 @@ make_decl_rtl (decl, asmspec, top_level)
        {
          int nregs;
 
-         if (DECL_INITIAL (decl) != 0 && top_level)
+         if (DECL_INITIAL (decl) != 0 && TREE_STATIC (decl))
            {
              DECL_INITIAL (decl) = 0;
              error ("global register variable has initial value");
@@ -754,12 +664,13 @@ make_decl_rtl (decl, asmspec, top_level)
             usage is somewhat suspect, we nevertheless use the following
             kludge to avoid setting DECL_RTL to frame_pointer_rtx.  */
 
-         DECL_RTL (decl)
-           = gen_rtx_REG (DECL_MODE (decl), FIRST_PSEUDO_REGISTER);
+         SET_DECL_RTL (decl,
+                       gen_rtx_REG (DECL_MODE (decl), 
+                                    FIRST_PSEUDO_REGISTER));
          REGNO (DECL_RTL (decl)) = reg_number;
          REG_USERVAR_P (DECL_RTL (decl)) = 1;
 
-         if (top_level)
+         if (TREE_STATIC (decl))
            {
              /* Make this register global, so not usable for anything
                 else.  */
@@ -797,7 +708,8 @@ make_decl_rtl (decl, asmspec, top_level)
      Concatenate a distinguishing number.  */
   if (!top_level && !TREE_PUBLIC (decl)
       && ! (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
-      && asmspec == 0)
+      && asmspec == 0
+      && name == IDENTIFIER_POINTER (DECL_NAME (decl)))
     {
       char *label;
       ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
@@ -821,7 +733,7 @@ make_decl_rtl (decl, asmspec, top_level)
 
   if (name != new_name)
     {
-      DECL_ASSEMBLER_NAME (decl) = get_identifier (new_name);
+      SET_DECL_ASSEMBLER_NAME (decl, get_identifier (new_name));
       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     }
 
@@ -833,8 +745,9 @@ make_decl_rtl (decl, asmspec, top_level)
           && (TREE_PUBLIC (decl) || TREE_STATIC (decl)))))
     TREE_SIDE_EFFECTS (decl) = 1;
 
-  DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl),
-                                gen_rtx_SYMBOL_REF (Pmode, name));
+  SET_DECL_RTL (decl, gen_rtx_MEM (DECL_MODE (decl),
+                                  gen_rtx_SYMBOL_REF (Pmode, name)));
+  SYMBOL_REF_WEAK (XEXP (DECL_RTL (decl), 0)) = DECL_WEAK (decl);
   if (TREE_CODE (decl) != FUNCTION_DECL)
     set_mem_attributes (DECL_RTL (decl), decl, 1);
 
@@ -1328,7 +1241,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
 
   last_assemble_variable_decl = 0;
 
-  if (GET_CODE (DECL_RTL (decl)) == REG)
+  if (DECL_RTL_SET_P (decl) && GET_CODE (DECL_RTL (decl)) == REG)
     {
       /* Do output symbol info for global register variables, but do nothing
         else for them.  */
@@ -1712,6 +1625,13 @@ void
 assemble_external (decl)
      tree decl ATTRIBUTE_UNUSED;
 {
+  /* Because most platforms do not define ASM_OUTPUT_EXTERNAL, the
+     main body of this code is only rarely exercised.  To provide some
+     testing, on all platforms, we make sure that the ASM_OUT_FILE is
+     open.  If it's not, we should not be calling this function.  */
+  if (!asm_out_file)
+    abort ();
+
 #ifdef ASM_OUTPUT_EXTERNAL
   if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
     {
@@ -2027,7 +1947,7 @@ assemble_real (d, mode)
       abort ();
     }
 
-  set_float_handler (NULL_PTR);
+  set_float_handler (NULL);
 }
 \f
 /* Here we combine duplicate floating constants to make
@@ -2072,7 +1992,7 @@ immed_double_const (i0, i1, mode)
         represented as a 64 bit value -1, and not as 0x00000000ffffffff.
         The later confuses the sparc backend.  */
 
-      if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width
+      if (width < HOST_BITS_PER_WIDE_INT
          && (i0 & ((HOST_WIDE_INT) 1 << (width - 1))))
        i0 |= ((HOST_WIDE_INT) (-1) << width);
 
@@ -2303,15 +2223,11 @@ decode_addr_const (exp, value)
   value->offset = offset;
 }
 \f
+enum kind { RTX_DOUBLE, RTX_INT };
 struct rtx_const
 {
-#ifdef ONLY_INT_FIELDS
-  unsigned int kind : 16;
-  unsigned int mode : 16;
-#else
-  enum kind kind : 16;
-  enum machine_mode mode : 16;
-#endif
+  ENUM_BITFIELD(kind) kind : 16;
+  ENUM_BITFIELD(machine_mode) mode : 16;
   union {
     union real_extract du;
     struct addr_const addr;
@@ -2533,7 +2449,7 @@ const_hash (exp)
       
     default:
       /* A language specific constant. Just hash the code. */
-      return code % MAX_HASH_TABLE;
+      return (int) code % MAX_HASH_TABLE;
     }
 
   /* Compute hashing function */
@@ -3446,7 +3362,6 @@ free_varasm_status (f)
   f->varasm = NULL;
 }
 \f
-enum kind { RTX_DOUBLE, RTX_INT };
 
 /* Express an rtx for a constant integer (perhaps symbolic)
    as the sum of a symbol or label plus an explicit integer.
@@ -3682,6 +3597,9 @@ force_const_mem (mode, x)
       pool_offset += align - 1;
       pool_offset &= ~ (align - 1);
 
+      if (GET_CODE (x) == LABEL_REF)
+       LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
+
       /* Allocate a pool constant descriptor, fill it in, and chain it in.  */
 
       pool = (struct pool_constant *) ggc_alloc (sizeof (struct pool_constant));
@@ -3927,7 +3845,8 @@ output_constant_pool (fnname, fndecl)
 }
 
 /* Look through the instructions for this function, and mark all the
-   entries in the constant pool which are actually being used.  */
+   entries in the constant pool which are actually being used.
+   Emit used deferred strings.  */
 
 static void
 mark_constant_pool ()
@@ -3950,41 +3869,16 @@ mark_constant_pool ()
        insn = XEXP (insn, 1))
     if (INSN_P (insn))
       mark_constants (PATTERN (insn));
-
-  /* It's possible that the only reference to a symbol is in a symbol
-     that's in the constant pool.  This happens in Fortran under some
-     situations.  (When the constant contains the address of another
-     constant, and only the first is used directly in an insn.) 
-     This is potentially suboptimal if there's ever a possibility of
-     backwards (in pool order) 2'd level references.  However, it's
-     not clear that 2'd level references can happen. */
-  for (pool = first_pool; pool; pool = pool->next)
-    {
-      struct pool_constant *tem;
-      const char *label;
-
-      /* skip unmarked entries; no insn refers to them. */
-      if (!pool->mark)
-         continue;
-
-      /* Skip everything except SYMBOL_REFs.  */
-      if (GET_CODE (pool->constant) != SYMBOL_REF)
-       continue;
-      label = XSTR (pool->constant, 0);
-
-      /* Be sure the symbol's value is marked. */
-      for (tem = const_rtx_sym_hash_table[SYMHASH (label)]; tem; 
-           tem = tem->next)
-         if (tem->label == label)
-           tem->mark = 1;
-      /* If we didn't find it, there's something truly wrong here, but it
-        will be announced by the assembler. */
-    }
 }
 
+/* Look through appropriate parts of X, marking all entries in the
+   constant pool which are actually being used.  Entries that are only
+   referenced by other constants are also marked as used.  Emit
+   deferred strings that are used.  */
+
 static void
 mark_constants (x)
-     register rtx x;
+     rtx x;
 {
   register int i;
   register const char *format_ptr;
@@ -3994,24 +3888,7 @@ mark_constants (x)
 
   if (GET_CODE (x) == SYMBOL_REF)
     {
-      if (CONSTANT_POOL_ADDRESS_P (x))
-       find_pool_constant (cfun, x)->mark = 1;
-      else if (STRING_POOL_ADDRESS_P (x))
-       {
-         struct deferred_string **defstr;
-
-         defstr = (struct deferred_string **)
-                  htab_find_slot_with_hash (const_str_htab, XSTR (x, 0),
-                                            STRHASH (XSTR (x, 0)), NO_INSERT);
-         if (defstr)
-           {
-             struct deferred_string *p = *defstr;
-
-             STRING_POOL_ADDRESS_P (x) = 0;
-             output_constant_def_contents (p->exp, 0, p->labelno);
-             htab_clear_slot (const_str_htab, (void **) defstr);
-           }
-       }
+      mark_constant (&x, NULL);
       return;
     }
   /* Never search inside a CONST_DOUBLE, because CONST_DOUBLE_MEM may be
@@ -4062,6 +3939,55 @@ mark_constants (x)
        }
     }
 }
+
+/* Given a SYMBOL_REF CURRENT_RTX, mark it and all constants it refers
+   to as used.  Emit referenced deferred strings.  This function can
+   be used with for_each_rtx () to mark all SYMBOL_REFs in an rtx.  */
+
+static int
+mark_constant (current_rtx, data)
+     rtx *current_rtx;
+     void *data ATTRIBUTE_UNUSED;
+{
+  rtx x = *current_rtx;
+
+  if (x == NULL_RTX)
+    return 0;
+  else if (GET_CODE(x) == CONST_DOUBLE)
+    /* Never search inside a CONST_DOUBLE because CONST_DOUBLE_MEM may
+       be a MEM but does not constitute a use of that MEM.  */
+    return -1;
+  else if (GET_CODE (x) == SYMBOL_REF)
+    {
+      if (CONSTANT_POOL_ADDRESS_P (x))
+       {
+         struct pool_constant *pool = find_pool_constant (cfun, x);
+         if (pool->mark == 0) {
+           pool->mark = 1;
+           for_each_rtx (&(pool->constant), &mark_constant, NULL);
+         }
+         else
+           return -1;
+       }
+      else if (STRING_POOL_ADDRESS_P (x))
+       {
+         struct deferred_string **defstr;
+
+         defstr = (struct deferred_string **)
+           htab_find_slot_with_hash (const_str_htab, XSTR (x, 0),
+                                     STRHASH (XSTR (x, 0)), NO_INSERT);
+         if (defstr)
+           {
+             struct deferred_string *p = *defstr;
+
+             STRING_POOL_ADDRESS_P (x) = 0;
+             output_constant_def_contents (p->exp, 0, p->labelno);
+             htab_clear_slot (const_str_htab, (void **) defstr);
+           }
+       }
+    }
+  return 0;
+}
 \f
 /* Find all the constants whose addresses are referenced inside of EXP,
    and make sure assembler code with a label has been output for each one.
@@ -4323,7 +4249,10 @@ output_constant (exp, size)
      directly.  Give the front-end a chance to convert EXP to a
      language-independent representation.  */
   if (lang_expand_constant)
-    exp = (*lang_expand_constant) (exp);
+    {
+      exp = (*lang_expand_constant) (exp);
+      code = TREE_CODE (TREE_TYPE (exp));
+    }
 
   if (size == 0 || flag_syntax_only)
     return;
@@ -4446,19 +4375,12 @@ output_constant (exp, size)
    arrays of unspecified length.  VAL must be a CONSTRUCTOR of an array
    type with an unspecified upper bound.  */
 
-static int
+static unsigned HOST_WIDE_INT
 array_size_for_constructor (val)
      tree val;
 {
   tree max_index, i;
 
-  if (!val || TREE_CODE (val) != CONSTRUCTOR
-      || TREE_CODE (TREE_TYPE (val)) != ARRAY_TYPE
-      || TYPE_DOMAIN (TREE_TYPE (val)) == NULL_TREE
-      || TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (val))) != NULL_TREE
-      || TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (val))) == NULL_TREE)
-    abort ();
-
   max_index = NULL_TREE;
   for (i = CONSTRUCTOR_ELTS (val); i ; i = TREE_CHAIN (i))
     {
@@ -4470,20 +4392,17 @@ array_size_for_constructor (val)
        max_index = index;
     }
 
-  /* ??? I'm fairly certain if there were no elements, we shouldn't have
-     created the constructor in the first place.  */
   if (max_index == NULL_TREE)
-    abort ();
+    return 0;
 
   /* Compute the total number of array elements.  */
-  i = fold (build (MINUS_EXPR, TREE_TYPE (max_index), max_index
-                  TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (val)))));
-  i = fold (build (PLUS_EXPR, TREE_TYPE (i), i,
-                  convert (TREE_TYPE (i), integer_one_node)));
+  i = size_binop (MINUS_EXPR, convert (sizetype, max_index)
+                 convert (sizetype,
+                          TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (val)))));
+  i = size_binop (PLUS_EXPR, i, convert (sizetype, integer_one_node));
 
   /* Multiply by the array element unit size to find number of bytes.  */
-  i = fold (build (MULT_EXPR, TREE_TYPE (max_index), i,
-                  TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (val)))));
+  i = size_binop (MULT_EXPR, i, TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (val))));
 
   return tree_low_cst (i, 1);
 }
@@ -4549,7 +4468,7 @@ output_constructor (exp, size)
 
       if (index && TREE_CODE (index) == RANGE_EXPR)
        {
-         register int fieldsize
+         unsigned HOST_WIDE_INT fieldsize
            = int_size_in_bytes (TREE_TYPE (type));
          HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0);
          HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0);
@@ -4571,7 +4490,7 @@ output_constructor (exp, size)
        {
          /* An element that is not a bit-field.  */
 
-         register int fieldsize;
+         unsigned HOST_WIDE_INT fieldsize;
          /* Since this structure is static,
             we know the positions are constant.  */
          HOST_WIDE_INT pos = field ? int_byte_position (field) : 0;
@@ -4607,19 +4526,30 @@ output_constructor (exp, size)
          /* Determine size this element should occupy.  */
          if (field)
            {
-             if (DECL_SIZE_UNIT (field)
-                 && ! integer_zerop (DECL_SIZE_UNIT (field)))
-               fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
-             else if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+             fieldsize = 0;
+
+             /* If this is an array with an unspecified upper bound,
+                the initializer determines the size.  */
+             /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL,
+                but we cannot do this until the deprecated support for
+                initializing zero-length array members is removed.  */
+             if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
+                 && TYPE_DOMAIN (TREE_TYPE (field))
+                 && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))
                {
-                 /* If DECL_SIZE is not set or is zero, then this must be
-                    an array of unspecified length.  The initialized value
-                    must be a CONSTRUCTOR, and we take the length from the
-                    last initialized element.  */
                  fieldsize = array_size_for_constructor (val);
+                 /* Given a non-empty initialization, this field had
+                    better be last.  */
+                 if (fieldsize != 0 && TREE_CHAIN (field) != NULL_TREE)
+                   abort ();
+               }
+             else if (DECL_SIZE_UNIT (field))
+               {
+                 /* ??? This can't be right.  If the decl size overflows
+                    a host integer we will silently emit no data.  */
+                 if (host_integerp (DECL_SIZE_UNIT (field), 1))
+                   fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
                }
-             else
-               fieldsize = 0;
            }
          else
            fieldsize = int_size_in_bytes (TREE_TYPE (type));
@@ -4880,8 +4810,11 @@ assemble_alias (decl, target)
 {
   const char *name;
 
-  make_decl_rtl (decl, (char *) 0, 1);
-  name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+  /* We must force creation of DECL_RTL for debug info generation, even though
+     we don't use it here.  */
+  make_decl_rtl (decl, NULL);
+
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
 
 #ifdef ASM_OUTPUT_DEF
   /* Make name accessible from other files, if appropriate.  */
@@ -4921,15 +4854,6 @@ assemble_alias (decl, target)
 #endif
 }
 
-/* This determines whether or not we support link-once semantics.  */
-#ifndef SUPPORTS_ONE_ONLY
-#ifdef MAKE_DECL_ONE_ONLY
-#define SUPPORTS_ONE_ONLY 1
-#else
-#define SUPPORTS_ONE_ONLY 0
-#endif
-#endif
-
 /* Returns 1 if the target configuration supports defining public symbols
    so that one of them will be chosen at link time instead of generating a
    multiply-defined symbol error, whether through the use of weak symbols or