OSDN Git Service

libcpp/
[pf3gnuchains/gcc-fork.git] / gcc / varasm.c
index 88068b5..f21c4b9 100644 (file)
@@ -844,7 +844,8 @@ decode_reg_name (const char *asmspec)
          = ADDITIONAL_REGISTER_NAMES;
 
        for (i = 0; i < (int) ARRAY_SIZE (table); i++)
-         if (! strcmp (asmspec, table[i].name))
+         if (table[i].name[0]
+             && ! strcmp (asmspec, table[i].name))
            return table[i].number;
       }
 #endif /* ADDITIONAL_REGISTER_NAMES */
@@ -922,10 +923,16 @@ make_decl_rtl (tree decl)
     }
 
   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
-  if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
+  
+  if (name[0] != '*' && TREE_CODE (decl) != FUNCTION_DECL
+      && DECL_REGISTER (decl))
+    {
+      error ("register name not specified for %q+D", decl);    
+    }
+  else if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
     {
-      reg_number = decode_reg_name (name);
+      const char *asmspec = name+1;
+      reg_number = decode_reg_name (asmspec);
       /* First detect errors in declaring global registers.  */
       if (reg_number == -1)
        error ("register name not specified for %q+D", decl);
@@ -3846,12 +3853,50 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
   if (size == 0 || flag_syntax_only)
     return;
 
+  /* See if we're trying to initialize a pointer in a non-default mode
+     to the address of some declaration somewhere.  If the target says
+     the mode is valid for pointers, assume the target has a way of
+     resolving it.  */
+  if (TREE_CODE (exp) == NOP_EXPR
+      && POINTER_TYPE_P (TREE_TYPE (exp))
+      && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+    {
+      tree saved_type = TREE_TYPE (exp);
+
+      /* Peel off any intermediate conversions-to-pointer for valid
+        pointer modes.  */
+      while (TREE_CODE (exp) == NOP_EXPR
+            && POINTER_TYPE_P (TREE_TYPE (exp))
+            && targetm.valid_pointer_mode (TYPE_MODE (TREE_TYPE (exp))))
+       exp = TREE_OPERAND (exp, 0);
+
+      /* If what we're left with is the address of something, we can
+        convert the address to the final type and output it that
+        way.  */
+      if (TREE_CODE (exp) == ADDR_EXPR)
+       exp = build1 (ADDR_EXPR, saved_type, TREE_OPERAND (exp, 0));
+    }
+
   /* Eliminate any conversions since we'll be outputting the underlying
      constant.  */
   while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
         || TREE_CODE (exp) == NON_LVALUE_EXPR
         || TREE_CODE (exp) == VIEW_CONVERT_EXPR)
-    exp = TREE_OPERAND (exp, 0);
+    {
+      HOST_WIDE_INT type_size = int_size_in_bytes (TREE_TYPE (exp));
+      HOST_WIDE_INT op_size = int_size_in_bytes (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+      /* Make sure eliminating the conversion is really a no-op, except with
+        VIEW_CONVERT_EXPRs to allow for wild Ada unchecked conversions and
+        union types to allow for Ada unchecked unions.  */
+      if (type_size != op_size
+         && TREE_CODE (exp) != VIEW_CONVERT_EXPR
+         && TREE_CODE (TREE_TYPE (exp)) != UNION_TYPE)
+       internal_error ("no-op convert from %wd to %wd bytes in initializer",
+                       op_size, type_size);
+
+      exp = TREE_OPERAND (exp, 0);
+    }
 
   code = TREE_CODE (TREE_TYPE (exp));
   thissize = int_size_in_bytes (TREE_TYPE (exp));
@@ -5017,47 +5062,7 @@ default_select_section (tree decl, int reloc,
     data_section ();
 }
 
-/* A helper function for default_elf_select_section and
-   default_elf_unique_section.  Categorizes the DECL.  */
-
 enum section_category
-{
-  SECCAT_TEXT,
-
-  SECCAT_RODATA,
-  SECCAT_RODATA_MERGE_STR,
-  SECCAT_RODATA_MERGE_STR_INIT,
-  SECCAT_RODATA_MERGE_CONST,
-  SECCAT_SRODATA,
-
-  SECCAT_DATA,
-
-  /* To optimize loading of shared programs, define following subsections
-     of data section:
-       _REL    Contains data that has relocations, so they get grouped
-               together and dynamic linker will visit fewer pages in memory.
-       _RO     Contains data that is otherwise read-only.  This is useful
-               with prelinking as most relocations won't be dynamically
-               linked and thus stay read only.
-       _LOCAL  Marks data containing relocations only to local objects.
-               These relocations will get fully resolved by prelinking.  */
-  SECCAT_DATA_REL,
-  SECCAT_DATA_REL_LOCAL,
-  SECCAT_DATA_REL_RO,
-  SECCAT_DATA_REL_RO_LOCAL,
-
-  SECCAT_SDATA,
-  SECCAT_TDATA,
-
-  SECCAT_BSS,
-  SECCAT_SBSS,
-  SECCAT_TBSS
-};
-
-static enum section_category
-categorize_decl_for_section (tree, int, int);
-
-static enum section_category
 categorize_decl_for_section (tree decl, int reloc, int shlib)
 {
   enum section_category ret;