diff options
author | dannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-10-12 20:54:50 +0000 |
---|---|---|
committer | dannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-10-12 20:54:50 +0000 |
commit | 6c1e551f8f0706e3f2d8359f1235448262b4f736 (patch) | |
tree | 18c5c3123c37f3bfc1dcf357bb32d0289c2b8bb8 /gcc/config/i386/winnt.c | |
parent | 7823812a978701f449a84474041f9962fa5f034d (diff) | |
download | gcc-6c1e551f8f0706e3f2d8359f1235448262b4f736.tar.gz |
PR middle-end/21275
PR middle-end/21766
* target.h (struct gcc_target): Add valid_dllimport_attribute_p
target hook.
(struct cxx): Add adjust_class_at_definition target hook.
* target-def.h: (TARGET_VALID_DLLIMPORT_ATTRIBUTE_P): New define,
defaulting to hook_bool_tree_true. Add to TARGET_INITIALIZER
(TARGET_CXX_ADJUST_CLASS_AT_DEFINITION): New define, defaulting to
hook_void_tree. Add to TARGET_CXX.
* tree.h (struct decl_with_vis): Rename non_addr_const_p field to
dllimport_flag.
(DECL_NON_ADDR_CONSTANT_P): Replace with DECL_DLLIMPORT_P macro.
* tree.c (merge_dllimport_decl_attributes): Check DECL_DLLIMPORT_P
instead of attribute. Check for dllexport override. Warn if
inconsistent dll linkage. Don't lose old dllimport if decl has
had address referenced. Tweak lookup of dllimport atribute.
(handle_dll_attribute): Check targetm.valid_dllimport_attribute_p
for target specific rules. Don't add dllimport attribute if
DECL_DECLARED_INLINE_P. Set DECL_DLLIMPORT_P when adding
dllimport attribute.
(staticp): Replace DECL_NON_ADDR_CONSTANT_P with DECL_DLLIMPORT_P.
* varasm.c (initializer_constant_valid_p): Replace
DECL_NON_ADDR_CONSTANT_P with DECL_DLLIMPORT_P
PR target/21801
PR target/23589
* config.gcc (i[34567]86-*-cygwin*): Add winnt-cxx.o to
'cxx_target_objs', winnt-stubs,o to 'extra_objs'.
(i[34567]86-*-mingw32*): Likewise.
* doc/tm.texi (TARGET_CXX_ADJUST_CLASS_AT_DEFINITION): Document.
(TARGET_VALID_DLLIMPORT_ATTRIBUTE_P): Document.
* config/i386/winnt.c (i386_pe_dllimport_p): Factor out
C++-specific code. Change return value to bool.
(i386_pe_dllimport_p): Likewise.
(associated_type): Simplify and make language-independent
(i386_pe_encode_section_info): Replace override of ambiguous
dllimport symbol refs with a gcc_assert.
(i386_pe_valid_dllimport_attribute_p): Define.
* config/i386/winnt-cxx.c: New file. Define C++ versions of
i386_pe_type_dllimport_p, i386_pe_type_dllexport_p,
i386_pe_adjust_class_at_definition.
* config/i386/winnt-stubs.c: New file. Define stub versions of
lang-specific functions.
* config/i386/i386-protos.h: Declare winnt-[cxx|stubs].c functions
i386_pe_type_dllimport_p, i386_pe_type_dllexport_p,
i386_pe_adjust_class_at_definition.
(i386_pe_valid_dllimport_attribute_p): Declare.
* config/i386/cygming.h (TARGET_VALID_DLLIMPORT_ATTRIBUTE_P): Define.
(TARGET_CXX_ADJUST_CLASS_AT_DEFINITION): Define.
* config/i386/t-cygming: Add rules for winnt-cxx.o, winnt-stubs.o.
PR target/19704
* config/i386/i386.c (ix86_function_ok_for_sibcall): Replace test for
dllimport attribute with test of DECL_DLLIMPORT_P.
cp
PR target/21801
PR target/23589
* class.c (finish_struct_1): Call
targetm.cxx.adjust_class_at_definition.
testsuite
* gcc.dg/dll-2.c: Add tests for warnings.
* gcc.dg/dll-3.c: Likewise.
* gcc.dg/dll-4.c: Likewise.
* g++.dg/ext/dllimport1.C: Adjust tests for warnings.
* g++.dg/ext/dllimport2.C: Likewise.
* g++.dg/ext/dllimport3.C: Likewise.
* g++.dg/ext/dllimport7.C: Likewise.
* g++.dg/ext/dllimport8.C: Likewise.
* g++.dg/ext/dllimport9.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105332 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386/winnt.c')
-rw-r--r-- | gcc/config/i386/winnt.c | 216 |
1 files changed, 64 insertions, 152 deletions
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index c1c605c6a1c..f8a36ff1ba1 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -48,8 +48,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA static tree associated_type (tree); static tree gen_stdcall_or_fastcall_suffix (tree, bool); -static int i386_pe_dllexport_p (tree); -static int i386_pe_dllimport_p (tree); +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); @@ -115,131 +115,63 @@ ix86_handle_selectany_attribute (tree *node, tree name, static tree associated_type (tree decl) { - tree t = NULL_TREE; - - /* In the C++ frontend, DECL_CONTEXT for a method doesn't actually refer - to the containing class. So we look at the 'this' arg. */ - if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) - { - /* Artificial methods are not affected by the import/export status - of their class unless they are COMDAT. Implicit copy ctor's and - dtor's are not affected by class status but virtual and - non-virtual thunks are. */ - if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl)) - t = TYPE_MAIN_VARIANT - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))))); - } - else if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))) - t = DECL_CONTEXT (decl); - - return t; + return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))) + ? DECL_CONTEXT (decl) : NULL_TREE; } -/* Return nonzero if DECL is a dllexport'd object. */ -static int +/* Return true if DECL is a dllexport'd object. */ + +static bool i386_pe_dllexport_p (tree decl) { - tree exp; - if (TREE_CODE (decl) != VAR_DECL - && TREE_CODE (decl) != FUNCTION_DECL) - return 0; - exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)); - if (exp) - return 1; - - /* Class members get the dllexport status of their class. */ - if (associated_type (decl)) - { - exp = lookup_attribute ("dllexport", - TYPE_ATTRIBUTES (associated_type (decl))); - if (exp) - return 1; - } + && TREE_CODE (decl) != FUNCTION_DECL) + return false; - return 0; -} + 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)))) + return i386_pe_type_dllexport_p (decl); -/* Return nonzero if DECL is a dllimport'd object. */ + return false; +} -static int +static bool i386_pe_dllimport_p (tree decl) { - tree imp; - int context_imp = 0; - - if (TREE_CODE (decl) == FUNCTION_DECL - && TARGET_NOP_FUN_DLLIMPORT) - return 0; - if (TREE_CODE (decl) != VAR_DECL - && TREE_CODE (decl) != FUNCTION_DECL) - return 0; - - imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl)); - - /* Class members get the dllimport status of their class. */ - if (!imp && associated_type (decl)) - { - imp = lookup_attribute ("dllimport", - TYPE_ATTRIBUTES (associated_type (decl))); - if (imp) - context_imp = 1; - } - - if (imp) - { - /* Don't mark defined functions as dllimport. If the definition - itself was marked with dllimport, than ix86_handle_dll_attribute - reports an error. This handles the case when the definition - overrides an earlier declaration. */ - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) - && !DECL_INLINE (decl)) - { - /* Don't warn about artificial methods. */ - if (!DECL_ARTIFICIAL (decl)) - warning (0, "function %q+D is defined after prior declaration " - "as dllimport: attribute ignored", decl); - return 0; - } - - /* We ignore the dllimport attribute for inline member functions. - This differs from MSVC behavior which treats it like GNUC - 'extern inline' extension. */ - else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)) - { - if (extra_warnings) - warning (0, "inline function %q+D is declared as dllimport: " - "attribute ignored", decl); - return 0; - } - - /* Don't allow definitions of static data members in dllimport class, - Just ignore attribute for vtable data. */ - else if (TREE_CODE (decl) == VAR_DECL - && TREE_STATIC (decl) && TREE_PUBLIC (decl) - && !DECL_EXTERNAL (decl) && context_imp) - { - if (!DECL_VIRTUAL_P (decl)) - error ("definition of static data member %q+D of " - "dllimport'd class", decl); - return 0; - } - - /* Since we can't treat a pointer to a dllimport'd symbol as a - constant address, we turn off the attribute on C++ virtual - methods to allow creation of vtables using thunks. Don't mark - artificial methods either (in associated_type, only COMDAT - artificial method get import status from class context). */ - else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE - && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl))) - return 0; - - return 1; - } + && TREE_CODE (decl) != FUNCTION_DECL) + return false; + + /* Lookup the attribute rather than rely on the DECL_DLLIMPORT_P flag. + We may need to override an earlier decision. */ + if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (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 overriden by an + out-of-class definition. */ + if (associated_type (decl) + && lookup_attribute ("dllimport", + TYPE_ATTRIBUTES (associated_type (decl)))) + return i386_pe_type_dllimport_p (decl); + + return false; +} - return 0; +/* Handle the -mno-fun-dllimport target switch. */ +bool +i386_pe_valid_dllimport_attribute_p (tree decl) +{ + if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL) + return false; + return true; } /* Return nonzero if SYMBOL is marked as being dllexport'd. */ @@ -283,7 +215,6 @@ i386_pe_mark_dllexport (tree 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 */ @@ -328,7 +259,9 @@ i386_pe_mark_dllimport (tree decl) { /* Already done, but do a sanity check to prevent assembler errors. */ - gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl)); + gcc_assert (DECL_EXTERNAL (decl) && TREE_PUBLIC (decl) + && DECL_DLLIMPORT_P (decl)); + return; } newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1); @@ -345,8 +278,7 @@ i386_pe_mark_dllimport (tree decl) newrtl = gen_rtx_MEM (Pmode,symref); XEXP (DECL_RTL (decl), 0) = newrtl; - /* Can't treat a pointer to this as a constant address */ - DECL_NON_ADDR_CONST_P (decl) = 1; + DECL_DLLIMPORT_P (decl) = 1; } /* Return string which is the former assembler name modified with a @@ -431,45 +363,25 @@ i386_pe_encode_section_info (tree decl, rtx rtl, int first) } /* 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. */ + 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 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 (0, "%q+D defined locally after being " - "referenced with dllimport linkage", decl); - else - warning (OPT_Wattributes, "%q+D redeclared without dllimport " - "attribute after being referenced with dllimport linkage", - 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)))); } /* Strip only the leading encoding, leaving the stdcall suffix and fastcall |