1 | /* Language-dependent hooks for C++. |
2 | Copyright (C) 2001-2024 Free Software Foundation, Inc. |
3 | Contributed by Alexandre Oliva <aoliva@redhat.com> |
4 | |
5 | This file is part of GCC. |
6 | |
7 | GCC is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 3, or (at your option) |
10 | any later version. |
11 | |
12 | GCC is distributed in the hope that it will be useful, |
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 |
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 "stor-layout.h" |
26 | #include "langhooks.h" |
27 | #include "langhooks-def.h" |
28 | #include "cp-objcp-common.h" |
29 | |
30 | enum c_language_kind c_language = clk_cxx; |
31 | static const char * cxx_dwarf_name (tree t, int verbosity); |
32 | static enum classify_record cp_classify_record (tree type); |
33 | static tree cp_eh_personality (void); |
34 | static tree get_template_innermost_arguments_folded (const_tree); |
35 | static tree get_template_argument_pack_elems_folded (const_tree); |
36 | static tree cxx_enum_underlying_base_type (const_tree); |
37 | static tree *cxx_omp_get_decl_init (tree); |
38 | static void cxx_omp_finish_decl_inits (void); |
39 | static const char *cp_get_sarif_source_language (const char *); |
40 | |
41 | /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h; |
42 | consequently, there should be very few hooks below. */ |
43 | |
44 | #undef LANG_HOOKS_NAME |
45 | #define LANG_HOOKS_NAME "GNU C++" |
46 | #undef LANG_HOOKS_INIT |
47 | #define LANG_HOOKS_INIT cxx_init |
48 | #undef LANG_HOOKS_CLASSIFY_RECORD |
49 | #define LANG_HOOKS_CLASSIFY_RECORD cp_classify_record |
50 | #undef LANG_HOOKS_GENERIC_TYPE_P |
51 | #define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p |
52 | |
53 | #undef LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS |
54 | #define LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS \ |
55 | get_primary_template_innermost_parameters |
56 | #undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS |
57 | #define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \ |
58 | get_template_innermost_arguments_folded |
59 | #undef LANG_HOOKS_FUNCTION_PARAMETER_PACK_P |
60 | #define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P \ |
61 | function_parameter_pack_p |
62 | #undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS |
63 | #define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \ |
64 | get_template_argument_pack_elems_folded |
65 | #undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P |
66 | #define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \ |
67 | template_template_parameter_p |
68 | #undef LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P |
69 | #define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \ |
70 | function_parameter_expanded_from_pack_p |
71 | #undef LANG_HOOKS_GET_GENERIC_FUNCTION_DECL |
72 | #define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL get_function_template_decl |
73 | #undef LANG_HOOKS_DWARF_NAME |
74 | #define LANG_HOOKS_DWARF_NAME cxx_dwarf_name |
75 | #undef LANG_HOOKS_INIT_TS |
76 | #define LANG_HOOKS_INIT_TS cp_common_init_ts |
77 | #undef LANG_HOOKS_EH_PERSONALITY |
78 | #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality |
79 | #undef LANG_HOOKS_EH_RUNTIME_TYPE |
80 | #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type |
81 | #undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE |
82 | #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE cxx_enum_underlying_base_type |
83 | #undef LANG_HOOKS_PREPROCESS_MAIN_FILE |
84 | #define LANG_HOOKS_PREPROCESS_MAIN_FILE module_begin_main_file |
85 | #undef LANG_HOOKS_PREPROCESS_OPTIONS |
86 | #define LANG_HOOKS_PREPROCESS_OPTIONS module_preprocess_options |
87 | #undef LANG_HOOKS_PREPROCESS_TOKEN |
88 | #define LANG_HOOKS_PREPROCESS_TOKEN module_token_pre |
89 | |
90 | #if CHECKING_P |
91 | #undef LANG_HOOKS_RUN_LANG_SELFTESTS |
92 | #define LANG_HOOKS_RUN_LANG_SELFTESTS selftest::run_cp_tests |
93 | #endif /* #if CHECKING_P */ |
94 | |
95 | #undef LANG_HOOKS_GET_SUBSTRING_LOCATION |
96 | #define LANG_HOOKS_GET_SUBSTRING_LOCATION c_get_substring_location |
97 | |
98 | #undef LANG_HOOKS_OMP_GET_DECL_INIT |
99 | #define LANG_HOOKS_OMP_GET_DECL_INIT cxx_omp_get_decl_init |
100 | |
101 | #undef LANG_HOOKS_OMP_FINISH_DECL_INITS |
102 | #define LANG_HOOKS_OMP_FINISH_DECL_INITS cxx_omp_finish_decl_inits |
103 | |
104 | #undef LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE |
105 | #define LANG_HOOKS_GET_SARIF_SOURCE_LANGUAGE cp_get_sarif_source_language |
106 | |
107 | /* Each front end provides its own lang hook initializer. */ |
108 | struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; |
109 | |
110 | /* Lang hook routines common to C++ and ObjC++ appear in cp/cp-objcp-common.cc; |
111 | there should be very few routines below. */ |
112 | |
113 | /* The following function does something real, but only in Objective-C++. */ |
114 | |
115 | tree |
116 | objcp_tsubst_expr (tree /*t*/, tree /*args*/, tsubst_flags_t /*complain*/, |
117 | tree /*in_decl*/) |
118 | { |
119 | return NULL_TREE; |
120 | } |
121 | |
122 | /* Implement c-family hook to add language-specific features |
123 | for __has_{feature,extension}. */ |
124 | |
125 | void |
126 | c_family_register_lang_features () |
127 | { |
128 | cp_register_features (); |
129 | } |
130 | |
131 | static const char * |
132 | cxx_dwarf_name (tree t, int verbosity) |
133 | { |
134 | gcc_assert (DECL_P (t)); |
135 | |
136 | if (DECL_NAME (t) && IDENTIFIER_ANON_P (DECL_NAME (t))) |
137 | return NULL; |
138 | if (verbosity >= 2) |
139 | return decl_as_dwarf_string (t, |
140 | TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME |
141 | | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); |
142 | |
143 | return lang_decl_dwarf_name (t, verbosity, false); |
144 | } |
145 | |
146 | static enum classify_record |
147 | cp_classify_record (tree type) |
148 | { |
149 | if (TYPE_LANG_SPECIFIC (type) |
150 | && CLASSTYPE_DECLARED_CLASS (type)) |
151 | return RECORD_IS_CLASS; |
152 | |
153 | return RECORD_IS_STRUCT; |
154 | } |
155 | |
156 | static GTY(()) tree cp_eh_personality_decl; |
157 | |
158 | static tree |
159 | cp_eh_personality (void) |
160 | { |
161 | if (!cp_eh_personality_decl) |
162 | cp_eh_personality_decl = build_personality_function ("gxx" ); |
163 | |
164 | return cp_eh_personality_decl; |
165 | } |
166 | |
167 | /* This is a subroutine of fold_cplus_constants. It returns TRUE if T |
168 | is a C++ specific constant that needs to be folded further before |
169 | being passed to the debug info emitter. */ |
170 | |
171 | static bool |
172 | template_arg_needs_folding (const_tree t) |
173 | { |
174 | /* For now only PTRMEM_CST nodes are to be folded further. */ |
175 | if (TREE_CODE (t) == PTRMEM_CST) |
176 | return true; |
177 | return false; |
178 | } |
179 | |
180 | /* Fold the elements of the TREE_VEC C which are C++ specific nodes |
181 | that would need folding so that they can be processed by the debug |
182 | info emitter. This is a subroutine of |
183 | get_template_innermost_arguments_folded and |
184 | get_template_argument_pack_elems_folded. */ |
185 | |
186 | static tree |
187 | fold_cplus_constants (const_tree c) |
188 | { |
189 | tree folded_elems, elems = CONST_CAST_TREE (c); |
190 | int vec_len, i; |
191 | |
192 | if (elems == NULL_TREE || elems == error_mark_node) |
193 | return elems; |
194 | |
195 | vec_len = TREE_VEC_LENGTH (elems); |
196 | |
197 | /* First check if there is at least one element that needs |
198 | folding. If there is none, we just return ELEMS. Otherwise create |
199 | and return a new tree vector that contains the folded versions of |
200 | ELEMS. This is to avoid allocating memory if we don't need |
201 | to. */ |
202 | for (i = 0; i < vec_len; ++i) |
203 | { |
204 | if (template_arg_needs_folding (TREE_VEC_ELT (elems, i))) |
205 | break; |
206 | } |
207 | if (i == vec_len) |
208 | return elems; |
209 | |
210 | folded_elems = make_tree_vec (vec_len); |
211 | for (i = 0; i < vec_len; ++i) |
212 | { |
213 | tree elem = TREE_VEC_ELT (elems, i); |
214 | TREE_VEC_ELT (folded_elems, i) = |
215 | (elem && !TYPE_P (elem)) ? cplus_expand_constant (elem) : elem; |
216 | |
217 | } |
218 | return folded_elems; |
219 | } |
220 | |
221 | /* The C++ implementation of the LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS |
222 | hook. It returns the innermost template arguments of type T, and |
223 | makes sure those arguments are folded enough for the debug info |
224 | emitter. */ |
225 | |
226 | static tree |
227 | get_template_innermost_arguments_folded (const_tree t) |
228 | { |
229 | return fold_cplus_constants (c: get_template_innermost_arguments (t)); |
230 | } |
231 | |
232 | static tree |
233 | get_template_argument_pack_elems_folded (const_tree t) |
234 | { |
235 | return fold_cplus_constants (c: get_template_argument_pack_elems (t)); |
236 | } |
237 | |
238 | /* The C++ version of the enum_underlying_base_type langhook. |
239 | See also cp/semantics.cc (finish_underlying_type). */ |
240 | |
241 | static |
242 | tree cxx_enum_underlying_base_type (const_tree type) |
243 | { |
244 | tree underlying_type = ENUM_UNDERLYING_TYPE (type); |
245 | |
246 | if (! ENUM_FIXED_UNDERLYING_TYPE_P (type)) |
247 | underlying_type |
248 | = c_common_type_for_mode (TYPE_MODE (underlying_type), |
249 | TYPE_UNSIGNED (underlying_type)); |
250 | |
251 | return underlying_type; |
252 | } |
253 | |
254 | /* The C++ version of the omp_get_decl_init langhook returns the static |
255 | initializer for a variable declaration if present, otherwise it |
256 | tries to find and return the dynamic initializer. If not present, |
257 | it returns NULL. */ |
258 | |
259 | static tree * |
260 | cxx_omp_get_decl_init (tree decl) |
261 | { |
262 | if (DECL_INITIAL (decl)) |
263 | return &DECL_INITIAL (decl); |
264 | |
265 | return hash_map_safe_get (h: dynamic_initializers, k: decl); |
266 | } |
267 | |
268 | /* The C++ version of the omp_finish_decl_inits langhook allows GC to |
269 | reclaim the memory used by the hash-map used to hold dynamic initializer |
270 | information. */ |
271 | |
272 | static void |
273 | cxx_omp_finish_decl_inits (void) |
274 | { |
275 | dynamic_initializers = NULL; |
276 | } |
277 | |
278 | /* Get a value for the SARIF v2.1.0 "artifact.sourceLanguage" property, |
279 | based on the list in SARIF v2.1.0 Appendix J. */ |
280 | |
281 | static const char * |
282 | cp_get_sarif_source_language (const char *) |
283 | { |
284 | return "cplusplus" ; |
285 | } |
286 | |
287 | #if CHECKING_P |
288 | |
289 | namespace selftest { |
290 | |
291 | /* Implementation of LANG_HOOKS_RUN_LANG_SELFTESTS for the C++ frontend. */ |
292 | |
293 | void |
294 | run_cp_tests (void) |
295 | { |
296 | /* Run selftests shared within the C family. */ |
297 | c_family_tests (); |
298 | |
299 | /* Additional C++-specific tests. */ |
300 | cp_pt_cc_tests (); |
301 | cp_tree_cc_tests (); |
302 | } |
303 | |
304 | } // namespace selftest |
305 | |
306 | #endif /* #if CHECKING_P */ |
307 | |
308 | |
309 | #include "gt-cp-cp-lang.h" |
310 | #include "gtype-cp.h" |
311 | |