OSDN Git Service

* varasm.c (initializer_constant_valid_p): Don't deny
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 Mar 2007 21:54:35 +0000 (21:54 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 Mar 2007 21:54:35 +0000 (21:54 +0000)
DECL_DLLIMPORT_P on functions.

* config/i386/cygming.h: Remove function declarations.
(SUBTARGET_ENCODE_SECTION_INFO): Don't undef first.
(ASM_OUTPUT_LABELREF): Remove.
(COMMON_ASM_OP): Remove.
(ASM_OUTPUT_COMMON): Remove.
(ASM_OUTPUT_ALIGNED_DECL_COMMON): New.
(ASM_DECLARE_OBJECT_NAME): Use i386_pe_maybe_record_exported_symbol.
(ASM_DECLARE_FUNCTION_NAME): Likewise.
* config/i386/i386-interix.h (SUBTARGET_ENCODE_SECTION_INFO):
Rename from TARGET_ENCODE_SECTION_INFO.
* config/i386/netware.h: Likewise.
* config/i386/i386-protos.h: Update.
* config/i386/i386.c (ix86_function_ok_for_sibcall): Turn ifdef
of TARGET_DLLIMPORT_DECL_ATTRIBUTES into straight if.
(legitimate_constant_p): Reject dllimports.
(dllimport_map, get_dllimport_decl): New.
(legitimize_dllimport_symbol): New.
(legitimize_address, ix86_expand_move): Use it.
(TARGET_BINDS_LOCAL_P): Redefine for TARGET_DLLIMPORT_DECL_ATTRIBUTES.
* config/i386/i386.h (DLL_IMPORT_EXPORT_PREFIX): Remove.
(SYMBOL_FLAG_DLLIMPORT, SYMBOL_REF_DLLIMPORT_P): New.
(SYMBOL_FLAG_DLLEXPORT, SYMBOL_REF_DLLEXPORT_P): New.
* config/i386/predicates.md (constant_call_address_operand): Only
accept symbols; reject dllimport_p symbols.
* config/i386/uwin.h (ASM_DECLARE_FUNCTION_NAME): Use
i386_pe_maybe_record_exported_symbol.
* config/i386/winnt.c (DLL_IMPORT_PREFIX, DLL_EXPORT_PREFIX): Remove.
(i386_pe_determine_dllexport_p): Rename from i386_pe_dllexport_p.
(i386_pe_determine_dllimport_p): Rename from i386_pe_dllimport_p;
trust the setting of DECL_DLLIMPORT_P.
(i386_pe_dllexport_name_p, i386_pe_dllimport_name_p): Remove.
(i386_pe_mark_dllexport, i386_pe_mark_dllimport): Remove.
(gen_stdcall_or_fastcall_suffix): Return NULL if no change required;
tidy the argument scanning loop.
(i386_pe_encode_section_info): Set SYMBOL_FLAG_DLLIMPORT and
SYMBOL_FLAG_DLLEXPORT in SYMBOL_REF_FLAGS.
(i386_pe_strip_name_encoding): Remove.
(i386_pe_binds_local_p): New.
(i386_pe_strip_name_encoding_full): Use default_strip_name_encoding.
(i386_pe_output_labelref): Remove.
(i386_pe_asm_output_aligned_decl_common): New.
(i386_pe_maybe_record_exported_symbol): Rename from
i386_pe_record_exported_symbol; check for dllexported symbols.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123344 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/cygming.h
gcc/config/i386/i386-interix.h
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/netware.h
gcc/config/i386/predicates.md
gcc/config/i386/uwin.h
gcc/config/i386/winnt.c
gcc/varasm.c

index 5b568a7..dc59fd7 100644 (file)
@@ -1,3 +1,52 @@
+2007-03-29  Richard Henderson  <rth@redhat.com>
+
+       * varasm.c (initializer_constant_valid_p): Don't deny
+       DECL_DLLIMPORT_P on functions.
+
+       * config/i386/cygming.h: Remove function declarations.
+       (SUBTARGET_ENCODE_SECTION_INFO): Don't undef first.
+       (ASM_OUTPUT_LABELREF): Remove.
+       (COMMON_ASM_OP): Remove.
+       (ASM_OUTPUT_COMMON): Remove.
+       (ASM_OUTPUT_ALIGNED_DECL_COMMON): New.
+       (ASM_DECLARE_OBJECT_NAME): Use i386_pe_maybe_record_exported_symbol.
+       (ASM_DECLARE_FUNCTION_NAME): Likewise.
+       * config/i386/i386-interix.h (SUBTARGET_ENCODE_SECTION_INFO):
+       Rename from TARGET_ENCODE_SECTION_INFO.
+       * config/i386/netware.h: Likewise.
+       * config/i386/i386-protos.h: Update.
+       * config/i386/i386.c (ix86_function_ok_for_sibcall): Turn ifdef
+       of TARGET_DLLIMPORT_DECL_ATTRIBUTES into straight if.
+       (legitimate_constant_p): Reject dllimports.
+       (dllimport_map, get_dllimport_decl): New.
+       (legitimize_dllimport_symbol): New.
+       (legitimize_address, ix86_expand_move): Use it.
+       (TARGET_BINDS_LOCAL_P): Redefine for TARGET_DLLIMPORT_DECL_ATTRIBUTES.
+       * config/i386/i386.h (DLL_IMPORT_EXPORT_PREFIX): Remove.
+       (SYMBOL_FLAG_DLLIMPORT, SYMBOL_REF_DLLIMPORT_P): New.
+       (SYMBOL_FLAG_DLLEXPORT, SYMBOL_REF_DLLEXPORT_P): New.
+       * config/i386/predicates.md (constant_call_address_operand): Only
+       accept symbols; reject dllimport_p symbols.
+       * config/i386/uwin.h (ASM_DECLARE_FUNCTION_NAME): Use
+       i386_pe_maybe_record_exported_symbol.
+       * config/i386/winnt.c (DLL_IMPORT_PREFIX, DLL_EXPORT_PREFIX): Remove.
+       (i386_pe_determine_dllexport_p): Rename from i386_pe_dllexport_p.
+       (i386_pe_determine_dllimport_p): Rename from i386_pe_dllimport_p;
+       trust the setting of DECL_DLLIMPORT_P.
+       (i386_pe_dllexport_name_p, i386_pe_dllimport_name_p): Remove.
+       (i386_pe_mark_dllexport, i386_pe_mark_dllimport): Remove.
+       (gen_stdcall_or_fastcall_suffix): Return NULL if no change required;
+       tidy the argument scanning loop.
+       (i386_pe_encode_section_info): Set SYMBOL_FLAG_DLLIMPORT and
+       SYMBOL_FLAG_DLLEXPORT in SYMBOL_REF_FLAGS.
+       (i386_pe_strip_name_encoding): Remove.
+       (i386_pe_binds_local_p): New.
+       (i386_pe_strip_name_encoding_full): Use default_strip_name_encoding.
+       (i386_pe_output_labelref): Remove.
+       (i386_pe_asm_output_aligned_decl_common): New.
+       (i386_pe_maybe_record_exported_symbol): Rename from
+       i386_pe_record_exported_symbol; check for dllexported symbols.
+
 2007-03-29  Zack Weinberg  <zack@mrtock.ucsd.edu>
 
        * gengtype.c (oprintf): Mostly revert changes from 2007-03-26;
index 9b0cd7f..aa4ca2a 100644 (file)
@@ -148,39 +148,20 @@ do {                                                                      \
    section and we need to set DECL_SECTION_NAME so we do that here.
    Note that we can be called twice on the same decl.  */
 
-#undef SUBTARGET_ENCODE_SECTION_INFO
 #define SUBTARGET_ENCODE_SECTION_INFO  i386_pe_encode_section_info
 #undef  TARGET_STRIP_NAME_ENCODING
 #define TARGET_STRIP_NAME_ENCODING  i386_pe_strip_name_encoding_full
-\f
-/* Output a reference to a label.  */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF  i386_pe_output_labelref
-
-#undef  COMMON_ASM_OP
-#define COMMON_ASM_OP  "\t.comm\t"
 
 /* Output a common block.  */
-#undef ASM_OUTPUT_COMMON
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
-do {                                                   \
-  if (i386_pe_dllexport_name_p (NAME))                 \
-    i386_pe_record_exported_symbol (NAME, 1);          \
-  if (! i386_pe_dllimport_name_p (NAME))               \
-    {                                                  \
-      fprintf ((STREAM), "\t.comm\t");                 \
-      assemble_name ((STREAM), (NAME));                        \
-      fprintf ((STREAM), ", %d\t%s %d\n",              \
-              (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)); \
-    }                                                  \
-} while (0)
+#undef ASM_OUTPUT_ALIGNED_DECL_COMMON
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON \
+  i386_pe_asm_output_aligned_decl_common
 
 /* Output the label for an initialized variable.  */
 #undef ASM_DECLARE_OBJECT_NAME
 #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL)    \
 do {                                                   \
-  if (i386_pe_dllexport_name_p (NAME))                 \
-    i386_pe_record_exported_symbol (NAME, 1);          \
+  i386_pe_maybe_record_exported_symbol (DECL, NAME, 1);        \
   ASM_OUTPUT_LABEL ((STREAM), (NAME));                 \
 } while (0)
 
@@ -210,7 +191,6 @@ do {                                                        \
 /* Windows uses explicit import from shared libraries.  */
 #define MULTIPLE_SYMBOL_SPACES 1
 
-extern void i386_pe_unique_section (TREE, int);
 #define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
 
@@ -229,8 +209,7 @@ extern void i386_pe_unique_section (TREE, int);
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                    \
   do                                                                   \
     {                                                                  \
-      if (i386_pe_dllexport_name_p (NAME))                             \
-       i386_pe_record_exported_symbol (NAME, 0);                       \
+      i386_pe_maybe_record_exported_symbol (DECL, NAME, 0);            \
       if (write_symbols != SDB_DEBUG)                                  \
        i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
       ASM_OUTPUT_LABEL (FILE, NAME);                                   \
@@ -289,15 +268,6 @@ extern void i386_pe_unique_section (TREE, int);
                               build_tree_list (get_identifier ("stdcall"),   \
                                                NULL))
 
-/* External function declarations.  */
-
-extern void i386_pe_record_external_function (tree, const char *);
-extern void i386_pe_declare_function_type (FILE *, const char *, int);
-extern void i386_pe_record_exported_symbol (const char *, int);
-extern void i386_pe_file_end (void);
-extern int i386_pe_dllexport_name_p (const char *);
-extern int i386_pe_dllimport_name_p (const char *);
-
 /* For Win32 ABI compatibility */
 #undef DEFAULT_PCC_STRUCT_RETURN
 #define DEFAULT_PCC_STRUCT_RETURN 0
@@ -315,10 +285,10 @@ extern int i386_pe_dllimport_name_p (const char *);
    machine.  Use this macro to limit the alignment which can be
    specified using the `__attribute__ ((aligned (N)))' construct.  If
    not defined, the default value is `BIGGEST_ALIGNMENT'.  */
-#undef MAX_OFILE_ALIGNMENT
 /* IMAGE_SCN_ALIGN_8192BYTES is the largest section alignment flag
    specified in the PECOFF60 spec.  Native MS compiler also limits
    user-specified alignment to 8192 bytes.  */
+#undef MAX_OFILE_ALIGNMENT
 #define MAX_OFILE_ALIGNMENT (8192 * 8)
 
 /* Native complier aligns internal doubles in structures on dword boundaries.  */
@@ -334,6 +304,7 @@ extern int i386_pe_dllimport_name_p (const char *);
 #ifndef SET_ASM_OP
 #define SET_ASM_OP "\t.set\t"
 #endif
+
 /* This implements the `alias' attribute, keeping any stdcall or
    fastcall decoration.  */
 #undef ASM_OUTPUT_DEF_FROM_DECLS
index 5e9f7da..fa75376 100644 (file)
@@ -326,8 +326,7 @@ while (0)
    differently depending on something about the variable or
    function named by the symbol (such as what section it is in).  */
 
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
+#define SUBTARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
 #undef  TARGET_STRIP_NAME_ENCODING
 #define TARGET_STRIP_NAME_ENCODING  i386_pe_strip_name_encoding_full
 
index aad4724..a379011 100644 (file)
@@ -191,9 +191,6 @@ extern int ix86_local_alignment (tree, int);
 extern int ix86_constant_alignment (tree, int);
 extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
 extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
-
-extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
-extern void i386_pe_asm_named_section (const char *, unsigned int, tree);
 extern int x86_field_alignment (tree, int);
 #endif
 
@@ -206,18 +203,22 @@ extern void ix86_expand_vector_extract (bool, rtx, rtx, int);
 extern void ix86_expand_reduc_v4sf (rtx (*)(rtx, rtx, rtx), rtx, rtx);
 
 /* In winnt.c  */
-extern int i386_pe_dllexport_name_p (const char *);
-extern int i386_pe_dllimport_name_p (const char *);
 extern void i386_pe_unique_section (tree, int);
 extern void i386_pe_declare_function_type (FILE *, const char *, int);
 extern void i386_pe_record_external_function (tree, const char *);
-extern void i386_pe_record_exported_symbol (const char *, int);
+extern void i386_pe_maybe_record_exported_symbol (tree, const char *, int);
 extern void i386_pe_asm_file_end (FILE *);
 extern void i386_pe_encode_section_info (tree, rtx, int);
-extern const char *i386_pe_strip_name_encoding (const char *);
+extern bool i386_pe_binds_local_p (tree);
 extern const char *i386_pe_strip_name_encoding_full (const char *);
-extern void i386_pe_output_labelref (FILE *, const char *);
 extern bool i386_pe_valid_dllimport_attribute_p (tree);
+extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
+extern void i386_pe_asm_named_section (const char *, unsigned int, tree);
+extern void i386_pe_asm_output_aligned_decl_common (FILE *, tree,
+                                                   const char *,
+                                                   HOST_WIDE_INT,
+                                                   HOST_WIDE_INT);
+extern void i386_pe_file_end (void);
 
 /* In winnt-cxx.c and winnt-stubs.c  */
 extern void i386_pe_adjust_class_at_definition (tree);
index 40ffcc8..ed25402 100644 (file)
@@ -2569,12 +2569,11 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
        }
     }
 
-#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   /* Dllimport'd functions are also called indirectly.  */
-  if (decl && DECL_DLLIMPORT_P (decl)
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+      && decl && DECL_DLLIMPORT_P (decl)
       && ix86_function_regparm (TREE_TYPE (decl), NULL) >= 3)
     return false;
-#endif
 
   /* If we forced aligned the stack, then sibcalling would unalign the
      stack, which may break the called function.  */
@@ -6332,6 +6331,11 @@ legitimate_constant_p (rtx x)
       /* TLS symbols are never valid.  */
       if (SYMBOL_REF_TLS_MODEL (x))
        return false;
+
+      /* DLLIMPORT symbols are never valid.  */
+      if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+         && SYMBOL_REF_DLLIMPORT_P (x))
+       return false;
       break;
 
     case CONST_DOUBLE:
@@ -7189,6 +7193,90 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
   return dest;
 }
 
+/* Create or return the unique __imp_DECL dllimport symbol corresponding
+   to symbol DECL.  */
+
+static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
+  htab_t dllimport_map;
+
+static tree
+get_dllimport_decl (tree decl)
+{
+  struct tree_map *h, in;
+  void **loc;
+  const char *name;
+  const char *prefix;
+  size_t namelen, prefixlen;
+  char *imp_name;
+  tree to;
+  rtx rtl;
+
+  if (!dllimport_map)
+    dllimport_map = htab_create_ggc (512, tree_map_hash, tree_map_eq, 0);
+
+  in.hash = htab_hash_pointer (decl);
+  in.base.from = decl;
+  loc = htab_find_slot_with_hash (dllimport_map, &in, in.hash, INSERT);
+  h = *loc;
+  if (h)
+    return h->to;
+
+  *loc = h = ggc_alloc (sizeof (struct tree_map));
+  h->hash = in.hash;
+  h->base.from = decl;
+  h->to = to = build_decl (VAR_DECL, NULL, ptr_type_node);
+  DECL_ARTIFICIAL (to) = 1;
+  DECL_IGNORED_P (to) = 1;
+  DECL_EXTERNAL (to) = 1;
+  TREE_READONLY (to) = 1;
+
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  name = targetm.strip_name_encoding (name);
+  if (name[0] == FASTCALL_PREFIX)
+    {
+      name++;
+      prefix = "*__imp_";
+    }
+  else
+    prefix = "*__imp__";
+
+  namelen = strlen (name);
+  prefixlen = strlen (prefix);
+  imp_name = alloca (namelen + prefixlen + 1);
+  memcpy (imp_name, prefix, prefixlen);
+  memcpy (imp_name + prefixlen, name, namelen + 1);
+
+  name = ggc_alloc_string (imp_name, namelen + prefixlen);
+  rtl = gen_rtx_SYMBOL_REF (Pmode, name);
+  SET_SYMBOL_REF_DECL (rtl, to);
+  SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL;
+
+  rtl = gen_const_mem (Pmode, rtl);
+  set_mem_alias_set (rtl, ix86_GOT_alias_set ());
+
+  SET_DECL_RTL (to, rtl);
+
+  return to;
+}
+
+/* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
+   true if we require the result be a register.  */
+
+static rtx
+legitimize_dllimport_symbol (rtx symbol, bool want_reg)
+{
+  tree imp_decl;
+  rtx x;
+
+  gcc_assert (SYMBOL_REF_DECL (symbol));
+  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol));
+
+  x = DECL_RTL (imp_decl);
+  if (want_reg)
+    x = force_reg (Pmode, x);
+  return x;
+}
+
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.
    This macro is used in only one place: `memory_address' in explow.c.
@@ -7231,6 +7319,20 @@ legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
   if (flag_pic && SYMBOLIC_CONST (x))
     return legitimize_pic_address (x, 0);
 
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
+    {
+      if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (x))
+       return legitimize_dllimport_symbol (x, true);
+      if (GET_CODE (x) == CONST
+         && GET_CODE (XEXP (x, 0)) == PLUS
+         && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+         && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (x, 0), 0)))
+       {
+         rtx t = legitimize_dllimport_symbol (XEXP (XEXP (x, 0), 0), true);
+         return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
+       }
+    }
+
   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
   if (GET_CODE (x) == ASHIFT
       && CONST_INT_P (XEXP (x, 1))
@@ -9236,20 +9338,31 @@ ix86_expand_move (enum machine_mode mode, rtx operands[])
          if (op1 == op0)
            return;
        }
+      else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+              && SYMBOL_REF_DLLIMPORT_P (op1))
+       op1 = legitimize_dllimport_symbol (op1, false);
     }
   else if (GET_CODE (op1) == CONST
           && GET_CODE (XEXP (op1, 0)) == PLUS
           && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF)
     {
-      model = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (op1, 0), 0));
+      rtx addend = XEXP (XEXP (op1, 0), 1);
+      rtx symbol = XEXP (XEXP (op1, 0), 0);
+      rtx tmp = NULL;
+
+      model = SYMBOL_REF_TLS_MODEL (symbol);
       if (model)
+       tmp = legitimize_tls_address (symbol, model, true);
+      else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
+              && SYMBOL_REF_DLLIMPORT_P (symbol))
+       tmp = legitimize_dllimport_symbol (symbol, true);
+
+      if (tmp)
        {
-         rtx addend = XEXP (XEXP (op1, 0), 1);
-         op1 = legitimize_tls_address (XEXP (XEXP (op1, 0), 0), model, true);
-         op1 = force_operand (op1, NULL);
-         op1 = expand_simple_binop (Pmode, PLUS, op1, addend,
+         tmp = force_operand (tmp, NULL);
+         tmp = expand_simple_binop (Pmode, PLUS, tmp, addend,
                                     op0, 1, OPTAB_DIRECT);
-         if (op1 == op0)
+         if (tmp == op0)
            return;
        }
     }
@@ -21648,6 +21761,10 @@ static const struct attribute_spec ix86_attribute_table[] =
 #undef TARGET_BINDS_LOCAL_P
 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
 #endif
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#undef TARGET_BINDS_LOCAL_P
+#define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
+#endif
 
 #undef TARGET_ASM_OUTPUT_MI_THUNK
 #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
index 4c62ce5..045741b 100644 (file)
@@ -2347,8 +2347,6 @@ enum ix86_stack_slot
   (! IN_RANGE ((SRC), FIRST_STACK_REG, LAST_STACK_REG))
 
 \f
-#define DLL_IMPORT_EXPORT_PREFIX '#'
-
 #define FASTCALL_PREFIX '@'
 \f
 struct machine_function GTY(())
@@ -2398,6 +2396,17 @@ struct machine_function GTY(())
 #define SYMBOL_FLAG_FAR_ADDR           (SYMBOL_FLAG_MACH_DEP << 0)
 #define SYMBOL_REF_FAR_ADDR_P(X)       \
        ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_FAR_ADDR) != 0)
+
+/* Flags to mark dllimport/dllexport.  Used by PE ports, but handy to
+   have defined always, to avoid ifdefing.  */
+#define SYMBOL_FLAG_DLLIMPORT          (SYMBOL_FLAG_MACH_DEP << 1)
+#define SYMBOL_REF_DLLIMPORT_P(X) \
+       ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLIMPORT) != 0)
+
+#define SYMBOL_FLAG_DLLEXPORT          (SYMBOL_FLAG_MACH_DEP << 2)
+#define SYMBOL_REF_DLLEXPORT_P(X) \
+       ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLEXPORT) != 0)
+
 /*
 Local variables:
 version-control: t
index 3630765..ed3ab3c 100644 (file)
@@ -150,7 +150,6 @@ Boston, MA 02110-1301, USA.  */
    the number of registers used, and an atsign (@). */
 void i386_nlm_encode_section_info (tree, rtx, int);
 const char *i386_nlm_strip_name_encoding (const char *);
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO  i386_nlm_encode_section_info
+#define SUBTARGET_ENCODE_SECTION_INFO  i386_nlm_encode_section_info
 #undef  TARGET_STRIP_NAME_ENCODING
 #define TARGET_STRIP_NAME_ENCODING  i386_nlm_strip_name_encoding
index 97deda6..efa5c98 100644 (file)
 
 ;; Test for a pc-relative call operand
 (define_predicate "constant_call_address_operand"
-  (and (ior (match_code "symbol_ref")
-            (match_operand 0 "local_symbolic_operand"))
-       (match_test "ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC")))
+  (match_code "symbol_ref")
+{
+  if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
+    return false;
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op))
+    return false;
+  return true;
+})
 
 ;; True for any non-virtual or eliminable register.  Used in places where
 ;; instantiation of such a register may cause the pattern to not be recognized.
index 38d218e..a87d1e7 100644 (file)
@@ -77,8 +77,7 @@ Boston, MA 02110-1301, USA.  */
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)                    \
   do                                                                   \
     {                                                                  \
-      if (i386_pe_dllexport_name_p (NAME))                             \
-       i386_pe_record_exported_symbol (NAME, 0);                       \
+      i386_pe_maybe_record_exported_symbol (DECL, NAME, 0);            \
       /* UWIN binutils bug workaround.  */                             \
       if (0 && write_symbols != SDB_DEBUG)                             \
        i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
index a46fc5b..a36fd08 100644 (file)
@@ -34,6 +34,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "toplev.h"
 #include "hashtab.h"
 #include "ggc.h"
+#include "target.h"
 
 /* i386/PE specific attribute support.
 
@@ -46,22 +47,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    multiple times.
 */
 
-static tree associated_type (tree);
-static tree gen_stdcall_or_fastcall_suffix (tree, bool);
-static bool i386_pe_dllexport_p (tree);
-static bool i386_pe_dllimport_p (tree);
-static void i386_pe_mark_dllexport (tree);
-static void i386_pe_mark_dllimport (tree);
-
-/* This is we how mark internal identifiers with dllimport or dllexport
-   attributes.  */
-#ifndef DLL_IMPORT_PREFIX
-#define DLL_IMPORT_PREFIX "#i."
-#endif
-#ifndef DLL_EXPORT_PREFIX
-#define DLL_EXPORT_PREFIX "#e."
-#endif
-
 /* Handle a "shared" attribute;
    arguments as in struct attribute_spec.handler.  */
 tree
@@ -108,67 +93,59 @@ ix86_handle_selectany_attribute (tree *node, tree name,
 static tree
 associated_type (tree decl)
 {
-  return  (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
-            ?  DECL_CONTEXT (decl) : NULL_TREE;
+  return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
+          ?  DECL_CONTEXT (decl) : NULL_TREE);
 }
 
-
-/* Return true if DECL is a dllexport'd object.  */
+/* Return true if DECL should be a dllexport'd object.  */
 
 static bool
-i386_pe_dllexport_p (tree decl)
+i386_pe_determine_dllexport_p (tree decl)
 {
-  if (TREE_CODE (decl) != VAR_DECL
-       && TREE_CODE (decl) != FUNCTION_DECL)
+  tree assoc;
+
+  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
     return false;
 
   if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
     return true;
 
   /* Also mark class members of exported classes with dllexport.  */
-  if (associated_type (decl)
-      && lookup_attribute ("dllexport",
-                           TYPE_ATTRIBUTES (associated_type (decl))))
+  assoc = associated_type (decl);
+  if (assoc && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (assoc)))
     return i386_pe_type_dllexport_p (decl);
 
   return false;
 }
 
+/* Return true if DECL should be a dllimport'd object.  */
+
 static bool
-i386_pe_dllimport_p (tree decl)
+i386_pe_determine_dllimport_p (tree decl)
 {
-  if (TREE_CODE (decl) != VAR_DECL
-       && TREE_CODE (decl) != FUNCTION_DECL)
+  tree assoc;
+
+  if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
     return false;
 
   /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag.
      We may need to override an earlier decision.  */
-  if (DECL_DLLIMPORT_P (decl)
-      && lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)))
-    {
-       /* Make a final check to see if this is a definition before we generate
-          RTL for an indirect reference.  */   
-       if (!DECL_EXTERNAL (decl))
-       {
-         error ("%q+D: definition is marked as dllimport", decl);
-         DECL_DLLIMPORT_P (decl) = 0;
-          return false;
-        }
-      return true;
-    }
+  if (DECL_DLLIMPORT_P (decl))
+    return true;
+
   /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
      by  targetm.cxx.adjust_class_at_definition.  Check again to emit
      warnings if the class attribute has been overridden by an
      out-of-class definition.  */
-  else if (associated_type (decl)
-           && lookup_attribute ("dllimport",
-                               TYPE_ATTRIBUTES (associated_type (decl))))
+  assoc = associated_type (decl);
+  if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)))
     return i386_pe_type_dllimport_p (decl);
 
   return false;
 }
 
 /* Handle the -mno-fun-dllimport target switch.  */
+
 bool
 i386_pe_valid_dllimport_attribute_p (tree decl)
 {
@@ -177,247 +154,157 @@ i386_pe_valid_dllimport_attribute_p (tree decl)
    return true;
 }
 
-/* Return nonzero if SYMBOL is marked as being dllexport'd.  */
-
-int
-i386_pe_dllexport_name_p (const char *symbol)
-{
-  return (strncmp (DLL_EXPORT_PREFIX, symbol,
-                  strlen (DLL_EXPORT_PREFIX)) == 0);
-}
-
-/* Return nonzero if SYMBOL is marked as being dllimport'd.  */
-
-int
-i386_pe_dllimport_name_p (const char *symbol)
-{
-  return (strncmp (DLL_IMPORT_PREFIX, symbol,
-                  strlen (DLL_IMPORT_PREFIX)) == 0);
-}
-
-/* Mark a DECL as being dllexport'd.
-   Note that we override the previous setting (e.g.: dllimport).  */
-
-static void
-i386_pe_mark_dllexport (tree decl)
-{
-  const char *oldname;
-  char  *newname;
-  rtx rtlname;
-  rtx symref;
-  tree idp;
-
-  rtlname = XEXP (DECL_RTL (decl), 0);
-  if (GET_CODE (rtlname) == MEM)
-    rtlname = XEXP (rtlname, 0);
-  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
-  oldname = XSTR (rtlname, 0);
-  if (i386_pe_dllimport_name_p (oldname))
-    {
-      warning (0, "inconsistent dll linkage for %q+D, dllexport assumed",
-              decl);
-     /* Remove DLL_IMPORT_PREFIX.  */
-      oldname += strlen (DLL_IMPORT_PREFIX);
-    }
-  else if (i386_pe_dllexport_name_p (oldname))
-    return;  /*  already done  */
-
-  newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
-  sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
-
-  /* We pass newname through get_identifier to ensure it has a unique
-     address.  RTL processing can sometimes peek inside the symbol ref
-     and compare the string's addresses to see if two symbols are
-     identical.  */
-  idp = get_identifier (newname);
-
-  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
-  SET_SYMBOL_REF_DECL (symref, decl);
-  XEXP (DECL_RTL (decl), 0) = symref;
-}
-
-/* Mark a DECL as being dllimport'd.  */
-
-static void
-i386_pe_mark_dllimport (tree decl)
-{
-  const char *oldname;
-  char  *newname;
-  tree idp;
-  rtx rtlname, newrtl;
-  rtx symref;
-
-  rtlname = XEXP (DECL_RTL (decl), 0);
-  if (GET_CODE (rtlname) == MEM)
-    rtlname = XEXP (rtlname, 0);
-  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
-  oldname = XSTR (rtlname, 0);
-  if (i386_pe_dllexport_name_p (oldname))
-    {
-      error ("%qs declared as both exported to and imported from a DLL",
-             IDENTIFIER_POINTER (DECL_NAME (decl)));
-      return;
-    }
-  else if (i386_pe_dllimport_name_p (oldname))
-    {
-      /* Already done, but do a sanity check to prevent assembler
-        errors.  */
-      gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)
-                 && DECL_DLLIMPORT_P (decl));
-      return;
-    }
-
-  newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
-  sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
-
-  /* We pass newname through get_identifier to ensure it has a unique
-     address.  RTL processing can sometimes peek inside the symbol ref
-     and compare the string's addresses to see if two symbols are
-     identical.  */
-  idp = get_identifier (newname);
-
-  symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
-  SET_SYMBOL_REF_DECL (symref, decl);
-  newrtl = gen_rtx_MEM (Pmode,symref);
-  XEXP (DECL_RTL (decl), 0) = newrtl;
-
-  DECL_DLLIMPORT_P (decl) = 1;
-}
-
 /* Return string which is the former assembler name modified with a
    suffix consisting of an atsign (@) followed by the number of bytes of
-   arguments.  If FASTCALL is true, also add the FASTCALL_PREFIX.  */
+   arguments.  If FASTCALL is true, also add the FASTCALL_PREFIX.
+   Return NULL if no change required.  */
 
 static tree
 gen_stdcall_or_fastcall_suffix (tree decl, bool fastcall)
 {
-  int total = 0;
-  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
-     of DECL_ASSEMBLER_NAME.  */
-   const char *asmname =  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  char *newsym;
-  char *p;
+  HOST_WIDE_INT total = 0;
+  const char *asm_str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  char *new_str, *p;
   tree formal_type;
 
   /* Do not change the identifier if a verbatim asmspec or already done. */
-  if (*asmname == '*' || strchr (asmname, '@'))
-    return DECL_ASSEMBLER_NAME (decl);
+  if (*asm_str == '*' || strchr (asm_str, '@'))
+    return NULL_TREE;
 
   formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
   if (formal_type != NULL_TREE)
-    {
-      /* These attributes are ignored for variadic functions in
-        i386.c:ix86_return_pops_args. For compatibility with MS
-         compiler do not add @0 suffix here.  */ 
-      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
-        return DECL_ASSEMBLER_NAME (decl);
-
-      /* Quit if we hit an incomplete type.  Error is reported
-         by convert_arguments in c-typeck.c or cp/typeck.c.  */
-      while (TREE_VALUE (formal_type) != void_type_node
-            && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))     
-       {
-         int parm_size
-           = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
-           /* Must round up to include padding.  This is done the same
-              way as in store_one_arg.  */
-         parm_size = ((parm_size + PARM_BOUNDARY - 1)
-                      / PARM_BOUNDARY * PARM_BOUNDARY);
-         total += parm_size;
-         formal_type = TREE_CHAIN (formal_type);\
-       }
-     }
+    while (1)
+      {
+       HOST_WIDE_INT parm_size;
+       HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
+
+       /* We got to the end of the list without seeing void_list_node,
+          which means the function is variadic.  The suffix is to be
+          ignored in that case.  */
+       if (formal_type == NULL_TREE)
+         return NULL_TREE;
+
+       /* End of arguments, non-varargs marker.  */
+        if (formal_type == void_list_node)
+         break;
+
+        /* Quit if we hit an incomplete type.  Error is reported
+          by convert_arguments in c-typeck.c or cp/typeck.c.  */
+       parm_size = int_size_in_bytes (TREE_VALUE (formal_type));
+       if (parm_size < 0)
+         break;
+
+       /* Must round up to include padding.  This is done the same
+          way as in store_one_arg.  */
+       parm_size = ((parm_size + parm_boundary_bytes - 1)
+                    / parm_boundary_bytes * parm_boundary_bytes);
+       total += parm_size;
+
+       formal_type = TREE_CHAIN (formal_type);
+      }
 
   /* Assume max of 8 base 10 digits in the suffix.  */
-  newsym = alloca (1 + strlen (asmname) + 1 + 8 + 1);
-  p = newsym;
+  p = new_str = alloca (1 + strlen (asm_str) + 1 + 8 + 1);
   if (fastcall)
     *p++ = FASTCALL_PREFIX;
-  sprintf (p, "%s@%d", asmname, total/BITS_PER_UNIT);
-  return get_identifier (newsym);
+  sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, asm_str, total);
+
+  return get_identifier (new_str);
 }
 
 void
 i386_pe_encode_section_info (tree decl, rtx rtl, int first)
 {
+  rtx symbol;
+  int flags;
+
+  /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above.  */
   default_encode_section_info (decl, rtl, first);
 
-  if (first && TREE_CODE (decl) == FUNCTION_DECL)
+  /* Careful not to prod global register variables.  */
+  if (!MEM_P (rtl))
+    return;
+
+  symbol = XEXP (rtl, 0);
+  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
+
+  switch (TREE_CODE (decl))
     {
-      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
-      tree newid = NULL_TREE;
-
-      if (lookup_attribute ("stdcall", type_attributes))
-       newid = gen_stdcall_or_fastcall_suffix (decl, false);
-      else if (lookup_attribute ("fastcall", type_attributes))
-       newid = gen_stdcall_or_fastcall_suffix (decl, true);
-      if (newid != NULL_TREE)  
+    case FUNCTION_DECL:
+      if (first)
        {
-         rtx rtlname = XEXP (rtl, 0);
-         if (GET_CODE (rtlname) == MEM)
-           rtlname = XEXP (rtlname, 0);
-         XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
-         /* These attributes must be present on first declaration,
-            change_decl_assembler_name will warn if they are added
-            later and the decl has been referenced, but duplicate_decls
-            should catch the mismatch before this is called.  */ 
-         change_decl_assembler_name (decl, newid);
+         tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+         tree newid = NULL_TREE;
+
+         if (lookup_attribute ("stdcall", type_attributes))
+           newid = gen_stdcall_or_fastcall_suffix (decl, false);
+         else if (lookup_attribute ("fastcall", type_attributes))
+           newid = gen_stdcall_or_fastcall_suffix (decl, true);
+         if (newid != NULL_TREE)       
+           {
+             XSTR (symbol, 0) = IDENTIFIER_POINTER (newid);
+             /* These attributes must be present on first declaration,
+                change_decl_assembler_name will warn if they are added
+                later and the decl has been referenced, but duplicate_decls
+                should catch the mismatch before this is called.  */ 
+             change_decl_assembler_name (decl, newid);
+           }
        }
-    }
+      break;
 
-  else if (TREE_CODE (decl) == VAR_DECL
-           && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
-    {
-      if (DECL_INITIAL (decl)
-         /* If an object is initialized with a ctor, the static
-            initialization and destruction code for it is present in
-            each unit defining the object.  The code that calls the
-            ctor is protected by a link-once guard variable, so that
-            the object still has link-once semantics,  */
-          || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
-       make_decl_one_only (decl);
-      else
-       error ("%q+D:'selectany' attribute applies only to initialized objects",
-              decl);
+    case VAR_DECL:
+      if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
+       {
+         if (DECL_INITIAL (decl)
+             /* If an object is initialized with a ctor, the static
+                initialization and destruction code for it is present in
+                each unit defining the object.  The code that calls the
+                ctor is protected by a link-once guard variable, so that
+                the object still has link-once semantics,  */
+             || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
+           make_decl_one_only (decl);
+         else
+           error ("%q+D:'selectany' attribute applies only to "
+                  "initialized objects", decl);
+       }
+      break;
+
+    default:
+      return;
     }
 
   /* Mark the decl so we can tell from the rtl whether the object is
      dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
      handles dllexport/dllimport override semantics.  */
-
-  if (i386_pe_dllexport_p (decl))
-    i386_pe_mark_dllexport (decl);
-  else if (i386_pe_dllimport_p (decl))
-    i386_pe_mark_dllimport (decl);
-  /* It might be that DECL has been declared as dllimport, but a
-     subsequent definition nullified that.  Assert that
-     tree.c: merge_dllimport_decl_attributes has removed the attribute
-     before the RTL name was marked with the DLL_IMPORT_PREFIX.  */
-  else
-    gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL
-                  || TREE_CODE (decl) == VAR_DECL)
-                 && rtl != NULL_RTX
-                 && GET_CODE (rtl) == MEM
-                 && GET_CODE (XEXP (rtl, 0)) == MEM
-                 && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF
-                 && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0))));
+  flags = (SYMBOL_REF_FLAGS (symbol) &
+          ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));
+  if (i386_pe_determine_dllexport_p (decl))
+    flags |= SYMBOL_FLAG_DLLEXPORT;
+  else if (i386_pe_determine_dllimport_p (decl))
+    {
+      flags |= SYMBOL_FLAG_DLLIMPORT;
+      /* If we went through the associated_type path, this won't already
+        be set.  Though, frankly, this seems wrong, and should be fixed
+        elsewhere.  */
+      if (!DECL_DLLIMPORT_P (decl))
+       {
+         DECL_DLLIMPORT_P (decl) = 1;
+         flags &= ~SYMBOL_FLAG_LOCAL;
+       }
+    }
+  SYMBOL_REF_FLAGS (symbol) = flags;
 }
 
-/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
-   prefix if it exists.  */
-
-const char *
-i386_pe_strip_name_encoding (const char *str)
+bool
+i386_pe_binds_local_p (tree exp)
 {
-  if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
-      == 0)
-    str += strlen (DLL_IMPORT_PREFIX);
-  else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
-          == 0)
-    str += strlen (DLL_EXPORT_PREFIX);
-  if (*str == '*')
-    str += 1;
-  return str;
+  /* PE does not do dynamic binding.  Indeed, the only kind of
+     non-local reference comes from a dllimport'd symbol.  */
+  if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
+      && DECL_DLLIMPORT_P (exp))
+    return false;
+
+  return true;
 }
 
 /* Also strip the fastcall prefix and stdcall suffix.  */
@@ -426,7 +313,7 @@ const char *
 i386_pe_strip_name_encoding_full (const char *str)
 {
   const char *p;
-  const char *name = i386_pe_strip_name_encoding (str);
+  const char *name = default_strip_name_encoding (str);
 
   /* Strip leading '@' on fastcall symbols.  */
   if (*name == '@')
@@ -440,46 +327,6 @@ i386_pe_strip_name_encoding_full (const char *str)
   return name;
 }
 
-/* Output a reference to a label. Fastcall symbols are prefixed with @,
-   whereas symbols for functions using other calling conventions don't
-   have a prefix (unless they are marked dllimport or dllexport).  */
-
-void i386_pe_output_labelref (FILE *stream, const char *name)
-{
-  if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
-      == 0)
-    /* A dll import */
-    {
-      if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
-      /* A dllimport fastcall symbol.  */
-        {
-          fprintf (stream, "__imp_%s",
-                   i386_pe_strip_name_encoding (name));
-        }
-      else
-      /* A dllimport non-fastcall symbol.  */
-        {
-          fprintf (stream, "__imp__%s",
-                   i386_pe_strip_name_encoding (name));
-        }
-    }
-  else if ((name[0] == FASTCALL_PREFIX)
-           || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
-              == 0
-              && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX))
-    /* A fastcall symbol.  */
-    {
-      fprintf (stream, "%s",
-               i386_pe_strip_name_encoding (name));
-    }
-  else
-    /* Everything else.  */
-    {
-      fprintf (stream, "%s%s", USER_LABEL_PREFIX,
-               i386_pe_strip_name_encoding (name));
-    }
-}
-
 void
 i386_pe_unique_section (tree decl, int reloc)
 {
@@ -612,6 +459,29 @@ i386_pe_asm_named_section (const char *name, unsigned int flags,
               (discard  ? "discard" : "same_size"));
     }
 }
+
+void
+i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
+                                       const char *name, HOST_WIDE_INT size,
+                                       HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+{
+  HOST_WIDE_INT rounded;
+
+  /* Compute as in assemble_noswitch_variable, since we don't actually
+     support aligned common.  */
+  rounded = size ? size : 1;
+  rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
+  rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
+            * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
+  
+  i386_pe_maybe_record_exported_symbol (decl, name, 1);
+
+  fprintf (stream, "\t.comm\t");
+  assemble_name (stream, name);
+  fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
+          " " HOST_WIDE_INT_PRINT_DEC "\n",
+          rounded, size);
+}
 \f
 /* The Microsoft linker requires that every function be marked as
    DT_FCN.  When using gas on cygwin, we must emit appropriate .type
@@ -682,10 +552,16 @@ static GTY(()) struct export_list *export_head;
    linkonce.  */
 
 void
-i386_pe_record_exported_symbol (const char *name, int is_data)
+i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
 {
+  rtx symbol;
   struct export_list *p;
 
+  symbol = XEXP (DECL_RTL (decl), 0);
+  gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
+  if (!SYMBOL_REF_DLLEXPORT_P (symbol))
+    return;
+
   p = (struct export_list *) ggc_alloc (sizeof *p);
   p->next = export_head;
   p->name = name;
@@ -727,8 +603,8 @@ i386_pe_file_end (void)
       for (q = export_head; q != NULL; q = q->next)
        {
          fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
-                  i386_pe_strip_name_encoding (q->name),
-                  (q->is_data) ? ",data" : "");
+                  targetm.strip_name_encoding (q->name),
+                  (q->is_data ? ",data" : ""));
        }
     }
 }
index cf880e8..1adc492 100644 (file)
@@ -4063,9 +4063,8 @@ initializer_constant_valid_p (tree value, tree endtype)
            return null_pointer_node;
          /* Taking the address of a nested function involves a trampoline.  */
          if (TREE_CODE (value) == FUNCTION_DECL
-             && ((decl_function_context (value)
-                  && !DECL_NO_STATIC_CHAIN (value))
-                 || DECL_DLLIMPORT_P (value)))
+             && decl_function_context (value)
+             && !DECL_NO_STATIC_CHAIN (value))
            return NULL_TREE;
          /* "&{...}" requires a temporary to hold the constructed
             object.  */