1 | /* Some code common to C++ and ObjC++ front ends. |
2 | Copyright (C) 2004-2024 Free Software Foundation, Inc. |
3 | Contributed by Ziemowit Laski <zlaski@apple.com> |
4 | |
5 | This file is part of GCC. |
6 | |
7 | GCC is free software; you can redistribute it and/or modify it under |
8 | the terms of the GNU General Public License as published by the Free |
9 | Software Foundation; either version 3, or (at your option) any later |
10 | version. |
11 | |
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
15 | for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ |
20 | |
21 | #include "config.h" |
22 | #include "system.h" |
23 | #include "coretypes.h" |
24 | #include "cp-tree.h" |
25 | #include "cp-objcp-common.h" |
26 | #include "c-family/c-common.h" |
27 | #include "dwarf2.h" |
28 | #include "stringpool.h" |
29 | #include "contracts.h" |
30 | |
31 | /* Class to determine whether a given C++ language feature is available. |
32 | Used to implement __has_{feature,extension}. */ |
33 | |
34 | struct cp_feature_selector |
35 | { |
36 | enum |
37 | { |
38 | DIALECT, |
39 | FLAG |
40 | } kind; |
41 | |
42 | enum class result |
43 | { |
44 | NONE, |
45 | EXT, |
46 | FEAT |
47 | }; |
48 | |
49 | union |
50 | { |
51 | const int *enable_flag; |
52 | struct { |
53 | enum cxx_dialect feat; |
54 | enum cxx_dialect ext; |
55 | } dialect; |
56 | }; |
57 | |
58 | constexpr cp_feature_selector (const int *flag) |
59 | : kind (FLAG), enable_flag (flag) {} |
60 | constexpr cp_feature_selector (enum cxx_dialect feat, |
61 | enum cxx_dialect ext) |
62 | : kind (DIALECT), dialect{.feat: feat, .ext: ext} {} |
63 | constexpr cp_feature_selector (enum cxx_dialect feat) |
64 | : cp_feature_selector (feat, feat) {} |
65 | |
66 | inline result has_feature () const; |
67 | }; |
68 | |
69 | /* Check whether this language feature is available as a feature, |
70 | extension, or not at all. */ |
71 | |
72 | cp_feature_selector::result |
73 | cp_feature_selector::has_feature () const |
74 | { |
75 | switch (kind) |
76 | { |
77 | case DIALECT: |
78 | if (cxx_dialect >= dialect.feat) |
79 | return result::FEAT; |
80 | else if (cxx_dialect >= dialect.ext) |
81 | return result::EXT; |
82 | else |
83 | return result::NONE; |
84 | case FLAG: |
85 | return *enable_flag ? result::FEAT : result::NONE; |
86 | } |
87 | |
88 | gcc_unreachable (); |
89 | } |
90 | |
91 | /* Information about a C++ language feature which can be queried |
92 | through __has_{feature,extension}. IDENT is the name of the feature, |
93 | and SELECTOR encodes how to compute whether the feature is available. */ |
94 | |
95 | struct cp_feature_info |
96 | { |
97 | const char *ident; |
98 | cp_feature_selector selector; |
99 | }; |
100 | |
101 | /* Table of features for __has_{feature,extension}. */ |
102 | |
103 | static constexpr cp_feature_info cp_feature_table[] = |
104 | { |
105 | { .ident: "cxx_exceptions" , .selector: &flag_exceptions }, |
106 | { .ident: "cxx_rtti" , .selector: &flag_rtti }, |
107 | { .ident: "cxx_access_control_sfinae" , .selector: { cxx11, cxx98 } }, |
108 | { .ident: "cxx_alias_templates" , .selector: cxx11 }, |
109 | { .ident: "cxx_alignas" , .selector: cxx11 }, |
110 | { .ident: "cxx_alignof" , .selector: cxx11 }, |
111 | { .ident: "cxx_attributes" , .selector: cxx11 }, |
112 | { .ident: "cxx_constexpr" , .selector: cxx11 }, |
113 | { .ident: "cxx_decltype" , .selector: cxx11 }, |
114 | { .ident: "cxx_decltype_incomplete_return_types" , .selector: cxx11 }, |
115 | { .ident: "cxx_default_function_template_args" , .selector: cxx11 }, |
116 | { .ident: "cxx_defaulted_functions" , .selector: cxx11 }, |
117 | { .ident: "cxx_delegating_constructors" , .selector: cxx11 }, |
118 | { .ident: "cxx_deleted_functions" , .selector: cxx11 }, |
119 | { .ident: "cxx_explicit_conversions" , .selector: cxx11 }, |
120 | { .ident: "cxx_generalized_initializers" , .selector: cxx11 }, |
121 | { .ident: "cxx_implicit_moves" , .selector: cxx11 }, |
122 | { .ident: "cxx_inheriting_constructors" , .selector: cxx11 }, |
123 | { .ident: "cxx_inline_namespaces" , .selector: { cxx11, cxx98 } }, |
124 | { .ident: "cxx_lambdas" , .selector: cxx11 }, |
125 | { .ident: "cxx_local_type_template_args" , .selector: cxx11 }, |
126 | { .ident: "cxx_noexcept" , .selector: cxx11 }, |
127 | { .ident: "cxx_nonstatic_member_init" , .selector: cxx11 }, |
128 | { .ident: "cxx_nullptr" , .selector: cxx11 }, |
129 | { .ident: "cxx_override_control" , .selector: cxx11 }, |
130 | { .ident: "cxx_reference_qualified_functions" , .selector: cxx11 }, |
131 | { .ident: "cxx_range_for" , .selector: cxx11 }, |
132 | { .ident: "cxx_raw_string_literals" , .selector: cxx11 }, |
133 | { .ident: "cxx_rvalue_references" , .selector: cxx11 }, |
134 | { .ident: "cxx_static_assert" , .selector: cxx11 }, |
135 | { .ident: "cxx_thread_local" , .selector: cxx11 }, |
136 | { .ident: "cxx_auto_type" , .selector: cxx11 }, |
137 | { .ident: "cxx_strong_enums" , .selector: cxx11 }, |
138 | { .ident: "cxx_trailing_return" , .selector: cxx11 }, |
139 | { .ident: "cxx_unicode_literals" , .selector: cxx11 }, |
140 | { .ident: "cxx_unrestricted_unions" , .selector: cxx11 }, |
141 | { .ident: "cxx_user_literals" , .selector: cxx11 }, |
142 | { .ident: "cxx_variadic_templates" , .selector: { cxx11, cxx98 } }, |
143 | { .ident: "cxx_binary_literals" , .selector: { cxx14, cxx98 } }, |
144 | { .ident: "cxx_contextual_conversions" , .selector: { cxx14, cxx98 } }, |
145 | { .ident: "cxx_decltype_auto" , .selector: cxx14 }, |
146 | { .ident: "cxx_aggregate_nsdmi" , .selector: cxx14 }, |
147 | { .ident: "cxx_init_captures" , .selector: { cxx14, cxx11 } }, |
148 | { .ident: "cxx_generic_lambdas" , .selector: cxx14 }, |
149 | { .ident: "cxx_relaxed_constexpr" , .selector: cxx14 }, |
150 | { .ident: "cxx_return_type_deduction" , .selector: cxx14 }, |
151 | { .ident: "cxx_variable_templates" , .selector: cxx14 }, |
152 | { .ident: "modules" , .selector: &flag_modules }, |
153 | }; |
154 | |
155 | /* Register C++ language features for __has_{feature,extension}. */ |
156 | |
157 | void |
158 | cp_register_features () |
159 | { |
160 | using result = cp_feature_selector::result; |
161 | |
162 | for (unsigned i = 0; i < ARRAY_SIZE (cp_feature_table); i++) |
163 | { |
164 | const cp_feature_info *info = cp_feature_table + i; |
165 | const auto res = info->selector.has_feature (); |
166 | if (res == result::NONE) |
167 | continue; |
168 | |
169 | c_common_register_feature (info->ident, res == result::FEAT); |
170 | } |
171 | } |
172 | |
173 | /* Special routine to get the alias set for C++. */ |
174 | |
175 | alias_set_type |
176 | cxx_get_alias_set (tree t) |
177 | { |
178 | if (IS_FAKE_BASE_TYPE (t)) |
179 | /* The base variant of a type must be in the same alias set as the |
180 | complete type. */ |
181 | return get_alias_set (TYPE_CONTEXT (t)); |
182 | |
183 | /* Punt on PMFs until we canonicalize functions properly. */ |
184 | if (TYPE_PTRMEMFUNC_P (t) |
185 | || (INDIRECT_TYPE_P (t) |
186 | && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))) |
187 | return 0; |
188 | |
189 | return c_common_get_alias_set (t); |
190 | } |
191 | |
192 | /* Called from check_global_declaration. */ |
193 | |
194 | bool |
195 | cxx_warn_unused_global_decl (const_tree decl) |
196 | { |
197 | if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) |
198 | return false; |
199 | if (DECL_IN_SYSTEM_HEADER (decl)) |
200 | return false; |
201 | |
202 | return true; |
203 | } |
204 | |
205 | /* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */ |
206 | size_t |
207 | cp_tree_size (enum tree_code code) |
208 | { |
209 | gcc_checking_assert (code >= NUM_TREE_CODES); |
210 | switch (code) |
211 | { |
212 | case PTRMEM_CST: return sizeof (ptrmem_cst); |
213 | case BASELINK: return sizeof (tree_baselink); |
214 | case TEMPLATE_PARM_INDEX: return sizeof (template_parm_index); |
215 | case DEFERRED_PARSE: return sizeof (tree_deferred_parse); |
216 | case DEFERRED_NOEXCEPT: return sizeof (tree_deferred_noexcept); |
217 | case OVERLOAD: return sizeof (tree_overload); |
218 | case STATIC_ASSERT: return sizeof (tree_static_assert); |
219 | #if 0 |
220 | /* This would match cp_common_init_ts, but breaks GC because |
221 | tree_node_structure_for_code returns TS_TYPE_NON_COMMON for all |
222 | types. */ |
223 | case UNBOUND_CLASS_TEMPLATE: |
224 | case TYPE_ARGUMENT_PACK: return sizeof (tree_type_common); |
225 | #endif |
226 | case ARGUMENT_PACK_SELECT: return sizeof (tree_argument_pack_select); |
227 | case TRAIT_EXPR: return sizeof (tree_trait_expr); |
228 | case LAMBDA_EXPR: return sizeof (tree_lambda_expr); |
229 | case TEMPLATE_INFO: return sizeof (tree_template_info); |
230 | case CONSTRAINT_INFO: return sizeof (tree_constraint_info); |
231 | case USERDEF_LITERAL: return sizeof (tree_userdef_literal); |
232 | case TEMPLATE_DECL: return sizeof (tree_template_decl); |
233 | case ASSERTION_STMT: return sizeof (tree_exp); |
234 | case PRECONDITION_STMT: return sizeof (tree_exp); |
235 | case POSTCONDITION_STMT: return sizeof (tree_exp); |
236 | default: |
237 | switch (TREE_CODE_CLASS (code)) |
238 | { |
239 | case tcc_declaration: return sizeof (tree_decl_non_common); |
240 | case tcc_type: return sizeof (tree_type_non_common); |
241 | default: gcc_unreachable (); |
242 | } |
243 | } |
244 | /* NOTREACHED */ |
245 | } |
246 | |
247 | /* Returns true if T is a variably modified type, in the sense of C99. |
248 | FN is as passed to variably_modified_p. |
249 | This routine needs only check cases that cannot be handled by the |
250 | language-independent logic in tree.cc. */ |
251 | |
252 | bool |
253 | cp_var_mod_type_p (tree type, tree fn) |
254 | { |
255 | /* If TYPE is a pointer-to-member, it is variably modified if either |
256 | the class or the member are variably modified. */ |
257 | if (TYPE_PTRMEM_P (type)) |
258 | return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type), fn) |
259 | || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type), |
260 | fn)); |
261 | |
262 | /* All other types are not variably modified. */ |
263 | return false; |
264 | } |
265 | |
266 | /* This compares two types for equivalence ("compatible" in C-based languages). |
267 | This routine should only return 1 if it is sure. It should not be used |
268 | in contexts where erroneously returning 0 causes problems. */ |
269 | |
270 | int |
271 | cxx_types_compatible_p (tree x, tree y) |
272 | { |
273 | return same_type_ignoring_top_level_qualifiers_p (x, y); |
274 | } |
275 | |
276 | static GTY((cache)) type_tree_cache_map *debug_type_map; |
277 | |
278 | /* Return a type to use in the debug info instead of TYPE, or NULL_TREE to |
279 | keep TYPE. */ |
280 | |
281 | tree |
282 | cp_get_debug_type (const_tree type) |
283 | { |
284 | tree dtype = NULL_TREE; |
285 | |
286 | if (TYPE_PTRMEMFUNC_P (type) && !typedef_variant_p (type)) |
287 | dtype = build_offset_type (TYPE_PTRMEMFUNC_OBJECT_TYPE (type), |
288 | TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type))); |
289 | |
290 | /* We cannot simply return the debug type here because the function uses |
291 | the type canonicalization hashtable, which is GC-ed, so its behavior |
292 | depends on the actual collection points. Since we are building these |
293 | types on the fly for the debug info only, they would not be attached |
294 | to any GC root and always be swept, so we would make the contents of |
295 | the debug info depend on the collection points. */ |
296 | if (dtype) |
297 | { |
298 | tree ktype = CONST_CAST_TREE (type); |
299 | if (tree *slot = hash_map_safe_get (h: debug_type_map, k: ktype)) |
300 | return *slot; |
301 | hash_map_safe_put<hm_ggc> (h&: debug_type_map, k: ktype, v: dtype); |
302 | } |
303 | |
304 | return dtype; |
305 | } |
306 | |
307 | /* Return -1 if dwarf ATTR shouldn't be added for DECL, or the attribute |
308 | value otherwise. */ |
309 | int |
310 | cp_decl_dwarf_attribute (const_tree decl, int attr) |
311 | { |
312 | if (decl == NULL_TREE) |
313 | return -1; |
314 | |
315 | switch (attr) |
316 | { |
317 | case DW_AT_explicit: |
318 | if (TREE_CODE (decl) == FUNCTION_DECL |
319 | && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl)) |
320 | && DECL_NONCONVERTING_P (decl)) |
321 | return 1; |
322 | break; |
323 | |
324 | case DW_AT_deleted: |
325 | if (TREE_CODE (decl) == FUNCTION_DECL |
326 | && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl)) |
327 | && DECL_DELETED_FN (decl)) |
328 | return 1; |
329 | break; |
330 | |
331 | case DW_AT_defaulted: |
332 | if (TREE_CODE (decl) == FUNCTION_DECL |
333 | && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl)) |
334 | && DECL_DEFAULTED_FN (decl)) |
335 | { |
336 | if (DECL_DEFAULTED_IN_CLASS_P (decl)) |
337 | return DW_DEFAULTED_in_class; |
338 | |
339 | if (DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)) |
340 | return DW_DEFAULTED_out_of_class; |
341 | } |
342 | break; |
343 | |
344 | case DW_AT_const_expr: |
345 | if (VAR_OR_FUNCTION_DECL_P (decl) && DECL_DECLARED_CONSTEXPR_P (decl)) |
346 | return 1; |
347 | break; |
348 | |
349 | case DW_AT_reference: |
350 | if (TREE_CODE (decl) == FUNCTION_DECL |
351 | && DECL_IOBJ_MEMBER_FUNCTION_P (decl) |
352 | && FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)) |
353 | && !FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) |
354 | return 1; |
355 | break; |
356 | |
357 | case DW_AT_rvalue_reference: |
358 | if (TREE_CODE (decl) == FUNCTION_DECL |
359 | && DECL_IOBJ_MEMBER_FUNCTION_P (decl) |
360 | && FUNCTION_REF_QUALIFIED (TREE_TYPE (decl)) |
361 | && FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (decl))) |
362 | return 1; |
363 | break; |
364 | |
365 | case DW_AT_inline: |
366 | if (VAR_P (decl) && DECL_INLINE_VAR_P (decl)) |
367 | { |
368 | if (DECL_VAR_DECLARED_INLINE_P (decl)) |
369 | return DW_INL_declared_inlined; |
370 | else |
371 | return DW_INL_inlined; |
372 | } |
373 | break; |
374 | |
375 | case DW_AT_export_symbols: |
376 | if (TREE_CODE (decl) == NAMESPACE_DECL |
377 | && (DECL_NAMESPACE_INLINE_P (decl) |
378 | || (DECL_NAME (decl) == NULL_TREE && dwarf_version >= 5))) |
379 | return 1; |
380 | break; |
381 | |
382 | default: |
383 | break; |
384 | } |
385 | |
386 | return -1; |
387 | } |
388 | |
389 | /* Return -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute |
390 | value otherwise. */ |
391 | int |
392 | cp_type_dwarf_attribute (const_tree type, int attr) |
393 | { |
394 | if (type == NULL_TREE) |
395 | return -1; |
396 | |
397 | switch (attr) |
398 | { |
399 | case DW_AT_reference: |
400 | if (FUNC_OR_METHOD_TYPE_P (type) |
401 | && FUNCTION_REF_QUALIFIED (type) |
402 | && !FUNCTION_RVALUE_QUALIFIED (type)) |
403 | return 1; |
404 | break; |
405 | |
406 | case DW_AT_rvalue_reference: |
407 | if (FUNC_OR_METHOD_TYPE_P (type) |
408 | && FUNCTION_REF_QUALIFIED (type) |
409 | && FUNCTION_RVALUE_QUALIFIED (type)) |
410 | return 1; |
411 | break; |
412 | |
413 | case DW_AT_export_symbols: |
414 | if (ANON_AGGR_TYPE_P (type)) |
415 | return 1; |
416 | break; |
417 | |
418 | default: |
419 | break; |
420 | } |
421 | |
422 | return -1; |
423 | } |
424 | |
425 | /* Return the unit size of TYPE without reusable tail padding. */ |
426 | |
427 | tree |
428 | cp_unit_size_without_reusable_padding (tree type) |
429 | { |
430 | if (CLASS_TYPE_P (type)) |
431 | return CLASSTYPE_SIZE_UNIT (type); |
432 | return TYPE_SIZE_UNIT (type); |
433 | } |
434 | |
435 | /* Returns type corresponding to FIELD's type when FIELD is a C++ base class |
436 | i.e., type without virtual base classes or tail padding. Returns |
437 | NULL_TREE otherwise. */ |
438 | |
439 | tree |
440 | cp_classtype_as_base (const_tree field) |
441 | { |
442 | if (DECL_FIELD_IS_BASE (field)) |
443 | { |
444 | tree type = TREE_TYPE (field); |
445 | if (TYPE_LANG_SPECIFIC (type)) |
446 | return CLASSTYPE_AS_BASE (type); |
447 | } |
448 | return NULL_TREE; |
449 | } |
450 | |
451 | /* Stubs to keep c-opts.cc happy. */ |
452 | void |
453 | push_file_scope (void) |
454 | { |
455 | } |
456 | |
457 | void |
458 | pop_file_scope (void) |
459 | { |
460 | } |
461 | |
462 | /* c-pragma.cc needs to query whether a decl has extern "C" linkage. */ |
463 | bool |
464 | has_c_linkage (const_tree decl) |
465 | { |
466 | return DECL_EXTERN_C_P (decl); |
467 | } |
468 | |
469 | /* Return true if stmt can fall through. Used by block_may_fallthru |
470 | default case. */ |
471 | |
472 | bool |
473 | cxx_block_may_fallthru (const_tree stmt) |
474 | { |
475 | switch (TREE_CODE (stmt)) |
476 | { |
477 | case EXPR_STMT: |
478 | return block_may_fallthru (EXPR_STMT_EXPR (stmt)); |
479 | |
480 | case THROW_EXPR: |
481 | return false; |
482 | |
483 | case IF_STMT: |
484 | if (IF_STMT_CONSTEXPR_P (stmt)) |
485 | { |
486 | if (integer_nonzerop (IF_COND (stmt))) |
487 | return block_may_fallthru (THEN_CLAUSE (stmt)); |
488 | if (integer_zerop (IF_COND (stmt))) |
489 | return block_may_fallthru (ELSE_CLAUSE (stmt)); |
490 | } |
491 | if (block_may_fallthru (THEN_CLAUSE (stmt))) |
492 | return true; |
493 | return block_may_fallthru (ELSE_CLAUSE (stmt)); |
494 | |
495 | case CLEANUP_STMT: |
496 | /* Just handle the try/finally cases. */ |
497 | if (!CLEANUP_EH_ONLY (stmt)) |
498 | { |
499 | return (block_may_fallthru (CLEANUP_BODY (stmt)) |
500 | && block_may_fallthru (CLEANUP_EXPR (stmt))); |
501 | } |
502 | return true; |
503 | |
504 | default: |
505 | return c_block_may_fallthru (stmt); |
506 | } |
507 | } |
508 | |
509 | /* Return the list of decls in the global namespace. */ |
510 | |
511 | tree |
512 | cp_get_global_decls () |
513 | { |
514 | return NAMESPACE_LEVEL (global_namespace)->names; |
515 | } |
516 | |
517 | /* Push DECL into the current (namespace) scope. */ |
518 | |
519 | tree |
520 | cp_pushdecl (tree decl) |
521 | { |
522 | DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); |
523 | return pushdecl (decl); |
524 | } |
525 | |
526 | /* Get the global value binding of NAME. Called directly from |
527 | c-common.cc, not via a hook. */ |
528 | |
529 | tree |
530 | identifier_global_value (tree name) |
531 | { |
532 | return get_global_binding (id: name); |
533 | } |
534 | |
535 | /* Similarly, but return struct/class/union NAME instead. */ |
536 | |
537 | tree |
538 | identifier_global_tag (tree name) |
539 | { |
540 | tree ret = lookup_qualified_name (global_namespace, name, LOOK_want::TYPE, |
541 | /*complain*/false); |
542 | if (ret == error_mark_node) |
543 | return NULL_TREE; |
544 | return ret; |
545 | } |
546 | |
547 | /* Returns true if NAME refers to a built-in function or function-like |
548 | operator. */ |
549 | |
550 | bool |
551 | names_builtin_p (const char *name) |
552 | { |
553 | tree id = get_identifier (name); |
554 | if (tree binding = get_global_binding (id)) |
555 | { |
556 | if (TREE_CODE (binding) == FUNCTION_DECL |
557 | && DECL_IS_UNDECLARED_BUILTIN (binding)) |
558 | return true; |
559 | |
560 | /* Handle the case when an overload for a built-in name exists. */ |
561 | if (TREE_CODE (binding) != OVERLOAD) |
562 | return false; |
563 | |
564 | for (ovl_iterator it (binding); it; ++it) |
565 | { |
566 | tree decl = *it; |
567 | if (DECL_IS_UNDECLARED_BUILTIN (decl)) |
568 | return true; |
569 | } |
570 | } |
571 | |
572 | /* Check for built-in traits. */ |
573 | if (IDENTIFIER_TRAIT_P (id)) |
574 | return true; |
575 | |
576 | /* Also detect common reserved C++ words that aren't strictly built-in |
577 | functions. */ |
578 | switch (C_RID_CODE (id)) |
579 | { |
580 | case RID_ADDRESSOF: |
581 | case RID_BUILTIN_CONVERTVECTOR: |
582 | case RID_BUILTIN_HAS_ATTRIBUTE: |
583 | case RID_BUILTIN_SHUFFLE: |
584 | case RID_BUILTIN_SHUFFLEVECTOR: |
585 | case RID_BUILTIN_LAUNDER: |
586 | case RID_BUILTIN_ASSOC_BARRIER: |
587 | case RID_BUILTIN_BIT_CAST: |
588 | case RID_OFFSETOF: |
589 | return true; |
590 | default: |
591 | break; |
592 | } |
593 | |
594 | return false; |
595 | } |
596 | |
597 | /* Register c++-specific dumps. */ |
598 | |
599 | void |
600 | cp_register_dumps (gcc::dump_manager *dumps) |
601 | { |
602 | class_dump_id = dumps->dump_register |
603 | (suffix: ".class" , swtch: "lang-class" , glob: "lang-class" , dkind: DK_lang, optgroup_flags: OPTGROUP_NONE, take_ownership: false); |
604 | |
605 | module_dump_id = dumps->dump_register |
606 | (suffix: ".module" , swtch: "lang-module" , glob: "lang-module" , dkind: DK_lang, optgroup_flags: OPTGROUP_NONE, take_ownership: false); |
607 | |
608 | raw_dump_id = dumps->dump_register |
609 | (suffix: ".raw" , swtch: "lang-raw" , glob: "lang-raw" , dkind: DK_lang, optgroup_flags: OPTGROUP_NONE, take_ownership: false); |
610 | } |
611 | |
612 | void |
613 | cp_common_init_ts (void) |
614 | { |
615 | /* With type. */ |
616 | MARK_TS_TYPED (PTRMEM_CST); |
617 | MARK_TS_TYPED (LAMBDA_EXPR); |
618 | MARK_TS_TYPED (TYPE_ARGUMENT_PACK); |
619 | |
620 | /* Random new trees. */ |
621 | MARK_TS_COMMON (BASELINK); |
622 | MARK_TS_COMMON (OVERLOAD); |
623 | MARK_TS_COMMON (TEMPLATE_PARM_INDEX); |
624 | |
625 | /* New decls. */ |
626 | MARK_TS_DECL_COMMON (TEMPLATE_DECL); |
627 | MARK_TS_DECL_COMMON (WILDCARD_DECL); |
628 | |
629 | MARK_TS_DECL_NON_COMMON (USING_DECL); |
630 | |
631 | /* New Types. */ |
632 | MARK_TS_TYPE_COMMON (UNBOUND_CLASS_TEMPLATE); |
633 | MARK_TS_TYPE_COMMON (TYPE_ARGUMENT_PACK); |
634 | MARK_TS_TYPE_COMMON (DEPENDENT_OPERATOR_TYPE); |
635 | |
636 | MARK_TS_TYPE_NON_COMMON (DECLTYPE_TYPE); |
637 | MARK_TS_TYPE_NON_COMMON (TYPENAME_TYPE); |
638 | MARK_TS_TYPE_NON_COMMON (TYPEOF_TYPE); |
639 | MARK_TS_TYPE_NON_COMMON (TRAIT_TYPE); |
640 | MARK_TS_TYPE_NON_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM); |
641 | MARK_TS_TYPE_NON_COMMON (TEMPLATE_TEMPLATE_PARM); |
642 | MARK_TS_TYPE_NON_COMMON (TEMPLATE_TYPE_PARM); |
643 | MARK_TS_TYPE_NON_COMMON (TYPE_PACK_EXPANSION); |
644 | |
645 | /* Statements. */ |
646 | MARK_TS_EXP (CLEANUP_STMT); |
647 | MARK_TS_EXP (EH_SPEC_BLOCK); |
648 | MARK_TS_EXP (HANDLER); |
649 | MARK_TS_EXP (IF_STMT); |
650 | MARK_TS_EXP (OMP_DEPOBJ); |
651 | MARK_TS_EXP (RANGE_FOR_STMT); |
652 | MARK_TS_EXP (TRY_BLOCK); |
653 | MARK_TS_EXP (USING_STMT); |
654 | |
655 | /* Random expressions. */ |
656 | MARK_TS_EXP (ADDRESSOF_EXPR); |
657 | MARK_TS_EXP (AGGR_INIT_EXPR); |
658 | MARK_TS_EXP (ALIGNOF_EXPR); |
659 | MARK_TS_EXP (ARROW_EXPR); |
660 | MARK_TS_EXP (AT_ENCODE_EXPR); |
661 | MARK_TS_EXP (BIT_CAST_EXPR); |
662 | MARK_TS_EXP (CAST_EXPR); |
663 | MARK_TS_EXP (CONST_CAST_EXPR); |
664 | MARK_TS_EXP (CTOR_INITIALIZER); |
665 | MARK_TS_EXP (DELETE_EXPR); |
666 | MARK_TS_EXP (DOTSTAR_EXPR); |
667 | MARK_TS_EXP (DYNAMIC_CAST_EXPR); |
668 | MARK_TS_EXP (EMPTY_CLASS_EXPR); |
669 | MARK_TS_EXP (EXPR_STMT); |
670 | MARK_TS_EXP (IMPLICIT_CONV_EXPR); |
671 | MARK_TS_EXP (MEMBER_REF); |
672 | MARK_TS_EXP (MODOP_EXPR); |
673 | MARK_TS_EXP (MUST_NOT_THROW_EXPR); |
674 | MARK_TS_EXP (NEW_EXPR); |
675 | MARK_TS_EXP (NOEXCEPT_EXPR); |
676 | MARK_TS_EXP (OFFSETOF_EXPR); |
677 | MARK_TS_EXP (OFFSET_REF); |
678 | MARK_TS_EXP (PSEUDO_DTOR_EXPR); |
679 | MARK_TS_EXP (REINTERPRET_CAST_EXPR); |
680 | MARK_TS_EXP (SCOPE_REF); |
681 | MARK_TS_EXP (STATIC_CAST_EXPR); |
682 | MARK_TS_EXP (STMT_EXPR); |
683 | MARK_TS_EXP (TAG_DEFN); |
684 | MARK_TS_EXP (TEMPLATE_ID_EXPR); |
685 | MARK_TS_EXP (THROW_EXPR); |
686 | MARK_TS_EXP (TRAIT_EXPR); |
687 | MARK_TS_EXP (TYPEID_EXPR); |
688 | MARK_TS_EXP (TYPE_EXPR); |
689 | MARK_TS_EXP (UNARY_PLUS_EXPR); |
690 | MARK_TS_EXP (VEC_DELETE_EXPR); |
691 | MARK_TS_EXP (VEC_INIT_EXPR); |
692 | MARK_TS_EXP (VEC_NEW_EXPR); |
693 | MARK_TS_EXP (SPACESHIP_EXPR); |
694 | |
695 | /* Fold expressions. */ |
696 | MARK_TS_EXP (BINARY_LEFT_FOLD_EXPR); |
697 | MARK_TS_EXP (BINARY_RIGHT_FOLD_EXPR); |
698 | MARK_TS_EXP (EXPR_PACK_EXPANSION); |
699 | MARK_TS_EXP (NONTYPE_ARGUMENT_PACK); |
700 | MARK_TS_EXP (UNARY_LEFT_FOLD_EXPR); |
701 | MARK_TS_EXP (UNARY_RIGHT_FOLD_EXPR); |
702 | |
703 | /* Constraints. */ |
704 | MARK_TS_EXP (CHECK_CONSTR); |
705 | MARK_TS_EXP (COMPOUND_REQ); |
706 | MARK_TS_EXP (CONJ_CONSTR); |
707 | MARK_TS_EXP (DISJ_CONSTR); |
708 | MARK_TS_EXP (ATOMIC_CONSTR); |
709 | MARK_TS_EXP (NESTED_REQ); |
710 | MARK_TS_EXP (REQUIRES_EXPR); |
711 | MARK_TS_EXP (SIMPLE_REQ); |
712 | MARK_TS_EXP (TYPE_REQ); |
713 | |
714 | MARK_TS_EXP (CO_AWAIT_EXPR); |
715 | MARK_TS_EXP (CO_YIELD_EXPR); |
716 | MARK_TS_EXP (CO_RETURN_EXPR); |
717 | |
718 | MARK_TS_EXP (ASSERTION_STMT); |
719 | MARK_TS_EXP (PRECONDITION_STMT); |
720 | MARK_TS_EXP (POSTCONDITION_STMT); |
721 | |
722 | c_common_init_ts (); |
723 | } |
724 | |
725 | /* Handle C++-specficic options here. Punt to c_common otherwise. */ |
726 | |
727 | bool |
728 | cp_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, |
729 | int kind, location_t loc, |
730 | const struct cl_option_handlers *handlers) |
731 | { |
732 | if (handle_module_option (opt: unsigned (scode), arg, value)) |
733 | return true; |
734 | |
735 | enum opt_code code = (enum opt_code) scode; |
736 | bool handled_p = true; |
737 | |
738 | switch (code) |
739 | { |
740 | case OPT_fcontract_build_level_: |
741 | handle_OPT_fcontract_build_level_ (arg); |
742 | break; |
743 | |
744 | case OPT_fcontract_assumption_mode_: |
745 | handle_OPT_fcontract_assumption_mode_ (arg); |
746 | break; |
747 | |
748 | case OPT_fcontract_continuation_mode_: |
749 | handle_OPT_fcontract_continuation_mode_ (arg); |
750 | break; |
751 | |
752 | case OPT_fcontract_role_: |
753 | handle_OPT_fcontract_role_ (arg); |
754 | break; |
755 | |
756 | case OPT_fcontract_semantic_: |
757 | handle_OPT_fcontract_semantic_ (arg); |
758 | break; |
759 | |
760 | default: |
761 | handled_p = false; |
762 | break; |
763 | } |
764 | if (handled_p) |
765 | return handled_p; |
766 | |
767 | return c_common_handle_option (scode, arg, value, kind, loc, handlers); |
768 | } |
769 | |
770 | #include "gt-cp-cp-objcp-common.h" |
771 | |