diff options
author | Richard Henderson <rth@redhat.com> | 2007-03-29 14:54:35 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2007-03-29 14:54:35 -0700 |
commit | da489f7340623783872629a4ebd595d93fc3dced (patch) | |
tree | eb98f4ede31001adc419d6556b98962ff353afb5 /gcc/config/i386/winnt.c | |
parent | 0c9bce0b5cfe0a037bdabd00cc783a37ff1f159c (diff) | |
download | gcc-da489f7340623783872629a4ebd595d93fc3dced.zip gcc-da489f7340623783872629a4ebd595d93fc3dced.tar.gz gcc-da489f7340623783872629a4ebd595d93fc3dced.tar.bz2 |
varasm.c (initializer_constant_valid_p): Don't deny DECL_DLLIMPORT_P on functions.
* 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.
From-SVN: r123344
Diffstat (limited to 'gcc/config/i386/winnt.c')
-rw-r--r-- | gcc/config/i386/winnt.c | 466 |
1 files changed, 171 insertions, 295 deletions
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index a46fc5b..a36fd08 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -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); +} /* 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" : "")); } } } |