This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]