summaryrefslogtreecommitdiff
path: root/gcc/config/i386/winnt.c
diff options
context:
space:
mode:
authordannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-12 20:54:50 +0000
committerdannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4>2005-10-12 20:54:50 +0000
commit6c1e551f8f0706e3f2d8359f1235448262b4f736 (patch)
tree18c5c3123c37f3bfc1dcf357bb32d0289c2b8bb8 /gcc/config/i386/winnt.c
parent7823812a978701f449a84474041f9962fa5f034d (diff)
downloadgcc-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.c216
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