This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch: mingw/cygwin] Handle export of MI thunks from windows dll's
- From: Danny Smith <danny_r_smith_2001 at yahoo dot co dot nz>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Christopher Faylor <cgf at redhat dot com>, Jason Merrill <jason at redhat dot com>
- Date: Sat, 5 Jul 2003 12:18:58 +1000 (EST)
- Subject: [Patch: mingw/cygwin] Handle export of MI thunks from windows dll's
Currently, dllexport/import of methods from classes with multiple
inheitance fails on windows targets, because, when building the dll
non-virtual MI thunks are _not_ marked for export, unlike virtual thunks
which get dllexport status from their containing class
This patch to winnt.c, removes the test for DECL_ARTIFICIAL in
associated_type() so that non-virtual thunks do get marked for export. The
_export_ of public artifical methods should cause no problems: In fact the only
way to get MI to work now is to use the ld switch --export-all so that
ld dllexports all the symbols that would also be accessible from a
static library. However, recent addition of thunk aliases in cp/method.c
means that we do have to test for the the LTHUNK aliases, else
i386_pe_mark_dllexport will pass them through get_identifier and gen_rtx,
leading to undefined references.
Is there a better way to test for these LTHUNK symbols than just looking
at the assembler name?
The removal of the test for test for DECL_ARTIFICIAL in associated_type()
means that a test for artificial methods in i386_pe_dllimport_p is necessary
because marking non-virtual MI thunks with dllimport causes the same compiler
ICE as did marking virtual methods
Following patch and new test cases tested with i386-pc-mingw32. The test
cases can also be compiled into a dll and a client app that uses the dll to
show that everything is working, but I don't know how to do that within
dejagnu framework.
2003-07-05 Danny Smith <dannysmith@users.sourceforge.net>
* config/i386/winnt.c (associated_type): Don't exclude
all non-virtual artificial methods, but do exclude symbols
prefixed with '*'.
(i386_pe_dllimport_p): Don't mark artificial methods.
testsuite:
g++.dg/ext/dll-MI1.h: New file.
g++.dg/ext/dllexport-MI1.C: New file.
g++.dg/ext/dllimport-MI1.C: New file.
--- config/i386/winnt.c 5 Jul 2003 01:59:22 -0000
*************** associated_type (decl)
*** 176,184 ****
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 virtual. */
! if (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))
t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
}
else if (DECL_CONTEXT (decl)
--- 176,189 ----
to the containing class. So we look at the 'this' arg. */
if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
{
! /* Ignore internally generated aliases and other internal
! asm symbols prefixed with '*' */
! /*
! if (strncmp ("*LTHUNK",
! IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
! sizeof ("*LTHUNK") - 1))
! */
! if (*IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*')
t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
}
else if (DECL_CONTEXT (decl)
*************** i386_pe_dllimport_p (decl)
*** 284,293 ****
/* 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. */
else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
! && (DECL_VIRTUAL_P (decl)))
! return 0;
return 1;
}
--- 289,299 ----
/* 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
! non-virtual MI-thunks either, since we need their address. */
else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
! && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
! return 0;
return 1;
}
*** /dev/null Sat Jul 5 02:05:37 2003
--- g++.dg/ext/dll-MI1.h Sat Jul 5 00:10:38 2003
***************
*** 0 ****
--- 1,37 ----
+ // Class definitions for dllexport-MI1.C and dllimport-MI1.C
+
+ #ifdef BUILDING_MI_DLL
+ #define DLL_IMPEXP __attribute__ ((dllexport))
+ #else
+ #define DLL_IMPEXP __attribute__ ((dllimport))
+ #endif
+
+
+ #define D1_return 1
+ #define D2_return 2
+
+ class DLL_IMPEXP MBase
+ {
+ public:
+ virtual int vf() const = 0;
+ virtual ~MBase();
+ };
+
+ class DLL_IMPEXP D1 : virtual public MBase
+ {
+ public:
+ int vf() const;
+ };
+
+ class DLL_IMPEXP D2 : virtual public MBase
+ {
+ public:
+ int vf() const;
+ };
+
+ class DLL_IMPEXP MI1 : public D1, public D2
+ {
+ public:
+ int vf() const;
+ };
+
*** /dev/null Sat Jul 5 02:05:43 2003
--- g++.dg/ext/dllexport-MI1.C Sat Jul 5 02:04:53 2003
***************
*** 0 ****
--- 1,36 ----
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ // Test that non-virtual MI thunks are exported.
+
+
+ // To build the dll and client app:
+ // g++ -shared -o MI.dll dllexport-MI1.C
+ // g++ -o MItest.exe dllimport-MI1.C -L. MI.dll
+
+ #define BUILDING_MI_DLL
+ #include "dll-MI1.h"
+
+ MBase::~MBase(){}
+
+ int D1::vf() const { return D1_return; }
+
+ int D2::vf() const { return D2_return; }
+
+ int MI1::vf() const { return D1::vf();}
+
+ // a dllexported object
+ DLL_IMPEXP MI1 dllMI1;
+
+ // Scan for export of some methods that are undefined in dllimportMI1.C,
+
+ // { dg-final { scan-assembler "-export:_ZNK2D12vfEv" } }
+ // { dg-final { scan-assembler "-export:_ZNK2D22vfEv" } }
+ // { dg-final { scan-assembler "-export:_ZNK3MI12vfEv" } }
+
+ // and MI thunks,
+
+ // { dg-final { scan-assembler "-export:_ZThn4_NK3MI12vfEv" } }
+ // { dg-final { scan-assembler "-export:_ZTv0_n12_NK2D12vfEv" } }
+
+ // and a vtable data variable.
+
+ // { dg-final { scan-assembler "-export:_ZTV2D1,data" } }
*** /dev/null Sat Jul 5 02:05:53 2003
--- g++.dg/ext/dllimport-MI1.C Sat Jul 5 02:05:31 2003
***************
*** 0 ****
--- 1,41 ----
+ // { dg-do compile { target i?86-*-cygwin* i?86-*-mingw*} }
+ // Test handling of MI thunks in dllimported classes.
+
+ // To build the dll and client app:
+ // g++ -shared -o MI.dll dllexport-MI1.C
+ // g++ -o MItest.exe dllimport-MI1.C -L. MI.dll
+
+ #include <stdlib.h>
+ #include "dll-MI1.h"
+
+ extern DLL_IMPEXP MI1 dllMI1;
+
+ class MI2 : public D1, public D2
+ {
+ public:
+ int vf() const { return D2::vf();}
+ };
+
+ class MI3 : public MI1
+ {
+ };
+
+ int main ()
+
+ {
+ MI1 bar1;
+ MI2 bar2;
+ MI3 bar3;
+
+ if (dllMI1.vf() != D1_return)
+ abort();
+
+ if (bar1.vf() != D1_return)
+ abort();
+
+ if (bar2.vf() != (D2_return))
+ abort();
+
+ if (bar3.vf() != D1_return )
+ abort();
http://mobile.yahoo.com.au - Yahoo! Mobile
- Check & compose your email via SMS on your Telstra or Vodafone mobile.