OSDN Git Service

PR target/41512
authordannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Oct 2009 02:57:21 +0000 (02:57 +0000)
committerdannysmith <dannysmith@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Oct 2009 02:57:21 +0000 (02:57 +0000)
* config/i386/winnt.c (i386_pe_determine_dllexport_p): Don't propagate
dllexport to class members here.
(i386_pe_determine_dllimport_p): Only check static class data for
definition.
(i386_pe_encode_section_info): Don't recheck DECL_DLLIMPORT_P.
* config/i386/winnt-cxx.c (i386_pe_type_dllimport_p): Only check
functions for vague linkage.
(i386_pe_type_dllexport_p): Fix formatting.
(maybe_add_dllexport) New function.
(i386_pe_adjust_class_at_definition): Use it to propagate dllexport
to class members.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152511 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/winnt-cxx.c
gcc/config/i386/winnt.c

index a976d53..98e91f6 100644 (file)
@@ -1,4 +1,20 @@
-2009-10-07  Ben Elliston  <bje@au.ibm.com>
+
+2009-10-07  Danny Smith  <dannysmith@users.sourceforge.net>
+
+       PR target/41512
+       * config/i386/winnt.c (i386_pe_determine_dllexport_p): Don't propagate
+       dllexport to class members here.
+       (i386_pe_determine_dllimport_p): Only check static class data for
+       definition.
+       (i386_pe_encode_section_info): Don't recheck DECL_DLLIMPORT_P.
+       * config/i386/winnt-cxx.c (i386_pe_type_dllimport_p): Only check
+       functions for vague linkage.
+       (i386_pe_type_dllexport_p): Fix formatting.
+       (maybe_add_dllexport) New function.
+       (i386_pe_adjust_class_at_definition): Use it to propagate dllexport
+       to class members.
+       
+       2009-10-07  Ben Elliston  <bje@au.ibm.com>
 
        * config/rs6000/a2.md: Remove duplicated lines.
 
index 9df7cf6..48518ad 100644 (file)
@@ -1,7 +1,6 @@
 /* Target support for C++ classes on Windows.
    Contributed by Danny Smith (dannysmith@users.sourceforge.net)
-   Copyright (C) 2005, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2009  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -28,7 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hard-reg-set.h"
 #include "output.h"
 #include "tree.h"
-#include "cp/cp-tree.h" /* this is why we're a separate module */
+#include "cp/cp-tree.h" /* This is why we're a separate module.  */
 #include "flags.h"
 #include "tm_p.h"
 #include "toplev.h"
@@ -52,49 +51,44 @@ i386_pe_type_dllimport_p (tree decl)
          || DECL_TEMPLATE_INSTANTIATION (decl)
          || DECL_ARTIFICIAL (decl)))
     return false;
-
-
-  /* Don't mark defined functions as dllimport.  This code will only be
-     reached if we see a non-inline function defined out-of-class.  */
-  else if (TREE_CODE (decl) ==  FUNCTION_DECL
-          && (DECL_INITIAL (decl)))
-    return false;
-
-  /*  Don't allow definitions of static data members in dllimport class,
-      If vtable data is marked as DECL_EXTERNAL, import it; otherwise just
-      ignore the class attribute.  */
-  else if (TREE_CODE (decl) == VAR_DECL
-          && TREE_STATIC (decl) && TREE_PUBLIC (decl)
-          && !DECL_EXTERNAL (decl))
-    {
-      if (!DECL_VIRTUAL_P (decl))
-         error ("definition of static data member %q+D of "
-                "dllimport'd class", decl);
-      return false;
-    }
-
+  
+  /* Overrides of the class dllimport decls by out-of-class definitions are 
+     handled by tree.c:merge_dllimport_decl_attributes.   */
   return true;
 }
 
-
 bool
 i386_pe_type_dllexport_p (tree decl)
 {
-   gcc_assert (TREE_CODE (decl) == VAR_DECL 
-               || TREE_CODE (decl) == FUNCTION_DECL);
-   /* Avoid exporting compiler-generated default dtors and copy ctors.
-      The only artificial methods that need to be exported are virtual
-      and non-virtual thunks.  */
-   if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
-       && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl))
-     return false;
-   return true;
+  gcc_assert (TREE_CODE (decl) == VAR_DECL 
+              || TREE_CODE (decl) == FUNCTION_DECL);
+
+  /* Avoid exporting compiler-generated default dtors and copy ctors.
+     The only artificial methods that need to be exported are virtual
+     and non-virtual thunks.  */
+  if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
+      && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl))
+    return false;
+  return true;
 }
 
 static inline void maybe_add_dllimport (tree decl) 
 {
   if (i386_pe_type_dllimport_p (decl))
-    DECL_DLLIMPORT_P (decl) = 1;   
+    DECL_DLLIMPORT_P (decl) = 1;
+}
+
+static inline void maybe_add_dllexport (tree decl) 
+{
+  if (i386_pe_type_dllexport_p (decl))
+    {   
+      tree decl_attrs = DECL_ATTRIBUTES (decl);
+      if (lookup_attribute ("dllexport", decl_attrs) != NULL_TREE)
+       /* Already done.  */
+       return;
+      DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("dllexport"),
+                                         NULL_TREE, decl_attrs);
+    }
 }
 
 void
@@ -103,41 +97,69 @@ i386_pe_adjust_class_at_definition (tree t)
   tree member;
 
   gcc_assert (CLASS_TYPE_P (t));
+  if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
+    {
+      /* Check static VAR_DECL's.  */
+      for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
+       if (TREE_CODE (member) == VAR_DECL)     
+         maybe_add_dllexport (member);
+    
+      /* Check FUNCTION_DECL's.  */
+      for (member = TYPE_METHODS (t); member;  member = TREE_CHAIN (member))
+       if (TREE_CODE (member) == FUNCTION_DECL)
+         {
+           tree thunk;
+           maybe_add_dllexport (member);
+         
+           /* Also add the attribute to its thunks.  */
+           for (thunk = DECL_THUNKS (member); thunk;
+                thunk = TREE_CHAIN (thunk))
+             maybe_add_dllexport (thunk);
+       }
+      /* Check vtables  */
+      for (member = CLASSTYPE_VTABLES (t); member;  member = TREE_CHAIN (member))
+       if (TREE_CODE (member) == VAR_DECL) 
+         maybe_add_dllexport (member);
+    }
 
- /* We only look at dllimport.  The only thing that dllexport does is
-    add stuff to a '.drectiv' section at end-of-file, so no need to do
-    anything for dllexport'd classes until we generate RTL. */  
-  if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) == NULL_TREE)
-    return;
-
-  /* We don't actually add the attribute to the decl, just set the flag
-     that signals that the address of this symbol is not a compile-time
-     constant.   Any subsequent out-of-class declaration of members wil
-     cause the DECL_DLLIMPORT_P flag to be unset.
-     (See  tree.c: merge_dllimport_decl_attributes).
-     That is just right since out-of class declarations can only be a
-     definition.  We recheck the class members  at RTL generation to
-     emit warnings if this has happened.  Definition of static data member
-     of dllimport'd class always causes an error (as per MS compiler).
-  */
-
-  /* Check static VAR_DECL's.  */
-  for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
-    if (TREE_CODE (member) == VAR_DECL)     
-      maybe_add_dllimport (member);
+  else if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
+    {
+      /* We don't actually add the attribute to the decl, just set the flag
+        that signals that the address of this symbol is not a compile-time
+        constant.   Any subsequent out-of-class declaration of members wil
+        cause the DECL_DLLIMPORT_P flag to be unset.
+        (See  tree.c: merge_dllimport_decl_attributes).
+        That is just right since out-of class declarations can only be a
+        definition.   */
+
+      /* Check static VAR_DECL's.  */
+      for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
+       if (TREE_CODE (member) == VAR_DECL)     
+         maybe_add_dllimport (member);
     
-  /* Check FUNCTION_DECL's.  */
-  for (member = TYPE_METHODS (t); member;  member = TREE_CHAIN (member))
-    if (TREE_CODE (member) == FUNCTION_DECL)
-      maybe_add_dllimport (member);
+      /* Check FUNCTION_DECL's.  */
+      for (member = TYPE_METHODS (t); member;  member = TREE_CHAIN (member))
+       if (TREE_CODE (member) == FUNCTION_DECL)
+         {
+           tree thunk;
+           maybe_add_dllimport (member);
+         
+           /* Also add the attribute to its thunks.  */
+           for (thunk = DECL_THUNKS (member); thunk;
+                thunk = TREE_CHAIN (thunk))
+             maybe_add_dllimport (thunk);
+        }
  
-  /* Check vtables  */
-  for (member = CLASSTYPE_VTABLES (t); member;  member = TREE_CHAIN (member))
-    if (TREE_CODE (member) == VAR_DECL) 
-      maybe_add_dllimport (member);
-
-/* We leave typeinfo tables alone.  We can't mark TI objects as
-     dllimport, since the address of a secondary VTT may be needed
-     for static initialization of a primary VTT.  VTT's  of
-     dllimport'd classes should always be link-once COMDAT.  */ 
+      /* Check vtables  */
+      for (member = CLASSTYPE_VTABLES (t); member;  member = TREE_CHAIN (member))
+       if (TREE_CODE (member) == VAR_DECL) 
+         maybe_add_dllimport (member);
+
+      /* We leave typeinfo tables alone.  We can't mark TI objects as
+       dllimport, since the address of a secondary VTT may be needed
+       for static initialization of a primary VTT.  VTT's  of
+       dllimport'd classes should always be link-once COMDAT.  */ 
+    }
 }
index 7069c40..f8dcaa9 100644 (file)
@@ -102,8 +102,6 @@ associated_type (tree decl)
 static bool
 i386_pe_determine_dllexport_p (tree decl)
 {
-  tree assoc;
-
   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
     return false;
 
@@ -114,11 +112,6 @@ i386_pe_determine_dllexport_p (tree decl)
   if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
     return true;
 
-  /* Also mark class members of exported classes with dllexport.  */
-  assoc = associated_type (decl);
-  if (assoc && lookup_attribute ("dllexport", TYPE_ATTRIBUTES (assoc)))
-    return i386_pe_type_dllexport_p (decl);
-
   return false;
 }
 
@@ -132,18 +125,23 @@ i386_pe_determine_dllimport_p (tree decl)
   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
     return false;
 
-  /* Lookup the attribute in addition to checking the DECL_DLLIMPORT_P flag.
-     We may need to override an earlier decision.  */
   if (DECL_DLLIMPORT_P (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 overridden by an
-     out-of-class definition.  */
+     error message if the class attribute has been overridden by an
+     out-of-class definition of static data.  */
   assoc = associated_type (decl);
-  if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc)))
-    return i386_pe_type_dllimport_p (decl);
+  if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))
+      && TREE_CODE (decl) == VAR_DECL
+      && TREE_STATIC (decl) && TREE_PUBLIC (decl)
+      && !DECL_EXTERNAL (decl)
+      /* vtable's are linkonce constants, so defining a vtable is not
+        an error as long as we don't try to import it too.  */
+      && !DECL_VIRTUAL_P (decl))
+       error ("definition of static data member %q+D of "
+              "dllimport'd class", decl);
 
   return false;
 }
@@ -308,17 +306,8 @@ i386_pe_encode_section_info (tree decl, rtx rtl, int first)
   if (i386_pe_determine_dllexport_p (decl))
     flags |= SYMBOL_FLAG_DLLEXPORT;
   else if (i386_pe_determine_dllimport_p (decl))
-    {
-      flags |= SYMBOL_FLAG_DLLIMPORT;
-      /* If we went through the associated_type path, this won't already
-        be set.  Though, frankly, this seems wrong, and should be fixed
-        elsewhere.  */
-      if (!DECL_DLLIMPORT_P (decl))
-       {
-         DECL_DLLIMPORT_P (decl) = 1;
-         flags &= ~SYMBOL_FLAG_LOCAL;
-       }
-    }
+    flags |= SYMBOL_FLAG_DLLIMPORT;
   SYMBOL_REF_FLAGS (symbol) = flags;
 }