OSDN Git Service

cp/:
[pf3gnuchains/gcc-fork.git] / gcc / config / darwin.c
index 5461fe0..c8bb508 100644 (file)
@@ -1,6 +1,6 @@
 /* Functions for generic Darwin as target machine for GNU C compiler.
    Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007, 2008
+   2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Apple Computer Inc.
 
@@ -267,44 +267,26 @@ machopic_define_symbol (rtx mem)
   SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
 }
 
-static GTY(()) const char * function_base;
+/* Return either ORIG or:
 
-const char *
-machopic_function_base_name (void)
-{
-  /* if dynamic-no-pic is on, we should not get here */
-  gcc_assert (!MACHO_DYNAMIC_NO_PIC_P);
-
-  if (function_base == NULL)
-    function_base = ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
-
-  crtl->uses_pic_offset_table = 1;
-
-  return function_base;
-}
-
-/* Return a SYMBOL_REF for the PIC function base.  */
+     (const:P (unspec:P [ORIG] UNSPEC_MACHOPIC_OFFSET))
 
+   depending on MACHO_DYNAMIC_NO_PIC_P.  */
 rtx
-machopic_function_base_sym (void)
+machopic_gen_offset (rtx orig)
 {
-  rtx sym_ref;
-
-  sym_ref = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
-  SYMBOL_REF_FLAGS (sym_ref)
-    |= (MACHO_SYMBOL_FLAG_VARIABLE | MACHO_SYMBOL_FLAG_DEFINED);
-  return sym_ref;
-}
-
-/* Return either ORIG or (const:P (minus:P ORIG PIC_BASE)), depending
-   on whether pic_base is NULL or not.  */
-static inline rtx
-gen_pic_offset (rtx orig, rtx pic_base)
-{
-  if (!pic_base)
+  if (MACHO_DYNAMIC_NO_PIC_P)
     return orig;
   else
-    return gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, orig, pic_base));
+    {
+      /* Play games to avoid marking the function as needing pic if we
+        are being called as part of the cost-estimation process.  */
+      if (current_ir_type () != IR_GIMPLE || currently_expanding_to_rtl)
+       crtl->uses_pic_offset_table = 1;
+      orig = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
+                            UNSPEC_MACHOPIC_OFFSET);
+      return gen_rtx_CONST (Pmode, orig);
+    }
 }
 
 static GTY(()) const char * function_base_func_name;
@@ -332,7 +314,7 @@ machopic_output_function_base_name (FILE *file)
 /* The suffix attached to stub symbols.  */
 #define STUB_SUFFIX "$stub"
 
-typedef struct machopic_indirection GTY (())
+typedef struct GTY (()) machopic_indirection
 {
   /* The SYMBOL_REF for the entity referenced.  */
   rtx symbol;
@@ -366,7 +348,8 @@ machopic_indirection_hash (const void *slot)
 static int
 machopic_indirection_eq (const void *slot, const void *key)
 {
-  return strcmp (((const machopic_indirection *) slot)->ptr_name, key) == 0;
+  return strcmp (((const machopic_indirection *) slot)->ptr_name,
+                (const char *) key) == 0;
 }
 
 /* Return the name of the non-lazy pointer (if STUB_P is false) or
@@ -420,7 +403,7 @@ machopic_indirection_name (rtx sym_ref, bool stub_p)
   else
     suffix = NON_LAZY_POINTER_SUFFIX;
 
-  buffer = alloca (strlen ("&L")
+  buffer = XALLOCAVEC (char, strlen ("&L")
                   + strlen (prefix)
                   + namelen
                   + strlen (suffix)
@@ -527,8 +510,7 @@ machopic_indirect_data_reference (rtx orig, rtx reg)
       else if (defined)
        {
 #if defined (TARGET_TOC) || defined (HAVE_lo_sum)
-         rtx pic_base = machopic_function_base_sym ();
-         rtx offset = gen_pic_offset (orig, pic_base);
+         rtx offset = machopic_gen_offset (orig);
 #endif
 
 #if defined (TARGET_TOC) /* i.e., PowerPC */
@@ -674,8 +656,6 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
          ))
     {
       /* addr(foo) = &func+(foo-func) */
-      rtx pic_base;
-
       orig = machopic_indirect_data_reference (orig, reg);
 
       if (GET_CODE (orig) == PLUS
@@ -688,12 +668,6 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
          return reg;
        }
 
-      /* if dynamic-no-pic we don't have a pic base  */
-      if (MACHO_DYNAMIC_NO_PIC_P)
-       pic_base = NULL;
-      else
-       pic_base = machopic_function_base_sym ();
-
       if (GET_CODE (orig) == MEM)
        {
          if (reg == 0)
@@ -730,7 +704,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
          if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
              || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
            {
-             rtx offset = gen_pic_offset (XEXP (orig, 0), pic_base);
+             rtx offset = machopic_gen_offset (XEXP (orig, 0));
 #if defined (TARGET_TOC) /* i.e., PowerPC */
              /* Generating a new reg may expose opportunities for
                 common subexpression elimination.  */
@@ -786,8 +760,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
              if (reload_in_progress)
                df_set_regs_ever_live (REGNO (pic), true);
              pic_ref = gen_rtx_PLUS (Pmode, pic,
-                                     gen_pic_offset (XEXP (orig, 0),
-                                                     pic_base));
+                                     machopic_gen_offset (XEXP (orig, 0)));
            }
 
 #if !defined (TARGET_TOC)
@@ -802,7 +775,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
          if (GET_CODE (orig) == SYMBOL_REF
              || GET_CODE (orig) == LABEL_REF)
            {
-             rtx offset = gen_pic_offset (orig, pic_base);
+             rtx offset = machopic_gen_offset (orig);
 #if defined (TARGET_TOC) /* i.e., PowerPC */
               rtx hi_sum_reg;
 
@@ -859,7 +832,7 @@ machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
                    df_set_regs_ever_live (REGNO (pic), true);
                  pic_ref = gen_rtx_PLUS (Pmode,
                                          pic,
-                                         gen_pic_offset (orig, pic_base));
+                                         machopic_gen_offset (orig));
                }
            }
        }
@@ -969,7 +942,7 @@ machopic_output_indirection (void **slot, void *data)
            sym_name = IDENTIFIER_POINTER (id);
        }
 
-      sym = alloca (strlen (sym_name) + 2);
+      sym = XALLOCAVEC (char, strlen (sym_name) + 2);
       if (sym_name[0] == '*' || sym_name[0] == '&')
        strcpy (sym, sym_name + 1);
       else if (sym_name[0] == '-' || sym_name[0] == '+')
@@ -977,7 +950,7 @@ machopic_output_indirection (void **slot, void *data)
       else
        sprintf (sym, "%s%s", user_label_prefix, sym_name);
 
-      stub = alloca (strlen (ptr_name) + 2);
+      stub = XALLOCAVEC (char, strlen (ptr_name) + 2);
       if (ptr_name[0] == '*' || ptr_name[0] == '&')
        strcpy (stub, ptr_name + 1);
       else
@@ -1001,6 +974,30 @@ machopic_output_indirection (void **slot, void *data)
       rtx init = const0_rtx;
 
       switch_to_section (darwin_sections[machopic_nl_symbol_ptr_section]);
+
+      /* Mach-O symbols are passed around in code through indirect
+        references and the original symbol_ref hasn't passed through
+        the generic handling and reference-catching in
+        output_operand, so we need to manually mark weak references
+        as such.  */
+      if (SYMBOL_REF_WEAK (symbol))
+       {
+         tree decl = SYMBOL_REF_DECL (symbol);
+         gcc_assert (DECL_P (decl));
+
+         if (decl != NULL_TREE
+             && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
+             /* Handle only actual external-only definitions, not
+                e.g. extern inline code or variables for which
+                storage has been allocated.  */
+             && !TREE_STATIC (decl))
+           {
+             fputs ("\t.weak_reference ", asm_out_file);
+             assemble_name (asm_out_file, sym_name);
+             fputc ('\n', asm_out_file);
+           }
+       }
+
       assemble_name (asm_out_file, ptr_name);
       fprintf (asm_out_file, ":\n");
 
@@ -1039,27 +1036,12 @@ int
 machopic_operand_p (rtx op)
 {
   if (MACHOPIC_JUST_INDIRECT)
-    {
-      while (GET_CODE (op) == CONST)
-       op = XEXP (op, 0);
-
-      if (GET_CODE (op) == SYMBOL_REF)
-       return machopic_symbol_defined_p (op);
-      else
-       return 0;
-    }
-
-  while (GET_CODE (op) == CONST)
-    op = XEXP (op, 0);
-
-  if (GET_CODE (op) == MINUS
-      && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-      && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
-      && machopic_symbol_defined_p (XEXP (op, 0))
-      && machopic_symbol_defined_p (XEXP (op, 1)))
-      return 1;
-
-  return 0;
+    return (GET_CODE (op) == SYMBOL_REF
+           && machopic_symbol_defined_p (op));
+  else
+    return (GET_CODE (op) == CONST
+           && GET_CODE (XEXP (op, 0)) == UNSPEC
+           && XINT (XEXP (op, 0), 1) == UNSPEC_MACHOPIC_OFFSET);
 }
 
 /* This function records whether a given name corresponds to a defined
@@ -1425,15 +1407,15 @@ darwin_handle_kext_attribute (tree *node, tree name,
   /* APPLE KEXT stuff -- only applies with pure static C++ code.  */
   if (! TARGET_KEXTABI)
     {
-      warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
-              "only when compiling a kext", IDENTIFIER_POINTER (name));
+      warning (0, "%qE 2.95 vtable-compatibility attribute applies "
+              "only when compiling a kext", name);
 
       *no_add_attrs = true;
     }
   else if (TREE_CODE (*node) != RECORD_TYPE)
     {
-      warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
-              "only to C++ classes", IDENTIFIER_POINTER (name));
+      warning (0, "%qE 2.95 vtable-compatibility attribute applies "
+              "only to C++ classes", name);
 
       *no_add_attrs = true;
     }
@@ -1452,8 +1434,8 @@ darwin_handle_weak_import_attribute (tree *node, tree name,
 {
   if (TREE_CODE (*node) != FUNCTION_DECL && TREE_CODE (*node) != VAR_DECL)
     {
-      warning (OPT_Wattributes, "%qs attribute ignored",
-              IDENTIFIER_POINTER (name));
+      warning (OPT_Wattributes, "%qE attribute ignored",
+              name);
       *no_add_attrs = true;
     }
   else