]>
Commit | Line | Data |
---|---|---|
8d08fdba | 1 | /* Separate lexical analyzer for GNU C++. |
99dee823 | 2 | Copyright (C) 1987-2021 Free Software Foundation, Inc. |
8d08fdba MS |
3 | Hacked by Michael Tiemann (tiemann@cygnus.com) |
4 | ||
f5adbb8d | 5 | This file is part of GCC. |
8d08fdba | 6 | |
f5adbb8d | 7 | GCC is free software; you can redistribute it and/or modify |
8d08fdba | 8 | it under the terms of the GNU General Public License as published by |
e77f031d | 9 | the Free Software Foundation; either version 3, or (at your option) |
8d08fdba MS |
10 | any later version. |
11 | ||
f5adbb8d | 12 | GCC is distributed in the hope that it will be useful, |
8d08fdba MS |
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 | |
e77f031d NC |
18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
8d08fdba MS |
20 | |
21 | ||
22 | /* This file is the lexical analyzer for GNU C++. */ | |
23 | ||
da20811c | 24 | #include "config.h" |
7e2de6df DM |
25 | /* For use with name_hint. */ |
26 | #define INCLUDE_UNIQUE_PTR | |
8d052bc7 | 27 | #include "system.h" |
4977bab6 | 28 | #include "coretypes.h" |
8d08fdba | 29 | #include "cp-tree.h" |
2adfab87 | 30 | #include "stringpool.h" |
39dabefd | 31 | #include "c-family/c-pragma.h" |
dd2e44f0 | 32 | #include "c-family/c-objc.h" |
7e2de6df DM |
33 | #include "gcc-rich-location.h" |
34 | #include "cp-name-hint.h" | |
76a1719f | 35 | #include "langhooks.h" |
8d08fdba | 36 | |
9e7d1164 NN |
37 | static int interface_strcmp (const char *); |
38 | static void init_cp_pragma (void); | |
0e5921e8 | 39 | |
9e7d1164 NN |
40 | static tree parse_strconst_pragma (const char *, int); |
41 | static void handle_pragma_vtable (cpp_reader *); | |
42 | static void handle_pragma_unit (cpp_reader *); | |
43 | static void handle_pragma_interface (cpp_reader *); | |
44 | static void handle_pragma_implementation (cpp_reader *); | |
0e5921e8 | 45 | |
9e7d1164 NN |
46 | static void init_operators (void); |
47 | static void copy_lang_type (tree); | |
8d08fdba | 48 | |
0e5921e8 | 49 | /* A constraint that can be tested at compile time. */ |
0e5921e8 | 50 | #define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1] |
66a6250f | 51 | |
87e3dbc9 MM |
52 | /* Functions and data structures for #pragma interface. |
53 | ||
54 | `#pragma implementation' means that the main file being compiled | |
55 | is considered to implement (provide) the classes that appear in | |
56 | its main body. I.e., if this is file "foo.cc", and class `bar' | |
57 | is defined in "foo.cc", then we say that "foo.cc implements bar". | |
58 | ||
59 | All main input files "implement" themselves automagically. | |
60 | ||
61 | `#pragma interface' means that unless this file (of the form "foo.h" | |
62 | is not presently being included by file "foo.cc", the | |
63 | CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none | |
64 | of the vtables nor any of the inline functions defined in foo.h | |
65 | will ever be output. | |
66 | ||
67 | There are cases when we want to link files such as "defs.h" and | |
68 | "main.cc". In this case, we give "defs.h" a `#pragma interface', | |
69 | and "main.cc" has `#pragma implementation "defs.h"'. */ | |
70 | ||
71 | struct impl_files | |
72 | { | |
520a57c8 | 73 | const char *filename; |
87e3dbc9 MM |
74 | struct impl_files *next; |
75 | }; | |
76 | ||
77 | static struct impl_files *impl_file_chain; | |
8d08fdba | 78 | \f |
19551f29 | 79 | void |
9e7d1164 | 80 | cxx_finish (void) |
8d08fdba | 81 | { |
22703ccc | 82 | c_common_finish (); |
8d08fdba MS |
83 | } |
84 | ||
d6dd9d7f NS |
85 | ovl_op_info_t ovl_op_info[2][OVL_OP_MAX] = |
86 | { | |
87 | { | |
88 | {NULL_TREE, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0}, | |
89 | {NULL_TREE, NULL, NULL, NOP_EXPR, OVL_OP_NOP_EXPR, 0}, | |
90 | #define DEF_OPERATOR(NAME, CODE, MANGLING, FLAGS) \ | |
91 | {NULL_TREE, NAME, MANGLING, CODE, OVL_OP_##CODE, FLAGS}, | |
92 | #define OPERATOR_TRANSITION }, { \ | |
93 | {NULL_TREE, NULL, NULL, ERROR_MARK, OVL_OP_ERROR_MARK, 0}, | |
94 | #include "operators.def" | |
95 | } | |
96 | }; | |
97 | unsigned char ovl_op_mapping[MAX_TREE_CODES]; | |
98 | unsigned char ovl_op_alternate[OVL_OP_MAX]; | |
5362b086 | 99 | |
84c0088f NS |
100 | /* Get the name of the kind of identifier T. */ |
101 | ||
102 | const char * | |
103 | get_identifier_kind_name (tree id) | |
104 | { | |
105 | /* Keep in sync with cp_id_kind enumeration. */ | |
106 | static const char *const names[cik_max] = { | |
107 | "normal", "keyword", "constructor", "destructor", | |
183e687a NS |
108 | "simple-op", "assign-op", "conv-op", "<reserved>udlit-op" |
109 | }; | |
84c0088f NS |
110 | |
111 | unsigned kind = 0; | |
112 | kind |= IDENTIFIER_KIND_BIT_2 (id) << 2; | |
113 | kind |= IDENTIFIER_KIND_BIT_1 (id) << 1; | |
114 | kind |= IDENTIFIER_KIND_BIT_0 (id) << 0; | |
115 | ||
116 | return names[kind]; | |
117 | } | |
118 | ||
119 | /* Set the identifier kind, which we expect to currently be zero. */ | |
120 | ||
121 | void | |
122 | set_identifier_kind (tree id, cp_identifier_kind kind) | |
123 | { | |
124 | gcc_checking_assert (!IDENTIFIER_KIND_BIT_2 (id) | |
125 | & !IDENTIFIER_KIND_BIT_1 (id) | |
126 | & !IDENTIFIER_KIND_BIT_0 (id)); | |
127 | IDENTIFIER_KIND_BIT_2 (id) |= (kind >> 2) & 1; | |
128 | IDENTIFIER_KIND_BIT_1 (id) |= (kind >> 1) & 1; | |
129 | IDENTIFIER_KIND_BIT_0 (id) |= (kind >> 0) & 1; | |
130 | } | |
131 | ||
f26881e3 NS |
132 | /* Create and tag the internal operator name for the overloaded |
133 | operator PTR describes. */ | |
134 | ||
135 | static tree | |
881c969c | 136 | set_operator_ident (ovl_op_info_t *ptr) |
f26881e3 NS |
137 | { |
138 | char buffer[32]; | |
139 | size_t len = snprintf (buffer, sizeof (buffer), "operator%s%s", | |
140 | &" "[ptr->name[0] && ptr->name[0] != '_' | |
141 | && !ISALPHA (ptr->name[0])], | |
142 | ptr->name); | |
143 | gcc_checking_assert (len < sizeof (buffer)); | |
144 | ||
145 | tree ident = get_identifier_with_length (buffer, len); | |
146 | ptr->identifier = ident; | |
147 | ||
148 | return ident; | |
149 | } | |
150 | ||
d6dd9d7f NS |
151 | /* Initialize data structures that keep track of operator names. */ |
152 | ||
596ea4e5 | 153 | static void |
9e7d1164 | 154 | init_operators (void) |
596ea4e5 | 155 | { |
d6dd9d7f NS |
156 | /* We rely on both these being zero. */ |
157 | gcc_checking_assert (!OVL_OP_ERROR_MARK && !ERROR_MARK); | |
158 | ||
159 | /* This loop iterates backwards because we need to move the | |
160 | assignment operators down to their correct slots. I.e. morally | |
161 | equivalent to an overlapping memmove where dest > src. Slot | |
162 | zero is for error_mark, so hae no operator. */ | |
163 | for (unsigned ix = OVL_OP_MAX; --ix;) | |
164 | { | |
165 | ovl_op_info_t *op_ptr = &ovl_op_info[false][ix]; | |
166 | ||
167 | if (op_ptr->name) | |
168 | { | |
d6dd9d7f NS |
169 | tree ident = set_operator_ident (op_ptr); |
170 | if (unsigned index = IDENTIFIER_CP_INDEX (ident)) | |
171 | { | |
172 | ovl_op_info_t *bin_ptr = &ovl_op_info[false][index]; | |
173 | ||
174 | /* They should only differ in unary/binary ness. */ | |
175 | gcc_checking_assert ((op_ptr->flags ^ bin_ptr->flags) | |
176 | == OVL_OP_FLAG_AMBIARY); | |
177 | bin_ptr->flags |= op_ptr->flags; | |
178 | ovl_op_alternate[index] = ix; | |
179 | } | |
180 | else | |
181 | { | |
182 | IDENTIFIER_CP_INDEX (ident) = ix; | |
183e687a | 183 | set_identifier_kind (ident, cik_simple_op); |
d6dd9d7f NS |
184 | } |
185 | } | |
186 | if (op_ptr->tree_code) | |
187 | { | |
188 | gcc_checking_assert (op_ptr->ovl_op_code == ix | |
189 | && !ovl_op_mapping[op_ptr->tree_code]); | |
190 | ovl_op_mapping[op_ptr->tree_code] = op_ptr->ovl_op_code; | |
191 | } | |
192 | ||
193 | ovl_op_info_t *as_ptr = &ovl_op_info[true][ix]; | |
194 | if (as_ptr->name) | |
195 | { | |
196 | /* These will be placed at the start of the array, move to | |
197 | the correct slot and initialize. */ | |
198 | if (as_ptr->ovl_op_code != ix) | |
199 | { | |
200 | ovl_op_info_t *dst_ptr = &ovl_op_info[true][as_ptr->ovl_op_code]; | |
201 | gcc_assert (as_ptr->ovl_op_code > ix && !dst_ptr->tree_code); | |
202 | memcpy (dst_ptr, as_ptr, sizeof (*dst_ptr)); | |
203 | memset (as_ptr, 0, sizeof (*as_ptr)); | |
204 | as_ptr = dst_ptr; | |
205 | } | |
206 | ||
207 | tree ident = set_operator_ident (as_ptr); | |
208 | gcc_checking_assert (!IDENTIFIER_CP_INDEX (ident)); | |
209 | IDENTIFIER_CP_INDEX (ident) = as_ptr->ovl_op_code; | |
210 | set_identifier_kind (ident, cik_assign_op); | |
211 | ||
212 | gcc_checking_assert (!ovl_op_mapping[as_ptr->tree_code] | |
213 | || (ovl_op_mapping[as_ptr->tree_code] | |
214 | == as_ptr->ovl_op_code)); | |
215 | ovl_op_mapping[as_ptr->tree_code] = as_ptr->ovl_op_code; | |
216 | } | |
217 | } | |
596ea4e5 AS |
218 | } |
219 | ||
eea1139b | 220 | /* Initialize the reserved words. */ |
0e5921e8 | 221 | |
f5e99456 | 222 | void |
9e7d1164 | 223 | init_reswords (void) |
0e5921e8 ZW |
224 | { |
225 | unsigned int i; | |
226 | tree id; | |
eea1139b ILT |
227 | int mask = 0; |
228 | ||
604b2bfc | 229 | if (cxx_dialect < cxx11) |
36a85135 | 230 | mask |= D_CXX11; |
b04445d4 | 231 | if (cxx_dialect < cxx20) |
4742dbe7 | 232 | mask |= D_CXX20; |
971e17ff AS |
233 | if (!flag_concepts) |
234 | mask |= D_CXX_CONCEPTS; | |
49789fd0 IS |
235 | if (!flag_coroutines) |
236 | mask |= D_CXX_COROUTINES; | |
41676a36 NS |
237 | if (!flag_modules) |
238 | mask |= D_CXX_MODULES; | |
b8fd7909 JM |
239 | if (!flag_tm) |
240 | mask |= D_TRANSMEM; | |
2d91f79d TH |
241 | if (!flag_char8_t) |
242 | mask |= D_CXX_CHAR8_T; | |
eea1139b ILT |
243 | if (flag_no_asm) |
244 | mask |= D_ASM | D_EXT; | |
245 | if (flag_no_gnu_keywords) | |
246 | mask |= D_EXT; | |
7ce841d2 JM |
247 | |
248 | /* The Objective-C keywords are all context-dependent. */ | |
249 | mask |= D_OBJC; | |
0e5921e8 | 250 | |
766090c2 | 251 | ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX); |
eea1139b | 252 | for (i = 0; i < num_c_common_reswords; i++) |
2b2a3531 | 253 | { |
08222495 JJ |
254 | if (c_common_reswords[i].disable & D_CONLY) |
255 | continue; | |
eea1139b ILT |
256 | id = get_identifier (c_common_reswords[i].word); |
257 | C_SET_RID_CODE (id, c_common_reswords[i].rid); | |
258 | ridpointers [(int) c_common_reswords[i].rid] = id; | |
259 | if (! (c_common_reswords[i].disable & mask)) | |
84c0088f | 260 | set_identifier_kind (id, cik_keyword); |
78a7c317 DD |
261 | } |
262 | ||
263 | for (i = 0; i < NUM_INT_N_ENTS; i++) | |
264 | { | |
265 | char name[50]; | |
266 | sprintf (name, "__int%d", int_n_data[i].bitsize); | |
267 | id = get_identifier (name); | |
268 | C_SET_RID_CODE (id, RID_FIRST_INT_N + i); | |
84c0088f | 269 | set_identifier_kind (id, cik_keyword); |
5e580306 JL |
270 | |
271 | sprintf (name, "__int%d__", int_n_data[i].bitsize); | |
272 | id = get_identifier (name); | |
273 | C_SET_RID_CODE (id, RID_FIRST_INT_N + i); | |
274 | set_identifier_kind (id, cik_keyword); | |
2b2a3531 | 275 | } |
0e5921e8 | 276 | } |
2b2a3531 | 277 | |
0e5921e8 | 278 | static void |
9e7d1164 | 279 | init_cp_pragma (void) |
0e5921e8 | 280 | { |
c58b209a NB |
281 | c_register_pragma (0, "vtable", handle_pragma_vtable); |
282 | c_register_pragma (0, "unit", handle_pragma_unit); | |
283 | c_register_pragma (0, "interface", handle_pragma_interface); | |
284 | c_register_pragma (0, "implementation", handle_pragma_implementation); | |
285 | c_register_pragma ("GCC", "interface", handle_pragma_interface); | |
286 | c_register_pragma ("GCC", "implementation", handle_pragma_implementation); | |
0e5921e8 | 287 | } |
009ed910 | 288 | \f |
feea5b18 ILT |
289 | /* TRUE if a code represents a statement. */ |
290 | ||
291 | bool statement_code_p[MAX_TREE_CODES]; | |
292 | ||
f5e99456 NB |
293 | /* Initialize the C++ front end. This function is very sensitive to |
294 | the exact order that things are done here. It would be nice if the | |
295 | initialization done by this routine were moved to its subroutines, | |
296 | and the ordering dependencies clarified and reduced. */ | |
4bfec483 NB |
297 | bool |
298 | cxx_init (void) | |
0e5921e8 | 299 | { |
966e8f4d | 300 | location_t saved_loc; |
feea5b18 | 301 | unsigned int i; |
009ed910 | 302 | static const enum tree_code stmt_codes[] = { |
feea5b18 ILT |
303 | CTOR_INITIALIZER, TRY_BLOCK, HANDLER, |
304 | EH_SPEC_BLOCK, USING_STMT, TAG_DEFN, | |
305 | IF_STMT, CLEANUP_STMT, FOR_STMT, | |
f9132eb7 RRC |
306 | RANGE_FOR_STMT, WHILE_STMT, DO_STMT, |
307 | BREAK_STMT, CONTINUE_STMT, SWITCH_STMT, | |
28567c40 | 308 | EXPR_STMT, OMP_DEPOBJ |
009ed910 SB |
309 | }; |
310 | ||
feea5b18 ILT |
311 | memset (&statement_code_p, 0, sizeof (statement_code_p)); |
312 | for (i = 0; i < ARRAY_SIZE (stmt_codes); i++) | |
313 | statement_code_p[stmt_codes[i]] = true; | |
009ed910 | 314 | |
966e8f4d TT |
315 | saved_loc = input_location; |
316 | input_location = BUILTINS_LOCATION; | |
0e5921e8 ZW |
317 | |
318 | init_reswords (); | |
87e3dbc9 | 319 | init_tree (); |
54f7877c | 320 | init_cp_semantics (); |
596ea4e5 | 321 | init_operators (); |
669ec2b4 | 322 | init_method (); |
f3cdb9c6 | 323 | |
8d08fdba MS |
324 | current_function_decl = NULL; |
325 | ||
9e62871e | 326 | class_type_node = ridpointers[(int) RID_CLASS]; |
8d08fdba | 327 | |
f5e99456 NB |
328 | cxx_init_decl_processing (); |
329 | ||
4bfec483 | 330 | if (c_common_init () == false) |
267a0752 | 331 | { |
966e8f4d | 332 | input_location = saved_loc; |
267a0752 MC |
333 | return false; |
334 | } | |
f5e99456 NB |
335 | |
336 | init_cp_pragma (); | |
337 | ||
966e8f4d | 338 | input_location = saved_loc; |
4bfec483 | 339 | return true; |
8d08fdba | 340 | } |
8d08fdba | 341 | \f |
51c184be | 342 | /* Return nonzero if S is not considered part of an |
8d08fdba | 343 | INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */ |
e92cc029 | 344 | |
8d08fdba | 345 | static int |
9e7d1164 | 346 | interface_strcmp (const char* s) |
8d08fdba MS |
347 | { |
348 | /* Set the interface/implementation bits for this scope. */ | |
349 | struct impl_files *ifiles; | |
d8e178a0 | 350 | const char *s1; |
8d08fdba | 351 | |
8d08fdba MS |
352 | for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) |
353 | { | |
d8e178a0 | 354 | const char *t1 = ifiles->filename; |
8d08fdba MS |
355 | s1 = s; |
356 | ||
ba78087b | 357 | if (*s1 == 0 || filename_ncmp (s1, t1, 1) != 0) |
8d08fdba MS |
358 | continue; |
359 | ||
ba78087b | 360 | while (*s1 != 0 && filename_ncmp (s1, t1, 1) == 0) |
8d08fdba MS |
361 | s1++, t1++; |
362 | ||
363 | /* A match. */ | |
364 | if (*s1 == *t1) | |
365 | return 0; | |
366 | ||
367 | /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ | |
9473c522 | 368 | if (strchr (s1, '.') || strchr (t1, '.')) |
8d08fdba MS |
369 | continue; |
370 | ||
371 | if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') | |
372 | continue; | |
373 | ||
374 | /* A match. */ | |
375 | return 0; | |
376 | } | |
377 | ||
378 | /* No matches. */ | |
379 | return 1; | |
380 | } | |
381 | ||
76a1719f NS |
382 | /* We've just read a cpp-token, figure out our next state. Hey, this |
383 | is a hand-coded co-routine! */ | |
384 | ||
385 | struct module_token_filter | |
386 | { | |
387 | enum state | |
388 | { | |
389 | idle, | |
390 | module_first, | |
391 | module_cont, | |
392 | module_end, | |
393 | }; | |
394 | ||
395 | enum state state : 8; | |
396 | bool is_import : 1; | |
397 | bool got_export : 1; | |
398 | bool got_colon : 1; | |
399 | bool want_dot : 1; | |
400 | ||
401 | location_t token_loc; | |
402 | cpp_reader *reader; | |
403 | module_state *module; | |
404 | module_state *import; | |
405 | ||
406 | module_token_filter (cpp_reader *reader) | |
407 | : state (idle), is_import (false), | |
408 | got_export (false), got_colon (false), want_dot (false), | |
409 | token_loc (UNKNOWN_LOCATION), | |
410 | reader (reader), module (NULL), import (NULL) | |
411 | { | |
412 | }; | |
413 | ||
414 | /* Process the next token. Note we cannot see CPP_EOF inside a | |
415 | pragma -- a CPP_PRAGMA_EOL always happens. */ | |
416 | uintptr_t resume (int type, int keyword, tree value, location_t loc) | |
417 | { | |
418 | unsigned res = 0; | |
419 | ||
420 | switch (state) | |
421 | { | |
422 | case idle: | |
423 | if (type == CPP_KEYWORD) | |
424 | switch (keyword) | |
425 | { | |
426 | default: | |
427 | break; | |
428 | ||
429 | case RID__EXPORT: | |
430 | got_export = true; | |
431 | res = lang_hooks::PT_begin_pragma; | |
432 | break; | |
433 | ||
434 | case RID__IMPORT: | |
435 | is_import = true; | |
436 | /* FALLTHRU */ | |
437 | case RID__MODULE: | |
438 | state = module_first; | |
439 | want_dot = false; | |
440 | got_colon = false; | |
441 | token_loc = loc; | |
442 | import = NULL; | |
443 | if (!got_export) | |
444 | res = lang_hooks::PT_begin_pragma; | |
445 | break; | |
446 | } | |
447 | break; | |
448 | ||
449 | case module_first: | |
450 | if (is_import && type == CPP_HEADER_NAME) | |
451 | { | |
452 | /* A header name. The preprocessor will have already | |
453 | done include searching and canonicalization. */ | |
454 | state = module_end; | |
455 | goto header_unit; | |
456 | } | |
457 | ||
458 | if (type == CPP_PADDING || type == CPP_COMMENT) | |
459 | break; | |
460 | ||
461 | state = module_cont; | |
462 | if (type == CPP_COLON && module) | |
463 | { | |
464 | got_colon = true; | |
465 | import = module; | |
466 | break; | |
467 | } | |
468 | /* FALLTHROUGH */ | |
469 | ||
470 | case module_cont: | |
471 | switch (type) | |
472 | { | |
473 | case CPP_PADDING: | |
474 | case CPP_COMMENT: | |
475 | break; | |
476 | ||
477 | default: | |
478 | /* If we ever need to pay attention to attributes for | |
479 | header modules, more logic will be needed. */ | |
480 | state = module_end; | |
481 | break; | |
482 | ||
483 | case CPP_COLON: | |
484 | if (got_colon) | |
485 | state = module_end; | |
486 | got_colon = true; | |
487 | /* FALLTHROUGH */ | |
488 | case CPP_DOT: | |
489 | if (!want_dot) | |
490 | state = module_end; | |
491 | want_dot = false; | |
492 | break; | |
493 | ||
494 | case CPP_PRAGMA_EOL: | |
495 | goto module_end; | |
496 | ||
497 | case CPP_NAME: | |
498 | if (want_dot) | |
499 | { | |
500 | /* Got name instead of [.:]. */ | |
501 | state = module_end; | |
502 | break; | |
503 | } | |
504 | header_unit: | |
505 | import = get_module (value, import, got_colon); | |
506 | want_dot = true; | |
507 | break; | |
508 | } | |
509 | break; | |
510 | ||
511 | case module_end: | |
512 | if (type == CPP_PRAGMA_EOL) | |
513 | { | |
514 | module_end:; | |
515 | /* End of the directive, handle the name. */ | |
504450c7 | 516 | if (import && (is_import || !flag_header_unit)) |
76a1719f NS |
517 | if (module_state *m |
518 | = preprocess_module (import, token_loc, module != NULL, | |
519 | is_import, got_export, reader)) | |
520 | if (!module) | |
521 | module = m; | |
522 | ||
523 | is_import = got_export = false; | |
524 | state = idle; | |
525 | } | |
526 | break; | |
527 | } | |
528 | ||
529 | return res; | |
530 | } | |
531 | }; | |
532 | ||
533 | /* Initialize or teardown. */ | |
534 | ||
535 | uintptr_t | |
536 | module_token_cdtor (cpp_reader *pfile, uintptr_t data_) | |
537 | { | |
538 | if (module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_)) | |
539 | { | |
540 | preprocessed_module (pfile); | |
541 | delete filter; | |
542 | data_ = 0; | |
543 | } | |
544 | else if (modules_p ()) | |
545 | data_ = reinterpret_cast<uintptr_t > (new module_token_filter (pfile)); | |
546 | ||
547 | return data_; | |
548 | } | |
549 | ||
550 | uintptr_t | |
551 | module_token_lang (int type, int keyword, tree value, location_t loc, | |
552 | uintptr_t data_) | |
553 | { | |
554 | module_token_filter *filter = reinterpret_cast<module_token_filter *> (data_); | |
555 | return filter->resume (type, keyword, value, loc); | |
556 | } | |
557 | ||
558 | uintptr_t | |
559 | module_token_pre (cpp_reader *pfile, const cpp_token *tok, uintptr_t data_) | |
560 | { | |
561 | if (!tok) | |
562 | return module_token_cdtor (pfile, data_); | |
563 | ||
564 | int type = tok->type; | |
565 | int keyword = RID_MAX; | |
566 | tree value = NULL_TREE; | |
567 | ||
568 | if (tok->type == CPP_NAME) | |
569 | { | |
570 | value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node)); | |
571 | if (IDENTIFIER_KEYWORD_P (value)) | |
572 | { | |
573 | keyword = C_RID_CODE (value); | |
574 | type = CPP_KEYWORD; | |
575 | } | |
576 | } | |
577 | else if (tok->type == CPP_HEADER_NAME) | |
578 | value = build_string (tok->val.str.len, (const char *)tok->val.str.text); | |
579 | ||
580 | return module_token_lang (type, keyword, value, tok->src_loc, data_); | |
581 | } | |
0e5921e8 ZW |
582 | |
583 | /* Parse a #pragma whose sole argument is a string constant. | |
584 | If OPT is true, the argument is optional. */ | |
585 | static tree | |
9e7d1164 | 586 | parse_strconst_pragma (const char* name, int opt) |
0e5921e8 ZW |
587 | { |
588 | tree result, x; | |
589 | enum cpp_ttype t; | |
590 | ||
ebf0088a | 591 | t = pragma_lex (&result); |
0e5921e8 ZW |
592 | if (t == CPP_STRING) |
593 | { | |
75ce3d48 | 594 | if (pragma_lex (&x) != CPP_EOF) |
a9c697b8 | 595 | warning (0, "junk at end of %<#pragma %s%>", name); |
0e5921e8 ZW |
596 | return result; |
597 | } | |
598 | ||
599 | if (t == CPP_EOF && opt) | |
ebf0088a | 600 | return NULL_TREE; |
0e5921e8 | 601 | |
a9c697b8 | 602 | error ("invalid %<#pragma %s%>", name); |
ebf0088a | 603 | return error_mark_node; |
0e5921e8 | 604 | } |
5362b086 | 605 | |
0e5921e8 | 606 | static void |
12308bc6 | 607 | handle_pragma_vtable (cpp_reader* /*dfile*/) |
0e5921e8 | 608 | { |
46ccf50a | 609 | parse_strconst_pragma ("vtable", 0); |
a9c697b8 | 610 | sorry ("%<#pragma vtable%> no longer supported"); |
0e5921e8 ZW |
611 | } |
612 | ||
1d02ac83 | 613 | static void |
12308bc6 | 614 | handle_pragma_unit (cpp_reader* /*dfile*/) |
1d02ac83 | 615 | { |
0e5921e8 ZW |
616 | /* Validate syntax, but don't do anything. */ |
617 | parse_strconst_pragma ("unit", 0); | |
618 | } | |
619 | ||
620 | static void | |
12308bc6 | 621 | handle_pragma_interface (cpp_reader* /*dfile*/) |
0e5921e8 ZW |
622 | { |
623 | tree fname = parse_strconst_pragma ("interface", 1); | |
624 | struct c_fileinfo *finfo; | |
c162c75e | 625 | const char *filename; |
0e5921e8 | 626 | |
ebf0088a | 627 | if (fname == error_mark_node) |
0e5921e8 ZW |
628 | return; |
629 | else if (fname == 0) | |
8400e75e | 630 | filename = lbasename (LOCATION_FILE (input_location)); |
0e5921e8 | 631 | else |
50c91950 | 632 | filename = TREE_STRING_POINTER (fname); |
0e5921e8 | 633 | |
8400e75e | 634 | finfo = get_fileinfo (LOCATION_FILE (input_location)); |
1d02ac83 JM |
635 | |
636 | if (impl_file_chain == 0) | |
637 | { | |
638 | /* If this is zero at this point, then we are | |
639 | auto-implementing. */ | |
640 | if (main_input_filename == 0) | |
8400e75e | 641 | main_input_filename = LOCATION_FILE (input_location); |
1d02ac83 JM |
642 | } |
643 | ||
c162c75e | 644 | finfo->interface_only = interface_strcmp (filename); |
15072eb1 ZW |
645 | /* If MULTIPLE_SYMBOL_SPACES is set, we cannot assume that we can see |
646 | a definition in another file. */ | |
5d709b00 ZW |
647 | if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only) |
648 | finfo->interface_unknown = 0; | |
1d02ac83 JM |
649 | } |
650 | ||
777ffbda JM |
651 | /* Note that we have seen a #pragma implementation for the key MAIN_FILENAME. |
652 | We used to only allow this at toplevel, but that restriction was buggy | |
653 | in older compilers and it seems reasonable to allow it in the headers | |
654 | themselves, too. It only needs to precede the matching #p interface. | |
655 | ||
5d709b00 ZW |
656 | We don't touch finfo->interface_only or finfo->interface_unknown; |
657 | the user must specify a matching #p interface for this to have | |
658 | any effect. */ | |
777ffbda | 659 | |
1d02ac83 | 660 | static void |
12308bc6 | 661 | handle_pragma_implementation (cpp_reader* /*dfile*/) |
1d02ac83 | 662 | { |
0e5921e8 | 663 | tree fname = parse_strconst_pragma ("implementation", 1); |
c162c75e | 664 | const char *filename; |
777ffbda | 665 | struct impl_files *ifiles = impl_file_chain; |
0e5921e8 | 666 | |
ebf0088a | 667 | if (fname == error_mark_node) |
0e5921e8 ZW |
668 | return; |
669 | ||
670 | if (fname == 0) | |
671 | { | |
672 | if (main_input_filename) | |
c162c75e | 673 | filename = main_input_filename; |
0e5921e8 | 674 | else |
8400e75e | 675 | filename = LOCATION_FILE (input_location); |
c162c75e | 676 | filename = lbasename (filename); |
0e5921e8 ZW |
677 | } |
678 | else | |
679 | { | |
50c91950 | 680 | filename = TREE_STRING_POINTER (fname); |
f1e20710 | 681 | if (cpp_included_before (parse_in, filename, input_location)) |
a9c697b8 | 682 | warning (0, "%<#pragma implementation%> for %qs appears after " |
c162c75e | 683 | "file is included", filename); |
0e5921e8 ZW |
684 | } |
685 | ||
777ffbda | 686 | for (; ifiles; ifiles = ifiles->next) |
1d02ac83 | 687 | { |
ba78087b | 688 | if (! filename_cmp (ifiles->filename, filename)) |
777ffbda | 689 | break; |
1d02ac83 | 690 | } |
777ffbda | 691 | if (ifiles == 0) |
1d02ac83 | 692 | { |
0ac1b889 | 693 | ifiles = XNEW (struct impl_files); |
50c91950 | 694 | ifiles->filename = xstrdup (filename); |
777ffbda JM |
695 | ifiles->next = impl_file_chain; |
696 | impl_file_chain = ifiles; | |
1d02ac83 | 697 | } |
1d02ac83 | 698 | } |
f181d4ae | 699 | |
15c7fb9c | 700 | /* Issue an error message indicating that the lookup of NAME (an |
b3445994 | 701 | IDENTIFIER_NODE) failed. Returns the ERROR_MARK_NODE. */ |
15c7fb9c | 702 | |
b3445994 | 703 | tree |
b2f6675b | 704 | unqualified_name_lookup_error (tree name, location_t loc) |
15c7fb9c | 705 | { |
b2f6675b | 706 | if (loc == UNKNOWN_LOCATION) |
f9d0ca40 | 707 | loc = cp_expr_loc_or_input_loc (name); |
b2f6675b | 708 | |
84c0088f | 709 | if (IDENTIFIER_ANY_OP_P (name)) |
ff630487 | 710 | error_at (loc, "%qD not defined", name); |
15c7fb9c MM |
711 | else |
712 | { | |
dd2e44f0 | 713 | if (!objc_diagnose_private_ivar (name)) |
501c95ff | 714 | { |
097f82ec | 715 | auto_diagnostic_group d; |
7e2de6df DM |
716 | name_hint hint = suggest_alternatives_for (loc, name, true); |
717 | if (const char *suggestion = hint.suggestion ()) | |
718 | { | |
719 | gcc_rich_location richloc (loc); | |
720 | richloc.add_fixit_replace (suggestion); | |
721 | error_at (&richloc, | |
722 | "%qD was not declared in this scope; did you mean %qs?", | |
723 | name, suggestion); | |
724 | } | |
725 | else | |
726 | error_at (loc, "%qD was not declared in this scope", name); | |
501c95ff | 727 | } |
58ec3cc5 MM |
728 | /* Prevent repeated error messages by creating a VAR_DECL with |
729 | this NAME in the innermost block scope. */ | |
fdf03377 | 730 | if (local_bindings_p ()) |
15c7fb9c | 731 | { |
77fa3ec1 NS |
732 | tree decl = build_decl (loc, VAR_DECL, name, error_mark_node); |
733 | TREE_USED (decl) = true; | |
734 | pushdecl (decl); | |
15c7fb9c | 735 | } |
15c7fb9c | 736 | } |
935d1834 | 737 | |
b3445994 | 738 | return error_mark_node; |
5566b478 MS |
739 | } |
740 | ||
b2f6675b PC |
741 | /* Like unqualified_name_lookup_error, but NAME_EXPR is an unqualified-id |
742 | NAME, encapsulated with its location in a CP_EXPR, used as a function. | |
743 | Returns an appropriate expression for NAME. */ | |
b3445994 | 744 | |
5566b478 | 745 | tree |
b2f6675b | 746 | unqualified_fn_lookup_error (cp_expr name_expr) |
5566b478 | 747 | { |
b2f6675b PC |
748 | tree name = name_expr.get_value (); |
749 | location_t loc = name_expr.get_location (); | |
750 | if (loc == UNKNOWN_LOCATION) | |
751 | loc = input_location; | |
752 | ||
5d9a0e3b MP |
753 | if (TREE_CODE (name) == TEMPLATE_ID_EXPR) |
754 | name = TREE_OPERAND (name, 0); | |
755 | ||
5156628f | 756 | if (processing_template_decl) |
5566b478 | 757 | { |
b3445994 MM |
758 | /* In a template, it is invalid to write "f()" or "f(3)" if no |
759 | declaration of "f" is available. Historically, G++ and most | |
c5785644 WB |
760 | other compilers accepted that usage since they deferred all name |
761 | lookup until instantiation time rather than doing unqualified | |
c8094d83 | 762 | name lookup at template definition time; explain to the user what |
c5785644 WB |
763 | is going wrong. |
764 | ||
765 | Note that we have the exact wording of the following message in | |
766 | the manual (trouble.texi, node "Name lookup"), so they need to | |
767 | be kept in synch. */ | |
b2f6675b | 768 | permerror (loc, "there are no arguments to %qD that depend on a template " |
393eda6a MLI |
769 | "parameter, so a declaration of %qD must be available", |
770 | name, name); | |
c8094d83 | 771 | |
b3445994 | 772 | if (!flag_permissive) |
5566b478 | 773 | { |
b3445994 MM |
774 | static bool hint; |
775 | if (!hint) | |
776 | { | |
b2f6675b | 777 | inform (loc, "(if you use %<-fpermissive%>, G++ will accept your " |
a9c697b8 MS |
778 | "code, but allowing the use of an undeclared name is " |
779 | "deprecated)"); | |
b3445994 MM |
780 | hint = true; |
781 | } | |
5566b478 | 782 | } |
10b1d5e7 | 783 | return name; |
5566b478 | 784 | } |
8d08fdba | 785 | |
b2f6675b | 786 | return unqualified_name_lookup_error (name, loc); |
8d08fdba MS |
787 | } |
788 | ||
f216550d NS |
789 | |
790 | /* Hasher for the conversion operator name hash table. */ | |
08fb1316 NS |
791 | struct conv_type_hasher : ggc_ptr_hash<tree_node> |
792 | { | |
f216550d NS |
793 | /* Hash NODE, an identifier node in the table. TYPE_UID is |
794 | suitable, as we're not concerned about matching canonicalness | |
795 | here. */ | |
796 | static hashval_t hash (tree node) | |
797 | { | |
798 | return (hashval_t) TYPE_UID (TREE_TYPE (node)); | |
799 | } | |
800 | ||
801 | /* Compare NODE, an identifier node in the table, against TYPE, an | |
802 | incoming TYPE being looked up. */ | |
803 | static bool equal (tree node, tree type) | |
804 | { | |
805 | return TREE_TYPE (node) == type; | |
806 | } | |
08fb1316 NS |
807 | }; |
808 | ||
809 | /* This hash table maps TYPEs to the IDENTIFIER for a conversion | |
810 | operator to TYPE. The nodes are IDENTIFIERs whose TREE_TYPE is the | |
811 | TYPE. */ | |
812 | ||
813 | static GTY (()) hash_table<conv_type_hasher> *conv_type_names; | |
814 | ||
f216550d NS |
815 | /* Return an identifier for a conversion operator to TYPE. We can get |
816 | from the returned identifier to the type. We store TYPE, which is | |
817 | not necessarily the canonical type, which allows us to report the | |
818 | form the user used in error messages. All these identifiers are | |
819 | not in the identifier hash table, and have the same string name. | |
820 | These IDENTIFIERS are not in the identifier hash table, and all | |
821 | have the same IDENTIFIER_STRING. */ | |
08fb1316 NS |
822 | |
823 | tree | |
824 | make_conv_op_name (tree type) | |
825 | { | |
08fb1316 NS |
826 | if (type == error_mark_node) |
827 | return error_mark_node; | |
828 | ||
829 | if (conv_type_names == NULL) | |
830 | conv_type_names = hash_table<conv_type_hasher>::create_ggc (31); | |
831 | ||
f216550d NS |
832 | tree *slot = conv_type_names->find_slot_with_hash |
833 | (type, (hashval_t) TYPE_UID (type), INSERT); | |
834 | tree identifier = *slot; | |
08fb1316 NS |
835 | if (!identifier) |
836 | { | |
f216550d NS |
837 | /* Create a raw IDENTIFIER outside of the identifier hash |
838 | table. */ | |
839 | identifier = copy_node (conv_op_identifier); | |
08fb1316 | 840 | |
f216550d NS |
841 | /* Just in case something managed to bind. */ |
842 | IDENTIFIER_BINDING (identifier) = NULL; | |
08fb1316 NS |
843 | |
844 | /* Hang TYPE off the identifier so it can be found easily later | |
845 | when performing conversions. */ | |
846 | TREE_TYPE (identifier) = type; | |
847 | ||
f216550d | 848 | *slot = identifier; |
08fb1316 NS |
849 | } |
850 | ||
851 | return identifier; | |
852 | } | |
853 | ||
4cc2a722 AC |
854 | /* Wrapper around build_lang_decl_loc(). Should gradually move to |
855 | build_lang_decl_loc() and then rename build_lang_decl_loc() back to | |
856 | build_lang_decl(). */ | |
857 | ||
8d08fdba | 858 | tree |
9e7d1164 | 859 | build_lang_decl (enum tree_code code, tree name, tree type) |
4cc2a722 AC |
860 | { |
861 | return build_lang_decl_loc (input_location, code, name, type); | |
862 | } | |
863 | ||
864 | /* Build a decl from CODE, NAME, TYPE declared at LOC, and then add | |
865 | DECL_LANG_SPECIFIC info to the result. */ | |
866 | ||
867 | tree | |
868 | build_lang_decl_loc (location_t loc, enum tree_code code, tree name, tree type) | |
8d08fdba | 869 | { |
4ce3d537 MM |
870 | tree t; |
871 | ||
4cc2a722 | 872 | t = build_decl (loc, code, name, type); |
fcfcdfc8 | 873 | retrofit_lang_decl (t); |
4ce3d537 | 874 | |
fcfcdfc8 JM |
875 | return t; |
876 | } | |
877 | ||
91e920c9 NS |
878 | /* Maybe add a raw lang_decl to T, a decl. Return true if it needed |
879 | one. */ | |
fcfcdfc8 | 880 | |
0fc6469d | 881 | bool |
91e920c9 | 882 | maybe_add_lang_decl_raw (tree t, bool decomp_p) |
fcfcdfc8 | 883 | { |
4ce3d537 | 884 | size_t size; |
91e920c9 | 885 | lang_decl_selector sel; |
3048c0c7 | 886 | |
91e920c9 NS |
887 | if (decomp_p) |
888 | sel = lds_decomp, size = sizeof (struct lang_decl_decomp); | |
6fc9f7aa | 889 | else if (TREE_CODE (t) == FUNCTION_DECL) |
91e920c9 | 890 | sel = lds_fn, size = sizeof (struct lang_decl_fn); |
b97e8a14 | 891 | else if (TREE_CODE (t) == NAMESPACE_DECL) |
91e920c9 | 892 | sel = lds_ns, size = sizeof (struct lang_decl_ns); |
ad909c97 | 893 | else if (TREE_CODE (t) == PARM_DECL) |
91e920c9 | 894 | sel = lds_parm, size = sizeof (struct lang_decl_parm); |
b97e8a14 | 895 | else if (LANG_DECL_HAS_MIN (t)) |
91e920c9 | 896 | sel = lds_min, size = sizeof (struct lang_decl_min); |
4ce3d537 | 897 | else |
91e920c9 | 898 | return false; |
b0d06515 | 899 | |
91e920c9 NS |
900 | struct lang_decl *ld |
901 | = (struct lang_decl *) ggc_internal_cleared_alloc (size); | |
8d08fdba | 902 | |
b97e8a14 | 903 | ld->u.base.selector = sel; |
9188c363 | 904 | DECL_LANG_SPECIFIC (t) = ld; |
98c28dd4 | 905 | |
91e920c9 | 906 | if (sel == lds_ns) |
98c28dd4 | 907 | /* Who'd create a namespace, only to put nothing in it? */ |
e833f686 | 908 | ld->u.ns.bindings = hash_table<named_decl_hash>::create_ggc (499); |
98c28dd4 | 909 | |
91e920c9 NS |
910 | if (GATHER_STATISTICS) |
911 | { | |
912 | tree_node_counts[(int)lang_decl] += 1; | |
913 | tree_node_sizes[(int)lang_decl] += size; | |
914 | } | |
915 | return true; | |
916 | } | |
917 | ||
918 | /* T has just had a decl_lang_specific added. Initialize its | |
919 | linkage. */ | |
920 | ||
921 | static void | |
922 | set_decl_linkage (tree t) | |
923 | { | |
ab73670a MM |
924 | if (current_lang_name == lang_name_cplusplus |
925 | || decl_linkage (t) == lk_none) | |
5d2ed28c | 926 | SET_DECL_LANGUAGE (t, lang_cplusplus); |
8d08fdba | 927 | else if (current_lang_name == lang_name_c) |
5d2ed28c | 928 | SET_DECL_LANGUAGE (t, lang_c); |
8dc2b103 NS |
929 | else |
930 | gcc_unreachable (); | |
91e920c9 | 931 | } |
8d08fdba | 932 | |
91e920c9 NS |
933 | /* T is a VAR_DECL node that needs to be a decomposition of BASE. */ |
934 | ||
935 | void | |
936 | fit_decomposition_lang_decl (tree t, tree base) | |
937 | { | |
938 | if (struct lang_decl *orig_ld = DECL_LANG_SPECIFIC (t)) | |
7aa6d18a | 939 | { |
91e920c9 NS |
940 | if (orig_ld->u.base.selector == lds_min) |
941 | { | |
942 | maybe_add_lang_decl_raw (t, true); | |
943 | memcpy (DECL_LANG_SPECIFIC (t), orig_ld, | |
944 | sizeof (struct lang_decl_min)); | |
945 | /* Reset selector, which will have been bashed by the | |
946 | memcpy. */ | |
947 | DECL_LANG_SPECIFIC (t)->u.base.selector = lds_decomp; | |
948 | } | |
949 | else | |
950 | gcc_checking_assert (orig_ld->u.base.selector == lds_decomp); | |
951 | } | |
952 | else | |
953 | { | |
954 | maybe_add_lang_decl_raw (t, true); | |
955 | set_decl_linkage (t); | |
7aa6d18a | 956 | } |
91e920c9 NS |
957 | |
958 | DECL_DECOMP_BASE (t) = base; | |
959 | } | |
960 | ||
961 | /* Add DECL_LANG_SPECIFIC info to T, if it needs one. Generally | |
962 | every C++ decl needs one, but C builtins etc do not. */ | |
963 | ||
964 | void | |
965 | retrofit_lang_decl (tree t) | |
966 | { | |
967 | if (DECL_LANG_SPECIFIC (t)) | |
968 | return; | |
969 | ||
970 | if (maybe_add_lang_decl_raw (t, false)) | |
971 | set_decl_linkage (t); | |
8d08fdba MS |
972 | } |
973 | ||
8d08fdba | 974 | void |
9e7d1164 | 975 | cxx_dup_lang_specific_decl (tree node) |
8d08fdba MS |
976 | { |
977 | int size; | |
8d08fdba | 978 | |
5566b478 MS |
979 | if (! DECL_LANG_SPECIFIC (node)) |
980 | return; | |
981 | ||
91e920c9 NS |
982 | switch (DECL_LANG_SPECIFIC (node)->u.base.selector) |
983 | { | |
984 | case lds_min: | |
985 | size = sizeof (struct lang_decl_min); | |
986 | break; | |
987 | case lds_fn: | |
988 | size = sizeof (struct lang_decl_fn); | |
989 | break; | |
990 | case lds_ns: | |
991 | size = sizeof (struct lang_decl_ns); | |
992 | break; | |
993 | case lds_parm: | |
994 | size = sizeof (struct lang_decl_parm); | |
995 | break; | |
996 | case lds_decomp: | |
997 | size = sizeof (struct lang_decl_decomp); | |
998 | break; | |
999 | default: | |
1000 | gcc_unreachable (); | |
1001 | } | |
b97e8a14 | 1002 | |
91e920c9 | 1003 | struct lang_decl *ld = (struct lang_decl *) ggc_internal_alloc (size); |
4e135bdd | 1004 | memcpy (ld, DECL_LANG_SPECIFIC (node), size); |
d60f72ae | 1005 | DECL_LANG_SPECIFIC (node) = ld; |
11e74ea6 | 1006 | |
cf97b970 NS |
1007 | /* Directly clear some flags that do not apply to the copy |
1008 | (module_purview_p still does). */ | |
1009 | ld->u.base.module_entity_p = false; | |
1010 | ld->u.base.module_import_p = false; | |
c778a237 | 1011 | ld->u.base.module_attached_p = false; |
cf97b970 | 1012 | |
7aa6d18a SB |
1013 | if (GATHER_STATISTICS) |
1014 | { | |
1015 | tree_node_counts[(int)lang_decl] += 1; | |
1016 | tree_node_sizes[(int)lang_decl] += size; | |
1017 | } | |
8d08fdba MS |
1018 | } |
1019 | ||
0acf7199 MM |
1020 | /* Copy DECL, including any language-specific parts. */ |
1021 | ||
1022 | tree | |
ad32f067 | 1023 | copy_decl (tree decl MEM_STAT_DECL) |
0acf7199 MM |
1024 | { |
1025 | tree copy; | |
1026 | ||
39d970d7 | 1027 | copy = copy_node (decl PASS_MEM_STAT); |
63e1b1c4 | 1028 | cxx_dup_lang_specific_decl (copy); |
0acf7199 MM |
1029 | return copy; |
1030 | } | |
1031 | ||
11e74ea6 KL |
1032 | /* Replace the shared language-specific parts of NODE with a new copy. */ |
1033 | ||
76648a8b | 1034 | static void |
9e7d1164 | 1035 | copy_lang_type (tree node) |
11e74ea6 | 1036 | { |
11e74ea6 KL |
1037 | if (! TYPE_LANG_SPECIFIC (node)) |
1038 | return; | |
1039 | ||
0fc6469d | 1040 | auto *lt = (struct lang_type *) ggc_internal_alloc (sizeof (struct lang_type)); |
030cfa22 NS |
1041 | |
1042 | memcpy (lt, TYPE_LANG_SPECIFIC (node), (sizeof (struct lang_type))); | |
11e74ea6 KL |
1043 | TYPE_LANG_SPECIFIC (node) = lt; |
1044 | ||
7aa6d18a SB |
1045 | if (GATHER_STATISTICS) |
1046 | { | |
1047 | tree_node_counts[(int)lang_type] += 1; | |
030cfa22 | 1048 | tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); |
7aa6d18a | 1049 | } |
11e74ea6 KL |
1050 | } |
1051 | ||
1052 | /* Copy TYPE, including any language-specific parts. */ | |
1053 | ||
1054 | tree | |
ad32f067 | 1055 | copy_type (tree type MEM_STAT_DECL) |
11e74ea6 KL |
1056 | { |
1057 | tree copy; | |
1058 | ||
39d970d7 | 1059 | copy = copy_node (type PASS_MEM_STAT); |
11e74ea6 KL |
1060 | copy_lang_type (copy); |
1061 | return copy; | |
1062 | } | |
1063 | ||
91e920c9 | 1064 | /* Add a raw lang_type to T, a type, should it need one. */ |
8d08fdba | 1065 | |
0fc6469d | 1066 | bool |
91e920c9 NS |
1067 | maybe_add_lang_type_raw (tree t) |
1068 | { | |
776ff3ef | 1069 | if (!RECORD_OR_UNION_CODE_P (TREE_CODE (t))) |
2de0ccc8 NS |
1070 | return false; |
1071 | ||
0fc6469d NS |
1072 | auto *lt = (struct lang_type *) (ggc_internal_cleared_alloc |
1073 | (sizeof (struct lang_type))); | |
1074 | TYPE_LANG_SPECIFIC (t) = lt; | |
11e74ea6 | 1075 | |
2de0ccc8 NS |
1076 | if (GATHER_STATISTICS) |
1077 | { | |
1078 | tree_node_counts[(int)lang_type] += 1; | |
1079 | tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); | |
11e74ea6 | 1080 | } |
2de0ccc8 NS |
1081 | |
1082 | return true; | |
91e920c9 NS |
1083 | } |
1084 | ||
1085 | tree | |
6ec04704 | 1086 | cxx_make_type (enum tree_code code MEM_STAT_DECL) |
91e920c9 | 1087 | { |
6ec04704 | 1088 | tree t = make_node (code PASS_MEM_STAT); |
91e920c9 | 1089 | |
776ff3ef | 1090 | if (maybe_add_lang_type_raw (t)) |
11e74ea6 | 1091 | { |
776ff3ef NS |
1092 | /* Set up some flags that give proper default behavior. */ |
1093 | struct c_fileinfo *finfo = | |
8400e75e | 1094 | get_fileinfo (LOCATION_FILE (input_location)); |
5d709b00 ZW |
1095 | SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown); |
1096 | CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only; | |
7ddedda4 | 1097 | } |
8d08fdba | 1098 | |
f4af4019 JH |
1099 | if (code == RECORD_TYPE || code == UNION_TYPE) |
1100 | TYPE_CXX_ODR_P (t) = 1; | |
1101 | ||
8d08fdba MS |
1102 | return t; |
1103 | } | |
1104 | ||
6ec04704 JM |
1105 | /* A wrapper without the memory stats for LANG_HOOKS_MAKE_TYPE. */ |
1106 | ||
1107 | tree | |
1108 | cxx_make_type_hook (enum tree_code code) | |
1109 | { | |
1110 | return cxx_make_type (code); | |
1111 | } | |
1112 | ||
33848bb0 | 1113 | tree |
6ec04704 | 1114 | make_class_type (enum tree_code code MEM_STAT_DECL) |
33848bb0 | 1115 | { |
6ec04704 | 1116 | tree t = cxx_make_type (code PASS_MEM_STAT); |
9e1e64ec | 1117 | SET_CLASS_TYPE_P (t, 1); |
33848bb0 RH |
1118 | return t; |
1119 | } | |
61172206 JM |
1120 | |
1121 | /* Returns true if we are currently in the main source file, or in a | |
1122 | template instantiation started from the main source file. */ | |
1123 | ||
1124 | bool | |
1125 | in_main_input_context (void) | |
1126 | { | |
e2c3721c | 1127 | struct tinst_level *tl = outermost_tinst_level(); |
61172206 JM |
1128 | |
1129 | if (tl) | |
ba78087b KT |
1130 | return filename_cmp (main_input_filename, |
1131 | LOCATION_FILE (tl->locus)) == 0; | |
61172206 | 1132 | else |
8400e75e | 1133 | return filename_cmp (main_input_filename, LOCATION_FILE (input_location)) == 0; |
61172206 | 1134 | } |
08fb1316 NS |
1135 | |
1136 | #include "gt-cp-lex.h" |