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) == SYMBOL_REF) oldname = XSTR (rtlname, 0); else if (GET_CODE (rtlname) == MEM && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF) oldname = XSTR (XEXP (rtlname, 0), 0); else abort (); 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. */ /* APPLE LOCAL begin mainline 2005-10-12 */ if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl) || !DECL_DLLIMPORT_P (decl)) { error ("%Jfailure in redeclaration of '%D': dllimport'd " "symbol lacks external linkage.", decl, decl); abort(); } /* APPLE LOCAL end mainline 2005-10-12 */ 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)); SYMBOL_REF_DECL (symref) = decl; newrtl = gen_rtx_MEM (Pmode,symref); XEXP (DECL_RTL (decl), 0) = newrtl; /* APPLE LOCAL begin mainline 2005-10-12 */ DECL_DLLIMPORT_P (decl) = 1; /* APPLE LOCAL end mainline 2005-10-12 */ }
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; }
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) == SYMBOL_REF) oldname = XSTR (rtlname, 0); else if (GET_CODE (rtlname) == MEM && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF) oldname = XSTR (XEXP (rtlname, 0), 0); else abort (); if (i386_pe_dllimport_name_p (oldname)) { warning ("%Jinconsistent dll linkage for '%D', dllexport assumed.", decl, decl); /* Remove DLL_IMPORT_PREFIX. */ oldname += strlen (DLL_IMPORT_PREFIX); DECL_NON_ADDR_CONST_P (decl) = 0; } 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)); SYMBOL_REF_DECL (symref) = decl; XEXP (DECL_RTL (decl), 0) = symref; }
void i386_pe_encode_section_info (tree decl, rtx rtl, int first) { default_encode_section_info (decl, rtl, first); if (first && TREE_CODE (decl) == FUNCTION_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) { 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); } } 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); } /* 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)))); }
void i386_pe_encode_section_info (tree decl, rtx rtl, int first) { default_encode_section_info (decl, rtl, first); if (first && TREE_CODE (decl) == FUNCTION_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) { 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); } } /* Mark the decl so we can tell from the rtl whether the object is dllexport'd or dllimport'd. This also 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 already been marked as dllimport, but a subsequent definition nullified that. The attribute is gone but DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove that. Ditto for the DECL_NON_ADDR_CONST_P flag. */ else if ((TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) && DECL_RTL (decl) != NULL_RTX && GET_CODE (DECL_RTL (decl)) == MEM && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0))) { const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0); /* Remove DLL_IMPORT_PREFIX. */ tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX)); rtx symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp)); SYMBOL_REF_DECL (symref) = decl; XEXP (DECL_RTL (decl), 0) = symref; DECL_NON_ADDR_CONST_P (decl) = 0; /* We previously set TREE_PUBLIC and DECL_EXTERNAL. We leave these alone for now. */ if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl)) warning ("%J'%D' defined locally after being " "referenced with dllimport linkage", decl, decl); else warning ("%J'%D' redeclared without dllimport attribute " "after being referenced with dllimport linkage", decl, decl); } }