OSDN Git Service

* src/x86/win32.S (_ffi_closure_STDCALL): New function.
[pf3gnuchains/gcc-fork.git] / gcc / varasm.c
index e74adae..c85cf9d 100644 (file)
@@ -1,6 +1,6 @@
 /* Output variables, constants and external declarations, for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -42,7 +42,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "output.h"
 #include "toplev.h"
 #include "hashtab.h"
-#include "c-pragma.h"
 #include "ggc.h"
 #include "langhooks.h"
 #include "tm_p.h"
@@ -449,7 +448,7 @@ emutls_common_1 (void **loc, void *xstmts)
 void
 emutls_finish (void)
 {
-  if (!targetm.emutls.register_common)
+  if (targetm.emutls.register_common)
     {
       tree body = NULL_TREE;
 
@@ -869,11 +868,18 @@ default_function_rodata_section (tree decl)
 
       if (DECL_ONE_ONLY (decl) && HAVE_COMDAT_GROUP)
         {
-         size_t len = strlen (name) + 3;
-         char* rname = (char *) alloca (len);
+         const char *dot;
+         size_t len;
+         char* rname;
+
+         dot = strchr (name + 1, '.');
+         if (!dot)
+           dot = name;
+         len = strlen (dot) + 8;
+         rname = (char *) alloca (len);
 
          strcpy (rname, ".rodata");
-         strcat (rname, name + 5);
+         strcat (rname, dot);
          return get_section (rname, SECTION_LINKONCE, decl);
        }
       /* For .gnu.linkonce.t.foo we want to use .gnu.linkonce.r.foo.  */
@@ -1677,7 +1683,7 @@ assemble_start_function (tree decl, const char *fnname)
       /* When the function starts with a cold section, we need to explicitly
         align the hot section and write out the hot section label.
         But if the current function is a thunk, we do not have a CFG.  */
-      if (!crtl->is_thunk
+      if (!cfun->is_thunk
          && BB_PARTITION (ENTRY_BLOCK_PTR->next_bb) == BB_COLD_PARTITION)
        {
          switch_to_section (text_section);
@@ -2161,7 +2167,6 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
   /* First make the assembler name(s) global if appropriate.  */
   sect = get_variable_section (decl, false);
   if (TREE_PUBLIC (decl)
-      && DECL_NAME (decl)
       && (sect->common.flags & SECTION_COMMON) == 0)
     globalize_decl (decl);
 
@@ -2250,7 +2255,7 @@ incorporeal_function_p (tree decl)
        return true;
 
       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-      if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
+      if (is_builtin_name (name))
        return true;
     }
   return false;
@@ -2290,9 +2295,10 @@ process_pending_assemble_externals (void)
    to be emitted.  */
 static GTY(()) tree weak_decls;
 
-/* Output something to declare an external symbol to the assembler.
-   (Most assemblers don't need this, so we normally output nothing.)
-   Do nothing if DECL is not external.  */
+/* Output something to declare an external symbol to the assembler,
+   and qualifiers such as weakness.  (Most assemblers don't need
+   extern declaration, so we normally output nothing.)  Do nothing if
+   DECL is not external.  */
 
 void
 assemble_external (tree decl ATTRIBUTE_UNUSED)
@@ -2303,17 +2309,26 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
      open.  If it's not, we should not be calling this function.  */
   gcc_assert (asm_out_file);
 
-#ifdef ASM_OUTPUT_EXTERNAL
   if (!DECL_P (decl) || !DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
     return;
 
-  if (SUPPORTS_WEAK && DECL_WEAK (decl))
-    weak_decls = tree_cons (NULL, decl, weak_decls);
+  /* We want to output annotation for weak and external symbols at
+     very last to check if they are references or not.  */
+
+  if (SUPPORTS_WEAK && DECL_WEAK (decl)
+      /* TREE_STATIC is a weird and abused creature which is not
+        generally the right test for whether an entity has been
+        locally emitted, inlined or otherwise not-really-extern, but
+        for declarations that can be weak, it happens to be
+        match.  */
+      && !TREE_STATIC (decl)
+      && tree_find_value (weak_decls, decl) == NULL_TREE)
+      weak_decls = tree_cons (NULL, decl, weak_decls);
 
-  /* We want to output external symbols at very last to check if they
-     are references or not.  */
-  pending_assemble_externals = tree_cons (0, decl,
-                                         pending_assemble_externals);
+#ifdef ASM_OUTPUT_EXTERNAL
+  if (tree_find_value (pending_assemble_externals, decl) == NULL_TREE)
+    pending_assemble_externals = tree_cons (NULL, decl,
+                                           pending_assemble_externals);
 #endif
 }
 
@@ -2621,7 +2636,7 @@ assemble_integer (rtx x, unsigned int size, unsigned int align, int force)
       enum machine_mode omode, imode;
       unsigned int subalign;
       unsigned int subsize, i;
-      unsigned char mclass;
+      enum mode_class mclass;
 
       subsize = size > UNITS_PER_WORD? UNITS_PER_WORD : 1;
       subalign = MIN (align, subsize * BITS_PER_UNIT);
@@ -2697,8 +2712,7 @@ assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
    Store them both in the structure *VALUE.
    EXP must be reducible.  */
 
-struct addr_const GTY(())
-{
+struct GTY(()) addr_const {
   rtx base;
   HOST_WIDE_INT offset;
 };
@@ -2766,8 +2780,7 @@ decode_addr_const (tree exp, struct addr_const *value)
    Each constant in memory thus far output is recorded
    in `const_desc_table'.  */
 
-struct constant_descriptor_tree GTY(())
-{
+struct GTY(()) constant_descriptor_tree {
   /* A MEM for the constant.  */
   rtx rtl;
 
@@ -3352,8 +3365,7 @@ lookup_constant_def (tree exp)
    can use one per-file pool.  Should add a targetm bit to tell the
    difference.  */
 
-struct rtx_constant_pool GTY(())
-{
+struct GTY(()) rtx_constant_pool {
   /* Pointers to first and last constant in pool, as ordered by offset.  */
   struct constant_descriptor_rtx *first;
   struct constant_descriptor_rtx *last;
@@ -3369,8 +3381,7 @@ struct rtx_constant_pool GTY(())
   HOST_WIDE_INT offset;
 };
 
-struct constant_descriptor_rtx GTY((chain_next ("%h.next")))
-{
+struct GTY((chain_next ("%h.next"))) constant_descriptor_rtx {
   struct constant_descriptor_rtx *next;
   rtx mem;
   rtx sym;
@@ -4063,10 +4074,11 @@ constructor_static_from_elts_p (const_tree ctor)
          && !VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (ctor)));
 }
 
-/* A subroutine of initializer_constant_valid_p.  VALUE is either a
-   MINUS_EXPR or a POINTER_PLUS_EXPR, and ENDTYPE is a narrowing
-   conversion to something smaller than a pointer.  This returns
-   null_pointer_node if the resulting value is an absolute constant
+/* A subroutine of initializer_constant_valid_p.  VALUE is a MINUS_EXPR,
+   PLUS_EXPR or POINTER_PLUS_EXPR.  This looks for cases of VALUE
+   which are valid when ENDTYPE is an integer of any size; in
+   particular, this does not accept a pointer minus a constant.  This
+   returns null_pointer_node if the VALUE is an absolute constant
    which can be used to initialize a static variable.  Otherwise it
    returns NULL.  */
 
@@ -4075,6 +4087,9 @@ narrowing_initializer_constant_valid_p (tree value, tree endtype)
 {
   tree op0, op1;
 
+  if (!INTEGRAL_TYPE_P (endtype))
+    return NULL_TREE;
+
   op0 = TREE_OPERAND (value, 0);
   op1 = TREE_OPERAND (value, 1);
 
@@ -4113,7 +4128,9 @@ narrowing_initializer_constant_valid_p (tree value, tree endtype)
   /* Both initializers must be known.  */
   if (op0 && op1)
     {
-      if (op0 == op1)
+      if (op0 == op1
+         && (op0 == null_pointer_node
+             || TREE_CODE (value) == MINUS_EXPR))
        return null_pointer_node;
 
       /* Support differences between labels.  */
@@ -4304,12 +4321,10 @@ initializer_constant_valid_p (tree value, tree endtype)
        }
 
       /* Support narrowing pointer differences.  */
-      if (TREE_CODE (value) == POINTER_PLUS_EXPR)
-       {
-         ret = narrowing_initializer_constant_valid_p (value, endtype);
-         if (ret != NULL_TREE)
-           return ret;
-       }
+      ret = narrowing_initializer_constant_valid_p (value, endtype);
+      if (ret != NULL_TREE)
+       return ret;
+
       break;
 
     case MINUS_EXPR:
@@ -4746,8 +4761,8 @@ output_constructor (tree exp, unsigned HOST_WIDE_INT size,
          total_bytes += fieldsize;
        }
       else if (val != 0 && TREE_CODE (val) != INTEGER_CST)
-       error ("invalid initial value for member %qs",
-              IDENTIFIER_POINTER (DECL_NAME (field)));
+       error ("invalid initial value for member %qE",
+              DECL_NAME (field));
       else
        {
          /* Element that is a bit-field.  */
@@ -5160,8 +5175,7 @@ globalize_decl (tree decl)
    of an alias.  This requires that the decl have been defined.  Aliases
    that precede their definition have to be queued for later processing.  */
 
-typedef struct alias_pair GTY(())
-{
+typedef struct GTY(()) alias_pair {
   tree decl;
   tree target;
 } alias_pair;
@@ -5330,13 +5344,13 @@ finish_aliases_1 (void)
       if (target_decl == NULL)
        {
          if (! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
-           error ("%q+D aliased to undefined symbol %qs",
-                  p->decl, IDENTIFIER_POINTER (p->target));
+           error ("%q+D aliased to undefined symbol %qE",
+                  p->decl, p->target);
        }
       else if (DECL_EXTERNAL (target_decl)
               && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
-       error ("%q+D aliased to external symbol %qs",
-              p->decl, IDENTIFIER_POINTER (p->target));
+       error ("%q+D aliased to external symbol %qE",
+              p->decl, p->target);
     }
 }
 
@@ -6382,7 +6396,8 @@ default_internal_label (FILE *stream, const char *prefix,
 void
 default_file_start (void)
 {
-  if (targetm.file_start_app_off && !flag_verbose_asm)
+  if (targetm.file_start_app_off
+      && !(flag_verbose_asm || flag_debug_asm || flag_dump_rtl_in_asm))
     fputs (ASM_APP_OFF, asm_out_file);
 
   if (targetm.file_start_file_directive)