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]

Re: [Patch: mingw/cygwin] Handle export of MI thunks from windows dll's


 --- Jason Merrill <jason@...> wrote: > On Sun, 6 Jul 2003 07:02:54 +1000 (EST), Danny Smith
<danny_r_smith_2001@...> wrote:
> 
> --- Jason Merrill <jason@...> wrote: 
> 
> >> Rather than remove the check for DECL_ARTIFICIAL, you should be able to
> >> add a check for DECL_THUNK_P to handle thunks.  We still don't want
> >> import/export to affect synthesized copy ctors et al.
> >
> > I was going to, but that would mean including cp/cp-tree.h.  I didn't think
> > inclusion of language-specific files or using a language-specific flag
> > was a good thing to do. (No other targets seem to.)
> 
> No, indeed, sorry.  So you'll need to check different flags instead.  Does
> it work to avoid setting dllexport on DECL_COMDAT decls?


Thanks for the suggestion to look at DECL_COMDAT.  In the end I used DECL_COMDAT
in the opposite way. Here are revised patch and testcases. 

Default copy ctors and default dtor's (DECL_COMDAT not set) do not get
dllimport/export attribute from containing class. Thunks do.
We use the attribute to mark thunks for export so that they end up in the dll,
but ignore it for import of artificial methos, as we do with virtual methods,
so that we don't run into problem with non-constant address.

The testcases now test for non-export of default copy ctor and default dtor.

Danny


2003-07-10  Danny Smith  <dannysmith@users.sourceforge.net>

	* config/i386/winnt.c (associated_type): Artificial methods are not
	affected by the import/export status of their class unless they are
	COMDAT.
	(i386_pe_dllimport_p): Do not mark artificial methods as dllimport.

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.

Index: config/i386/winnt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/winnt.c,v
retrieving revision 1.51
diff -c -3 -p -r1.51 winnt.c
*** config/i386/winnt.c	8 Jul 2003 23:40:36 -0000	1.51
--- config/i386/winnt.c	10 Jul 2003 10:53:36 -0000
*************** associated_type (decl)
*** 174,182 ****
       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)
--- 174,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 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 = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
      }
    else if (DECL_CONTEXT (decl)
*************** i386_pe_dllimport_p (decl)
*** 279,287 ****
  
        /* 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;
--- 281,291 ----
  
        /* 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;
*** /dev/null	Thu Jul 10 11:44:46 2003
--- testsuite/g++.dg/ext/dll-MI1.h	Wed Jul  9 09:36:08 2003
***************
*** 0 ****
--- 1,39 ----
+ // 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:
+   D2 ();
+   D2 (D2 const&);
+   int vf() const;
+ };
+ 
+ class DLL_IMPEXP MI1 : public D1, public D2
+ {
+ public:
+   int vf() const;
+ };
+ 
*** /dev/null	Thu Jul 10 11:44:46 2003
--- testsuite/g++.dg/ext/dllexport-MI1.C	Thu Jul 10 07:42:00 2003
***************
*** 0 ****
--- 1,51 ----
+ // { 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; }
+ 
+ D2::D2() { }
+ D2::D2 (D2 const&) { }
+ int D2::vf() const { return D2_return; }
+ 
+ int MI1::vf() const { return D1::vf();}
+ 
+ // a dllexported object 
+ DLL_IMPEXP MI1 dllMI1;
+ 
+ // use default copy ctor 
+ DLL_IMPEXP MI1 dllMI1Copy =  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" } }
+ 
+ // an explicit copy ctor
+ // { dg-final { scan-assembler "-export:_ZN2D2C2ERKS_" } }
+ 
+ // but not implicit copy ctor generated by compiler
+ // nor implicit dtor
+ 
+ // { dg-final { scan-assembler-not "-export:_ZN2D1C2ERKS_" } }
+ // { dg-final { scan-assembler-not "-export:_ZN2D1D2Ev" } }
+ 
*** /dev/null	Thu Jul 10 11:44:46 2003
--- testsuite/g++.dg/ext/dllimport-MI1.C	Wed Jul  9 10:14:23 2003
***************
*** 0 ****
--- 1,53 ----
+ // { 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;
+ 
+ // This should use the implicit copy ctor for D1 (not imported)
+ // and the explicit copy ctor for D2 (dll-imported). 
+ MI1 dllMI1LocalCopy = 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 (dllMI1LocalCopy.vf() != D1_return)
+     abort();
+ 
+   if (bar1.vf() != D1_return)
+     abort();
+ 
+   if (bar2.vf() != (D2_return))
+     abort();
+ 
+   if (bar3.vf() != D1_return )
+     abort();
+ }
+ 
+ // Scan for import of explicit copy ctor for D2, but no import
+ // of compiler generated copy ctor for D1. 
+ // { dg-final { scan-assembler  "__imp___ZN2D2C2ERKS_" } }
+ // { dg-final { scan-assembler-not "__imp___ZN2D1C2ERKS_" } }


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]