comparison gcc/config/i386/winnt-cxx.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents a06113de4d67
children f6334be47118
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* Target support for C++ classes on Windows. 1 /* Target support for C++ classes on Windows.
2 Contributed by Danny Smith (dannysmith@users.sourceforge.net) 2 Contributed by Danny Smith (dannysmith@users.sourceforge.net)
3 Copyright (C) 2005, 2007 3 Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
4 Free Software Foundation, Inc.
5 4
6 This file is part of GCC. 5 This file is part of GCC.
7 6
8 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free 8 the terms of the GNU General Public License as published by the Free
26 #include "rtl.h" 25 #include "rtl.h"
27 #include "regs.h" 26 #include "regs.h"
28 #include "hard-reg-set.h" 27 #include "hard-reg-set.h"
29 #include "output.h" 28 #include "output.h"
30 #include "tree.h" 29 #include "tree.h"
31 #include "cp/cp-tree.h" /* this is why we're a separate module */ 30 #include "cp/cp-tree.h" /* This is why we're a separate module. */
32 #include "flags.h" 31 #include "flags.h"
33 #include "tm_p.h" 32 #include "tm_p.h"
34 #include "toplev.h" 33 #include "toplev.h"
35 #include "hashtab.h" 34 #include "hashtab.h"
36 35
50 if (TREE_CODE (decl) == FUNCTION_DECL 49 if (TREE_CODE (decl) == FUNCTION_DECL
51 && (DECL_DECLARED_INLINE_P (decl) 50 && (DECL_DECLARED_INLINE_P (decl)
52 || DECL_TEMPLATE_INSTANTIATION (decl) 51 || DECL_TEMPLATE_INSTANTIATION (decl)
53 || DECL_ARTIFICIAL (decl))) 52 || DECL_ARTIFICIAL (decl)))
54 return false; 53 return false;
55 54
56 55 /* Overrides of the class dllimport decls by out-of-class definitions are
57 /* Don't mark defined functions as dllimport. This code will only be 56 handled by tree.c:merge_dllimport_decl_attributes. */
58 reached if we see a non-inline function defined out-of-class. */
59 else if (TREE_CODE (decl) == FUNCTION_DECL
60 && (DECL_INITIAL (decl)))
61 return false;
62
63 /* Don't allow definitions of static data members in dllimport class,
64 If vtable data is marked as DECL_EXTERNAL, import it; otherwise just
65 ignore the class attribute. */
66 else if (TREE_CODE (decl) == VAR_DECL
67 && TREE_STATIC (decl) && TREE_PUBLIC (decl)
68 && !DECL_EXTERNAL (decl))
69 {
70 if (!DECL_VIRTUAL_P (decl))
71 error ("definition of static data member %q+D of "
72 "dllimport'd class", decl);
73 return false;
74 }
75
76 return true; 57 return true;
77 } 58 }
78
79 59
80 bool 60 bool
81 i386_pe_type_dllexport_p (tree decl) 61 i386_pe_type_dllexport_p (tree decl)
82 { 62 {
83 gcc_assert (TREE_CODE (decl) == VAR_DECL 63 gcc_assert (TREE_CODE (decl) == VAR_DECL
84 || TREE_CODE (decl) == FUNCTION_DECL); 64 || TREE_CODE (decl) == FUNCTION_DECL);
85 /* Avoid exporting compiler-generated default dtors and copy ctors. 65
86 The only artificial methods that need to be exported are virtual 66 /* Avoid exporting compiler-generated default dtors and copy ctors.
87 and non-virtual thunks. */ 67 The only artificial methods that need to be exported are virtual
88 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE 68 and non-virtual thunks. */
89 && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl)) 69 if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
90 return false; 70 && DECL_ARTIFICIAL (decl) && !DECL_THUNK_P (decl))
91 return true; 71 return false;
72 return true;
92 } 73 }
93 74
94 static inline void maybe_add_dllimport (tree decl) 75 static inline void maybe_add_dllimport (tree decl)
95 { 76 {
96 if (i386_pe_type_dllimport_p (decl)) 77 if (i386_pe_type_dllimport_p (decl))
97 DECL_DLLIMPORT_P (decl) = 1; 78 DECL_DLLIMPORT_P (decl) = 1;
79 }
80
81 static inline void maybe_add_dllexport (tree decl)
82 {
83 if (i386_pe_type_dllexport_p (decl))
84 {
85 tree decl_attrs = DECL_ATTRIBUTES (decl);
86 if (lookup_attribute ("dllexport", decl_attrs) != NULL_TREE)
87 /* Already done. */
88 return;
89 DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("dllexport"),
90 NULL_TREE, decl_attrs);
91 }
98 } 92 }
99 93
100 void 94 void
101 i386_pe_adjust_class_at_definition (tree t) 95 i386_pe_adjust_class_at_definition (tree t)
102 { 96 {
103 tree member; 97 tree member;
104 98
105 gcc_assert (CLASS_TYPE_P (t)); 99 gcc_assert (CLASS_TYPE_P (t));
100
101
102 if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
103 {
104 /* Check static VAR_DECL's. */
105 for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
106 if (TREE_CODE (member) == VAR_DECL)
107 maybe_add_dllexport (member);
108
109 /* Check FUNCTION_DECL's. */
110 for (member = TYPE_METHODS (t); member; member = TREE_CHAIN (member))
111 if (TREE_CODE (member) == FUNCTION_DECL)
112 {
113 tree thunk;
114 maybe_add_dllexport (member);
115
116 /* Also add the attribute to its thunks. */
117 for (thunk = DECL_THUNKS (member); thunk;
118 thunk = TREE_CHAIN (thunk))
119 maybe_add_dllexport (thunk);
120 }
121 /* Check vtables */
122 for (member = CLASSTYPE_VTABLES (t); member; member = TREE_CHAIN (member))
123 if (TREE_CODE (member) == VAR_DECL)
124 maybe_add_dllexport (member);
125 }
106 126
107 /* We only look at dllimport. The only thing that dllexport does is 127 else if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) != NULL_TREE)
108 add stuff to a '.drectiv' section at end-of-file, so no need to do 128 {
109 anything for dllexport'd classes until we generate RTL. */ 129 /* We don't actually add the attribute to the decl, just set the flag
110 if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (t)) == NULL_TREE) 130 that signals that the address of this symbol is not a compile-time
111 return; 131 constant. Any subsequent out-of-class declaration of members wil
132 cause the DECL_DLLIMPORT_P flag to be unset.
133 (See tree.c: merge_dllimport_decl_attributes).
134 That is just right since out-of class declarations can only be a
135 definition. */
112 136
113 /* We don't actually add the attribute to the decl, just set the flag 137 /* Check static VAR_DECL's. */
114 that signals that the address of this symbol is not a compile-time 138 for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member))
115 constant. Any subsequent out-of-class declaration of members wil 139 if (TREE_CODE (member) == VAR_DECL)
116 cause the DECL_DLLIMPORT_P flag to be unset. 140 maybe_add_dllimport (member);
117 (See tree.c: merge_dllimport_decl_attributes). 141
118 That is just right since out-of class declarations can only be a 142 /* Check FUNCTION_DECL's. */
119 definition. We recheck the class members at RTL generation to 143 for (member = TYPE_METHODS (t); member; member = TREE_CHAIN (member))
120 emit warnings if this has happened. Definition of static data member 144 if (TREE_CODE (member) == FUNCTION_DECL)
121 of dllimport'd class always causes an error (as per MS compiler). 145 {
122 */ 146 tree thunk;
147 maybe_add_dllimport (member);
148
149 /* Also add the attribute to its thunks. */
150 for (thunk = DECL_THUNKS (member); thunk;
151 thunk = TREE_CHAIN (thunk))
152 maybe_add_dllimport (thunk);
153 }
154
155 /* Check vtables */
156 for (member = CLASSTYPE_VTABLES (t); member; member = TREE_CHAIN (member))
157 if (TREE_CODE (member) == VAR_DECL)
158 maybe_add_dllimport (member);
123 159
124 /* Check static VAR_DECL's. */ 160 /* We leave typeinfo tables alone. We can't mark TI objects as
125 for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) 161 dllimport, since the address of a secondary VTT may be needed
126 if (TREE_CODE (member) == VAR_DECL) 162 for static initialization of a primary VTT. VTT's of
127 maybe_add_dllimport (member); 163 dllimport'd classes should always be link-once COMDAT. */
128 164 }
129 /* Check FUNCTION_DECL's. */
130 for (member = TYPE_METHODS (t); member; member = TREE_CHAIN (member))
131 if (TREE_CODE (member) == FUNCTION_DECL)
132 maybe_add_dllimport (member);
133
134 /* Check vtables */
135 for (member = CLASSTYPE_VTABLES (t); member; member = TREE_CHAIN (member))
136 if (TREE_CODE (member) == VAR_DECL)
137 maybe_add_dllimport (member);
138
139 /* We leave typeinfo tables alone. We can't mark TI objects as
140 dllimport, since the address of a secondary VTT may be needed
141 for static initialization of a primary VTT. VTT's of
142 dllimport'd classes should always be link-once COMDAT. */
143 } 165 }