]>
Commit | Line | Data |
---|---|---|
1 | /* Language-dependent hooks for C++. | |
2 | Copyright (C) 2001-2020 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 | ||
38 | /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h; | |
39 | consequently, there should be very few hooks below. */ | |
40 | ||
41 | #undef LANG_HOOKS_NAME | |
42 | #define LANG_HOOKS_NAME "GNU C++" | |
43 | #undef LANG_HOOKS_INIT | |
44 | #define LANG_HOOKS_INIT cxx_init | |
45 | #undef LANG_HOOKS_CLASSIFY_RECORD | |
46 | #define LANG_HOOKS_CLASSIFY_RECORD cp_classify_record | |
47 | #undef LANG_HOOKS_GENERIC_TYPE_P | |
48 | #define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p | |
49 | ||
50 | #undef LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS | |
51 | #define LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS \ | |
52 | get_primary_template_innermost_parameters | |
53 | #undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS | |
54 | #define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \ | |
55 | get_template_innermost_arguments_folded | |
56 | #undef LANG_HOOKS_FUNCTION_PARAMETER_PACK_P | |
57 | #define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P \ | |
58 | function_parameter_pack_p | |
59 | #undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS | |
60 | #define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \ | |
61 | get_template_argument_pack_elems_folded | |
62 | #undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P | |
63 | #define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \ | |
64 | template_template_parameter_p | |
65 | #undef LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P | |
66 | #define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \ | |
67 | function_parameter_expanded_from_pack_p | |
68 | #undef LANG_HOOKS_GET_GENERIC_FUNCTION_DECL | |
69 | #define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL get_function_template_decl | |
70 | #undef LANG_HOOKS_DWARF_NAME | |
71 | #define LANG_HOOKS_DWARF_NAME cxx_dwarf_name | |
72 | #undef LANG_HOOKS_INIT_TS | |
73 | #define LANG_HOOKS_INIT_TS cp_common_init_ts | |
74 | #undef LANG_HOOKS_EH_PERSONALITY | |
75 | #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality | |
76 | #undef LANG_HOOKS_EH_RUNTIME_TYPE | |
77 | #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type | |
78 | #undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE | |
79 | #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE cxx_enum_underlying_base_type | |
80 | ||
81 | #if CHECKING_P | |
82 | #undef LANG_HOOKS_RUN_LANG_SELFTESTS | |
83 | #define LANG_HOOKS_RUN_LANG_SELFTESTS selftest::run_cp_tests | |
84 | #endif /* #if CHECKING_P */ | |
85 | ||
86 | #undef LANG_HOOKS_GET_SUBSTRING_LOCATION | |
87 | #define LANG_HOOKS_GET_SUBSTRING_LOCATION c_get_substring_location | |
88 | ||
89 | /* Each front end provides its own lang hook initializer. */ | |
90 | struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; | |
91 | ||
92 | /* Lang hook routines common to C++ and ObjC++ appear in cp/cp-objcp-common.c; | |
93 | there should be very few routines below. */ | |
94 | ||
95 | /* The following function does something real, but only in Objective-C++. */ | |
96 | ||
97 | tree | |
98 | objcp_tsubst_copy_and_build (tree /*t*/, | |
99 | tree /*args*/, | |
100 | tsubst_flags_t /*complain*/, | |
101 | tree /*in_decl*/, | |
102 | bool /*function_p*/) | |
103 | { | |
104 | return NULL_TREE; | |
105 | } | |
106 | ||
107 | static const char * | |
108 | cxx_dwarf_name (tree t, int verbosity) | |
109 | { | |
110 | gcc_assert (DECL_P (t)); | |
111 | ||
112 | if (DECL_NAME (t) && IDENTIFIER_ANON_P (DECL_NAME (t))) | |
113 | return NULL; | |
114 | if (verbosity >= 2) | |
115 | return decl_as_dwarf_string (t, | |
116 | TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME | |
117 | | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); | |
118 | ||
119 | return lang_decl_dwarf_name (t, verbosity, false); | |
120 | } | |
121 | ||
122 | static enum classify_record | |
123 | cp_classify_record (tree type) | |
124 | { | |
125 | if (TYPE_LANG_SPECIFIC (type) | |
126 | && CLASSTYPE_DECLARED_CLASS (type)) | |
127 | return RECORD_IS_CLASS; | |
128 | ||
129 | return RECORD_IS_STRUCT; | |
130 | } | |
131 | ||
132 | static GTY(()) tree cp_eh_personality_decl; | |
133 | ||
134 | static tree | |
135 | cp_eh_personality (void) | |
136 | { | |
137 | if (!cp_eh_personality_decl) | |
138 | cp_eh_personality_decl = build_personality_function ("gxx"); | |
139 | ||
140 | return cp_eh_personality_decl; | |
141 | } | |
142 | ||
143 | /* This is a subroutine of fold_cplus_constants. It returns TRUE if T | |
144 | is a C++ specific constant that needs to be folded further before | |
145 | being passed to the debug info emitter. */ | |
146 | ||
147 | static bool | |
148 | template_arg_needs_folding (const_tree t) | |
149 | { | |
150 | /* For now only PTRMEM_CST nodes are to be folded further. */ | |
151 | if (TREE_CODE (t) == PTRMEM_CST) | |
152 | return true; | |
153 | return false; | |
154 | } | |
155 | ||
156 | /* Fold the elements of the TREE_VEC C which are C++ specific nodes | |
157 | that would need folding so that they can be processed by the debug | |
158 | info emitter. This is a subroutine of | |
159 | get_template_innermost_arguments_folded and | |
160 | get_template_argument_pack_elems_folded. */ | |
161 | ||
162 | static tree | |
163 | fold_cplus_constants (const_tree c) | |
164 | { | |
165 | tree folded_elems, elems = CONST_CAST_TREE (c); | |
166 | int vec_len, i; | |
167 | ||
168 | if (elems == NULL_TREE || elems == error_mark_node) | |
169 | return elems; | |
170 | ||
171 | vec_len = TREE_VEC_LENGTH (elems); | |
172 | ||
173 | /* First check if there is at least one element that needs | |
174 | folding. If there is none, we just return ELEMS. Otherwise create | |
175 | and return a new tree vector that contains the folded versions of | |
176 | ELEMS. This is to avoid allocating memory if we don't need | |
177 | to. */ | |
178 | for (i = 0; i < vec_len; ++i) | |
179 | { | |
180 | if (template_arg_needs_folding (TREE_VEC_ELT (elems, i))) | |
181 | break; | |
182 | } | |
183 | if (i == vec_len) | |
184 | return elems; | |
185 | ||
186 | folded_elems = make_tree_vec (vec_len); | |
187 | for (i = 0; i < vec_len; ++i) | |
188 | { | |
189 | tree elem = TREE_VEC_ELT (elems, i); | |
190 | TREE_VEC_ELT (folded_elems, i) = | |
191 | (elem && !TYPE_P (elem)) ? cplus_expand_constant (elem) : elem; | |
192 | ||
193 | } | |
194 | return folded_elems; | |
195 | } | |
196 | ||
197 | /* The C++ implementation of the LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS | |
198 | hook. It returns the innermost template arguments of type T, and | |
199 | makes sure those arguments are folded enough for the debug info | |
200 | emitter. */ | |
201 | ||
202 | static tree | |
203 | get_template_innermost_arguments_folded (const_tree t) | |
204 | { | |
205 | return fold_cplus_constants (get_template_innermost_arguments (t)); | |
206 | } | |
207 | ||
208 | static tree | |
209 | get_template_argument_pack_elems_folded (const_tree t) | |
210 | { | |
211 | return fold_cplus_constants (get_template_argument_pack_elems (t)); | |
212 | } | |
213 | ||
214 | /* The C++ version of the enum_underlying_base_type langhook. | |
215 | See also cp/semantics.c (finish_underlying_type). */ | |
216 | ||
217 | static | |
218 | tree cxx_enum_underlying_base_type (const_tree type) | |
219 | { | |
220 | tree underlying_type = ENUM_UNDERLYING_TYPE (type); | |
221 | ||
222 | if (! ENUM_FIXED_UNDERLYING_TYPE_P (type)) | |
223 | underlying_type | |
224 | = c_common_type_for_mode (TYPE_MODE (underlying_type), | |
225 | TYPE_UNSIGNED (underlying_type)); | |
226 | ||
227 | return underlying_type; | |
228 | } | |
229 | ||
230 | #if CHECKING_P | |
231 | ||
232 | namespace selftest { | |
233 | ||
234 | /* Implementation of LANG_HOOKS_RUN_LANG_SELFTESTS for the C++ frontend. */ | |
235 | ||
236 | void | |
237 | run_cp_tests (void) | |
238 | { | |
239 | /* Run selftests shared within the C family. */ | |
240 | c_family_tests (); | |
241 | ||
242 | /* Additional C++-specific tests. */ | |
243 | cp_pt_c_tests (); | |
244 | cp_tree_c_tests (); | |
245 | } | |
246 | ||
247 | } // namespace selftest | |
248 | ||
249 | #endif /* #if CHECKING_P */ | |
250 | ||
251 | ||
252 | #include "gt-cp-cp-lang.h" | |
253 | #include "gtype-cp.h" |