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