]>
Commit | Line | Data |
---|---|---|
19551f29 | 1 | /* Language-dependent hooks for C++. |
e5f3b786 | 2 | Copyright 2001, 2002 Free Software Foundation, Inc. |
19551f29 AO |
3 | Contributed by Alexandre Oliva <aoliva@redhat.com> |
4 | ||
f5adbb8d | 5 | This file is part of GCC. |
19551f29 | 6 | |
f5adbb8d | 7 | GCC is free software; you can redistribute it and/or modify |
19551f29 AO |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2, or (at your option) | |
10 | any later version. | |
11 | ||
f5adbb8d | 12 | GCC is distributed in the hope that it will be useful, |
19551f29 AO |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
f5adbb8d | 18 | along with GCC; see the file COPYING. If not, write to |
19551f29 AO |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | #include "config.h" | |
23 | #include "system.h" | |
4977bab6 ZW |
24 | #include "coretypes.h" |
25 | #include "tm.h" | |
19551f29 AO |
26 | #include "tree.h" |
27 | #include "cp-tree.h" | |
ac79cd5a | 28 | #include "c-common.h" |
19551f29 AO |
29 | #include "toplev.h" |
30 | #include "langhooks.h" | |
d23c55c2 | 31 | #include "langhooks-def.h" |
19551f29 | 32 | |
848eed92 GDR |
33 | static HOST_WIDE_INT cxx_get_alias_set (tree); |
34 | static bool ok_to_generate_alias_set_for_type (tree); | |
35 | static bool cxx_warn_unused_global_decl (tree); | |
36 | static tree cp_expr_size (tree); | |
d78e771d | 37 | static size_t cp_tree_size (enum tree_code); |
848eed92 | 38 | static bool cp_var_mod_type_p (tree); |
8ac61af7 | 39 | |
3ac88239 NB |
40 | #undef LANG_HOOKS_NAME |
41 | #define LANG_HOOKS_NAME "GNU C++" | |
d78e771d ZW |
42 | #undef LANG_HOOKS_TREE_SIZE |
43 | #define LANG_HOOKS_TREE_SIZE cp_tree_size | |
19551f29 AO |
44 | #undef LANG_HOOKS_INIT |
45 | #define LANG_HOOKS_INIT cxx_init | |
46 | #undef LANG_HOOKS_FINISH | |
47 | #define LANG_HOOKS_FINISH cxx_finish | |
37207ee7 ZW |
48 | #undef LANG_HOOKS_CLEAR_BINDING_STACK |
49 | #define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything | |
19551f29 AO |
50 | #undef LANG_HOOKS_INIT_OPTIONS |
51 | #define LANG_HOOKS_INIT_OPTIONS cxx_init_options | |
52 | #undef LANG_HOOKS_DECODE_OPTION | |
0b6f2917 | 53 | #define LANG_HOOKS_DECODE_OPTION c_common_decode_option |
19551f29 | 54 | #undef LANG_HOOKS_POST_OPTIONS |
e5f3b786 | 55 | #define LANG_HOOKS_POST_OPTIONS c_common_post_options |
8ac61af7 RK |
56 | #undef LANG_HOOKS_GET_ALIAS_SET |
57 | #define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set | |
ac79cd5a RK |
58 | #undef LANG_HOOKS_EXPAND_CONSTANT |
59 | #define LANG_HOOKS_EXPAND_CONSTANT cplus_expand_constant | |
c9d892a8 NB |
60 | #undef LANG_HOOKS_EXPAND_EXPR |
61 | #define LANG_HOOKS_EXPAND_EXPR cxx_expand_expr | |
ac79cd5a RK |
62 | #undef LANG_HOOKS_SAFE_FROM_P |
63 | #define LANG_HOOKS_SAFE_FROM_P c_safe_from_p | |
52dabb6c NB |
64 | #undef LANG_HOOKS_PARSE_FILE |
65 | #define LANG_HOOKS_PARSE_FILE c_common_parse_file | |
63e1b1c4 NB |
66 | #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL |
67 | #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl | |
24965e7a NB |
68 | #undef LANG_HOOKS_UNSAVE_EXPR_NOW |
69 | #define LANG_HOOKS_UNSAVE_EXPR_NOW cxx_unsave_expr_now | |
7b3e5198 NB |
70 | #undef LANG_HOOKS_MAYBE_BUILD_CLEANUP |
71 | #define LANG_HOOKS_MAYBE_BUILD_CLEANUP cxx_maybe_build_cleanup | |
78ef5b89 NB |
72 | #undef LANG_HOOKS_TRUTHVALUE_CONVERSION |
73 | #define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion | |
7ffb4fd2 NB |
74 | #undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES |
75 | #define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES cxx_insert_default_attributes | |
48a7a235 NB |
76 | #undef LANG_HOOKS_UNSAFE_FOR_REEVAL |
77 | #define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval | |
599bba86 NB |
78 | #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME |
79 | #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME mangle_decl | |
dffd7eb6 NB |
80 | #undef LANG_HOOKS_MARK_ADDRESSABLE |
81 | #define LANG_HOOKS_MARK_ADDRESSABLE cxx_mark_addressable | |
5d69f816 NB |
82 | #undef LANG_HOOKS_PRINT_STATISTICS |
83 | #define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics | |
84 | #undef LANG_HOOKS_PRINT_XNODE | |
85 | #define LANG_HOOKS_PRINT_XNODE cxx_print_xnode | |
86 | #undef LANG_HOOKS_PRINT_DECL | |
87 | #define LANG_HOOKS_PRINT_DECL cxx_print_decl | |
88 | #undef LANG_HOOKS_PRINT_TYPE | |
89 | #define LANG_HOOKS_PRINT_TYPE cxx_print_type | |
90 | #undef LANG_HOOKS_PRINT_IDENTIFIER | |
91 | #define LANG_HOOKS_PRINT_IDENTIFIER cxx_print_identifier | |
7afff7cf NB |
92 | #undef LANG_HOOKS_DECL_PRINTABLE_NAME |
93 | #define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name | |
7cb32822 NB |
94 | #undef LANG_HOOKS_PRINT_ERROR_FUNCTION |
95 | #define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function | |
ef4f94ac RH |
96 | #undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL |
97 | #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl | |
2b59501b MA |
98 | #undef LANG_HOOKS_WRITE_GLOBALS |
99 | #define LANG_HOOKS_WRITE_GLOBALS lhd_do_nothing | |
100 | ||
19551f29 | 101 | |
b03e38e1 NB |
102 | #undef LANG_HOOKS_FUNCTION_INIT |
103 | #define LANG_HOOKS_FUNCTION_INIT cxx_push_function_context | |
e2500fed GK |
104 | #undef LANG_HOOKS_FUNCTION_FINAL |
105 | #define LANG_HOOKS_FUNCTION_FINAL cxx_pop_function_context | |
b03e38e1 | 106 | |
349ae713 NB |
107 | /* Attribute hooks. */ |
108 | #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE | |
109 | #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table | |
110 | #undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE | |
111 | #define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table | |
112 | #undef LANG_HOOKS_ATTRIBUTE_TABLE | |
113 | #define LANG_HOOKS_ATTRIBUTE_TABLE cxx_attribute_table | |
114 | ||
19551f29 AO |
115 | #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES |
116 | #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ | |
117 | cp_walk_subtrees | |
118 | #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN | |
119 | #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \ | |
120 | cp_cannot_inline_tree_fn | |
121 | #undef LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS | |
122 | #define LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS \ | |
123 | cp_add_pending_fn_decls | |
124 | #undef LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P | |
125 | #define LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P \ | |
126 | cp_is_overload_p | |
127 | #undef LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P | |
128 | #define LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P \ | |
129 | cp_auto_var_in_fn_p | |
130 | #undef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING | |
131 | #define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \ | |
132 | cp_copy_res_decl_for_inlining | |
133 | #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P | |
134 | #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p | |
8bcefb43 ZW |
135 | #undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P |
136 | #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P cp_var_mod_type_p | |
742a37d5 JM |
137 | #undef LANG_HOOKS_TREE_INLINING_START_INLINING |
138 | #define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining | |
139 | #undef LANG_HOOKS_TREE_INLINING_END_INLINING | |
140 | #define LANG_HOOKS_TREE_INLINING_END_INLINING cp_end_inlining | |
89d684bb BM |
141 | #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN |
142 | #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree | |
143 | #undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN | |
144 | #define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals | |
a77a9a18 JM |
145 | #undef LANG_HOOKS_EXPR_SIZE |
146 | #define LANG_HOOKS_EXPR_SIZE cp_expr_size | |
19551f29 | 147 | |
f1e639b1 NB |
148 | #undef LANG_HOOKS_MAKE_TYPE |
149 | #define LANG_HOOKS_MAKE_TYPE cxx_make_type | |
b0c48229 NB |
150 | #undef LANG_HOOKS_TYPE_FOR_MODE |
151 | #define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode | |
152 | #undef LANG_HOOKS_TYPE_FOR_SIZE | |
153 | #define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size | |
ceef8ce4 NB |
154 | #undef LANG_HOOKS_SIGNED_TYPE |
155 | #define LANG_HOOKS_SIGNED_TYPE c_common_signed_type | |
156 | #undef LANG_HOOKS_UNSIGNED_TYPE | |
157 | #define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type | |
158 | #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE | |
159 | #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type | |
7a228918 NB |
160 | #undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR |
161 | #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error | |
ab393bf1 NB |
162 | #undef LANG_HOOKS_TYPE_PROMOTES_TO |
163 | #define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to | |
f1e639b1 | 164 | |
19551f29 | 165 | /* Each front end provides its own hooks, for toplev.c. */ |
3ac88239 | 166 | const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; |
8ac61af7 | 167 | |
00a17e31 | 168 | /* Tree code classes. */ |
ef4f94ac RH |
169 | |
170 | #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, | |
171 | ||
172 | const char tree_code_type[] = { | |
173 | #include "tree.def" | |
174 | 'x', | |
175 | #include "c-common.def" | |
176 | 'x', | |
177 | #include "cp-tree.def" | |
178 | }; | |
179 | #undef DEFTREECODE | |
180 | ||
181 | /* Table indexed by tree code giving number of expression | |
182 | operands beyond the fixed part of the node structure. | |
183 | Not used for types or decls. */ | |
184 | ||
185 | #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, | |
186 | ||
187 | const unsigned char tree_code_length[] = { | |
188 | #include "tree.def" | |
189 | 0, | |
190 | #include "c-common.def" | |
191 | 0, | |
192 | #include "cp-tree.def" | |
193 | }; | |
194 | #undef DEFTREECODE | |
195 | ||
196 | /* Names of tree components. | |
197 | Used for printing out the tree and error messages. */ | |
198 | #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, | |
199 | ||
200 | const char *const tree_code_name[] = { | |
201 | #include "tree.def" | |
202 | "@@dummy", | |
203 | #include "c-common.def" | |
204 | "@@dummy", | |
205 | #include "cp-tree.def" | |
206 | }; | |
207 | #undef DEFTREECODE | |
208 | ||
61eece67 DN |
209 | /* Check if a C++ type is safe for aliasing. |
210 | Return TRUE if T safe for aliasing FALSE otherwise. */ | |
211 | ||
212 | static bool | |
848eed92 | 213 | ok_to_generate_alias_set_for_type (tree t) |
61eece67 DN |
214 | { |
215 | if (TYPE_PTRMEMFUNC_P (t)) | |
216 | return true; | |
217 | if (AGGREGATE_TYPE_P (t)) | |
218 | { | |
219 | if ((TREE_CODE (t) == RECORD_TYPE) || (TREE_CODE (t) == UNION_TYPE)) | |
220 | { | |
221 | tree fields; | |
0d08ea48 JM |
222 | /* Backend-created structs are safe. */ |
223 | if (! CLASS_TYPE_P (t)) | |
224 | return true; | |
61eece67 DN |
225 | /* PODs are safe. */ |
226 | if (! CLASSTYPE_NON_POD_P(t)) | |
227 | return true; | |
228 | /* Classes with virtual baseclasses are not. */ | |
229 | if (TYPE_USES_VIRTUAL_BASECLASSES (t)) | |
230 | return false; | |
231 | /* Recursively check the base classes. */ | |
232 | if (TYPE_BINFO (t) != NULL && TYPE_BINFO_BASETYPES (t) != NULL) | |
233 | { | |
234 | int i; | |
235 | for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); i++) | |
236 | { | |
237 | tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i); | |
238 | if (!ok_to_generate_alias_set_for_type (BINFO_TYPE (binfo))) | |
239 | return false; | |
240 | } | |
241 | } | |
242 | /* Check all the fields. */ | |
243 | for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) | |
244 | { | |
245 | if (TREE_CODE (fields) != FIELD_DECL) | |
246 | continue; | |
247 | if (! ok_to_generate_alias_set_for_type (TREE_TYPE (fields))) | |
248 | return false; | |
249 | } | |
250 | return true; | |
251 | } | |
252 | else if (TREE_CODE (t) == ARRAY_TYPE) | |
253 | return ok_to_generate_alias_set_for_type (TREE_TYPE (t)); | |
254 | else | |
255 | /* This should never happen, we dealt with all the aggregate | |
256 | types that can appear in C++ above. */ | |
257 | abort (); | |
258 | } | |
259 | else | |
260 | return true; | |
261 | } | |
262 | ||
8ac61af7 RK |
263 | /* Special routine to get the alias set for C++. */ |
264 | ||
265 | static HOST_WIDE_INT | |
848eed92 | 266 | cxx_get_alias_set (tree t) |
8ac61af7 | 267 | { |
1d719415 MM |
268 | |
269 | if (/* It's not yet safe to use alias sets for some classes in C++. */ | |
270 | !ok_to_generate_alias_set_for_type (t) | |
271 | /* Nor is it safe to use alias sets for pointers-to-member | |
272 | functions, due to the fact that there may be more than one | |
273 | RECORD_TYPE type corresponding to the same pointer-to-member | |
274 | type. */ | |
275 | || TYPE_PTRMEMFUNC_P (t)) | |
8ac61af7 RK |
276 | return 0; |
277 | ||
278 | return c_common_get_alias_set (t); | |
279 | } | |
ef4f94ac RH |
280 | |
281 | /* Called from check_global_declarations. */ | |
282 | ||
283 | static bool | |
848eed92 | 284 | cxx_warn_unused_global_decl (tree decl) |
ef4f94ac RH |
285 | { |
286 | if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) | |
287 | return false; | |
288 | if (DECL_IN_SYSTEM_HEADER (decl)) | |
289 | return false; | |
290 | ||
291 | /* Const variables take the place of #defines in C++. */ | |
292 | if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl)) | |
293 | return false; | |
294 | ||
295 | return true; | |
296 | } | |
a77a9a18 JM |
297 | |
298 | /* Langhook for expr_size: Tell the backend that the value of an expression | |
299 | of non-POD class type does not include any tail padding; a derived class | |
300 | might have allocated something there. */ | |
301 | ||
302 | static tree | |
848eed92 | 303 | cp_expr_size (tree exp) |
a77a9a18 JM |
304 | { |
305 | if (CLASS_TYPE_P (TREE_TYPE (exp))) | |
306 | { | |
307 | /* The backend should not be interested in the size of an expression | |
308 | of a type with both of these set; all copies of such types must go | |
309 | through a constructor or assignment op. */ | |
310 | if (TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp)) | |
d99f015c JM |
311 | && TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp)) |
312 | /* But storing a CONSTRUCTOR isn't a copy. */ | |
313 | && TREE_CODE (exp) != CONSTRUCTOR) | |
a77a9a18 JM |
314 | abort (); |
315 | /* This would be wrong for a type with virtual bases, but they are | |
316 | caught by the abort above. */ | |
317 | return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp)); | |
318 | } | |
319 | else | |
320 | /* Use the default code. */ | |
321 | return lhd_expr_size (exp); | |
322 | } | |
8bcefb43 | 323 | |
d78e771d ZW |
324 | /* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */ |
325 | static size_t | |
326 | cp_tree_size (enum tree_code code) | |
327 | { | |
328 | switch (code) | |
329 | { | |
330 | case PTRMEM_CST: return sizeof (struct ptrmem_cst); | |
331 | case BASELINK: return sizeof (struct tree_baselink); | |
332 | case TEMPLATE_PARM_INDEX: return sizeof (template_parm_index); | |
333 | case DEFAULT_ARG: return sizeof (struct tree_default_arg); | |
334 | case OVERLOAD: return sizeof (struct tree_overload); | |
335 | case WRAPPER: return sizeof (struct tree_wrapper); | |
336 | default: | |
337 | abort (); | |
338 | } | |
339 | /* NOTREACHED */ | |
340 | } | |
341 | ||
8bcefb43 ZW |
342 | /* Returns true if T is a variably modified type, in the sense of C99. |
343 | This routine needs only check cases that cannot be handled by the | |
344 | language-independent logic in tree-inline.c. */ | |
345 | ||
346 | static bool | |
347 | cp_var_mod_type_p (tree type) | |
348 | { | |
349 | /* If TYPE is a pointer-to-member, it is variably modified if either | |
350 | the class or the member are variably modified. */ | |
351 | if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type)) | |
352 | return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type)) | |
353 | || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type))); | |
354 | ||
355 | /* All other types are not variably modified. */ | |
356 | return false; | |
357 | } | |
358 |