Mercurial > hg > CbC > CbC_gcc
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 } |