File: | build/gcc/cp/parser.cc |
Warning: | line 9393, column 13 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- C++ -*- Parser. |
2 | Copyright (C) 2000-2023 Free Software Foundation, Inc. |
3 | Written by Mark Mitchell <mark@codesourcery.com>. |
4 | |
5 | This file is part of GCC. |
6 | |
7 | GCC is free software; you can redistribute it and/or modify it |
8 | 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, but |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | 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 | #define INCLUDE_MEMORY |
23 | #include "system.h" |
24 | #include "coretypes.h" |
25 | #include "cp-tree.h" |
26 | #include "c-family/c-common.h" |
27 | #include "timevar.h" |
28 | #include "stringpool.h" |
29 | #include "cgraph.h" |
30 | #include "print-tree.h" |
31 | #include "attribs.h" |
32 | #include "trans-mem.h" |
33 | #include "intl.h" |
34 | #include "decl.h" |
35 | #include "c-family/c-objc.h" |
36 | #include "plugin.h" |
37 | #include "tree-pretty-print.h" |
38 | #include "parser.h" |
39 | #include "gomp-constants.h" |
40 | #include "omp-general.h" |
41 | #include "omp-offload.h" |
42 | #include "c-family/c-indentation.h" |
43 | #include "context.h" |
44 | #include "gcc-rich-location.h" |
45 | #include "tree-iterator.h" |
46 | #include "cp-name-hint.h" |
47 | #include "memmodel.h" |
48 | #include "c-family/known-headers.h" |
49 | #include "contracts.h" |
50 | #include "bitmap.h" |
51 | |
52 | |
53 | /* The lexer. */ |
54 | |
55 | /* The cp_lexer_* routines mediate between the lexer proper (in libcpp |
56 | and c-lex.cc) and the C++ parser. */ |
57 | |
58 | /* The various kinds of non integral constant we encounter. */ |
59 | enum non_integral_constant { |
60 | NIC_NONE, |
61 | /* floating-point literal */ |
62 | NIC_FLOAT, |
63 | /* %<this%> */ |
64 | NIC_THIS, |
65 | /* %<__FUNCTION__%> */ |
66 | NIC_FUNC_NAME, |
67 | /* %<__PRETTY_FUNCTION__%> */ |
68 | NIC_PRETTY_FUNC, |
69 | /* %<__func__%> */ |
70 | NIC_C99_FUNC, |
71 | /* "%<va_arg%> */ |
72 | NIC_VA_ARG, |
73 | /* a cast */ |
74 | NIC_CAST, |
75 | /* %<typeid%> operator */ |
76 | NIC_TYPEID, |
77 | /* non-constant compound literals */ |
78 | NIC_NCC, |
79 | /* a function call */ |
80 | NIC_FUNC_CALL, |
81 | /* an increment */ |
82 | NIC_INC, |
83 | /* an decrement */ |
84 | NIC_DEC, |
85 | /* an array reference */ |
86 | NIC_ARRAY_REF, |
87 | /* %<->%> */ |
88 | NIC_ARROW, |
89 | /* %<.%> */ |
90 | NIC_POINT, |
91 | /* the address of a label */ |
92 | NIC_ADDR_LABEL, |
93 | /* %<*%> */ |
94 | NIC_STAR, |
95 | /* %<&%> */ |
96 | NIC_ADDR, |
97 | /* %<++%> */ |
98 | NIC_PREINCREMENT, |
99 | /* %<--%> */ |
100 | NIC_PREDECREMENT, |
101 | /* %<new%> */ |
102 | NIC_NEW, |
103 | /* %<delete%> */ |
104 | NIC_DEL, |
105 | /* calls to overloaded operators */ |
106 | NIC_OVERLOADED, |
107 | /* an assignment */ |
108 | NIC_ASSIGNMENT, |
109 | /* a comma operator */ |
110 | NIC_COMMA, |
111 | /* a call to a constructor */ |
112 | NIC_CONSTRUCTOR, |
113 | /* a transaction expression */ |
114 | NIC_TRANSACTION |
115 | }; |
116 | |
117 | /* The various kinds of errors about name-lookup failing. */ |
118 | enum name_lookup_error { |
119 | /* NULL */ |
120 | NLE_NULL, |
121 | /* is not a type */ |
122 | NLE_TYPE, |
123 | /* is not a class or namespace */ |
124 | NLE_CXX98, |
125 | /* is not a class, namespace, or enumeration */ |
126 | NLE_NOT_CXX98 |
127 | }; |
128 | |
129 | /* The various kinds of required token */ |
130 | enum required_token { |
131 | RT_NONE, |
132 | RT_SEMICOLON, /* ';' */ |
133 | RT_OPEN_PAREN, /* '(' */ |
134 | RT_CLOSE_BRACE, /* '}' */ |
135 | RT_OPEN_BRACE, /* '{' */ |
136 | RT_CLOSE_SQUARE, /* ']' */ |
137 | RT_OPEN_SQUARE, /* '[' */ |
138 | RT_COMMA, /* ',' */ |
139 | RT_SCOPE, /* '::' */ |
140 | RT_LESS, /* '<' */ |
141 | RT_GREATER, /* '>' */ |
142 | RT_EQ, /* '=' */ |
143 | RT_ELLIPSIS, /* '...' */ |
144 | RT_MULT, /* '*' */ |
145 | RT_COMPL, /* '~' */ |
146 | RT_COLON, /* ':' */ |
147 | RT_COLON_SCOPE, /* ':' or '::' */ |
148 | RT_CLOSE_PAREN, /* ')' */ |
149 | RT_COMMA_CLOSE_PAREN, /* ',' or ')' */ |
150 | RT_PRAGMA_EOL, /* end of line */ |
151 | RT_NAME, /* identifier */ |
152 | |
153 | /* The type is CPP_KEYWORD */ |
154 | RT_NEW, /* new */ |
155 | RT_DELETE, /* delete */ |
156 | RT_RETURN, /* return */ |
157 | RT_WHILE, /* while */ |
158 | RT_EXTERN, /* extern */ |
159 | RT_STATIC_ASSERT, /* static_assert */ |
160 | RT_DECLTYPE, /* decltype */ |
161 | RT_OPERATOR, /* operator */ |
162 | RT_CLASS, /* class */ |
163 | RT_TEMPLATE, /* template */ |
164 | RT_NAMESPACE, /* namespace */ |
165 | RT_USING, /* using */ |
166 | RT_ASM, /* asm */ |
167 | RT_TRY, /* try */ |
168 | RT_CATCH, /* catch */ |
169 | RT_THROW, /* throw */ |
170 | RT_AUTO, /* auto */ |
171 | RT_LABEL, /* __label__ */ |
172 | RT_AT_TRY, /* @try */ |
173 | RT_AT_SYNCHRONIZED, /* @synchronized */ |
174 | RT_AT_THROW, /* @throw */ |
175 | |
176 | RT_SELECT, /* selection-statement */ |
177 | RT_ITERATION, /* iteration-statement */ |
178 | RT_JUMP, /* jump-statement */ |
179 | RT_CLASS_KEY, /* class-key */ |
180 | RT_CLASS_TYPENAME_TEMPLATE, /* class, typename, or template */ |
181 | RT_TRANSACTION_ATOMIC, /* __transaction_atomic */ |
182 | RT_TRANSACTION_RELAXED, /* __transaction_relaxed */ |
183 | RT_TRANSACTION_CANCEL, /* __transaction_cancel */ |
184 | |
185 | RT_CO_YIELD /* co_yield */ |
186 | }; |
187 | |
188 | /* RAII wrapper for parser->in_type_id_in_expr_p, setting it on creation and |
189 | reverting it on destruction. */ |
190 | |
191 | class type_id_in_expr_sentinel |
192 | { |
193 | cp_parser *parser; |
194 | bool saved; |
195 | public: |
196 | type_id_in_expr_sentinel (cp_parser *parser, bool set = true) |
197 | : parser (parser), |
198 | saved (parser->in_type_id_in_expr_p) |
199 | { parser->in_type_id_in_expr_p = set; } |
200 | ~type_id_in_expr_sentinel () |
201 | { parser->in_type_id_in_expr_p = saved; } |
202 | }; |
203 | |
204 | /* Prototypes. */ |
205 | |
206 | static cp_lexer *cp_lexer_new_main |
207 | (void); |
208 | static cp_lexer *cp_lexer_new_from_tokens |
209 | (cp_token_cache *tokens); |
210 | static void cp_lexer_destroy |
211 | (cp_lexer *); |
212 | static int cp_lexer_saving_tokens |
213 | (const cp_lexer *); |
214 | static cp_token *cp_lexer_token_at |
215 | (cp_lexer *, cp_token_position); |
216 | static void cp_lexer_get_preprocessor_token |
217 | (unsigned, cp_token *); |
218 | static inline cp_token *cp_lexer_peek_token |
219 | (cp_lexer *); |
220 | static cp_token *cp_lexer_peek_nth_token |
221 | (cp_lexer *, size_t); |
222 | static inline bool cp_lexer_next_token_is |
223 | (cp_lexer *, enum cpp_ttype); |
224 | static bool cp_lexer_next_token_is_not |
225 | (cp_lexer *, enum cpp_ttype); |
226 | static bool cp_lexer_next_token_is_keyword |
227 | (cp_lexer *, enum rid); |
228 | static cp_token *cp_lexer_consume_token |
229 | (cp_lexer *); |
230 | static void cp_lexer_purge_token |
231 | (cp_lexer *); |
232 | static void cp_lexer_purge_tokens_after |
233 | (cp_lexer *, cp_token_position); |
234 | static void cp_lexer_save_tokens |
235 | (cp_lexer *); |
236 | static void cp_lexer_commit_tokens |
237 | (cp_lexer *); |
238 | static void cp_lexer_rollback_tokens |
239 | (cp_lexer *); |
240 | static void cp_lexer_print_token |
241 | (FILE *, cp_token *); |
242 | static inline bool cp_lexer_debugging_p |
243 | (cp_lexer *); |
244 | static void cp_lexer_start_debugging |
245 | (cp_lexer *) ATTRIBUTE_UNUSED__attribute__ ((__unused__)); |
246 | static void cp_lexer_stop_debugging |
247 | (cp_lexer *) ATTRIBUTE_UNUSED__attribute__ ((__unused__)); |
248 | |
249 | static cp_token_cache *cp_token_cache_new |
250 | (cp_token *, cp_token *); |
251 | static tree cp_parser_late_noexcept_specifier |
252 | (cp_parser *, tree); |
253 | static void noexcept_override_late_checks |
254 | (tree, tree); |
255 | |
256 | static void cp_parser_initial_pragma |
257 | (cp_token *); |
258 | |
259 | static bool cp_parser_omp_declare_reduction_exprs |
260 | (tree, cp_parser *); |
261 | static void cp_finalize_oacc_routine |
262 | (cp_parser *, tree, bool); |
263 | |
264 | /* Manifest constants. */ |
265 | #define CP_LEXER_BUFFER_SIZE((256 * 1024) / sizeof (cp_token)) ((256 * 1024) / sizeof (cp_token)) |
266 | #define CP_SAVED_TOKEN_STACK5 5 |
267 | |
268 | /* Variables. */ |
269 | |
270 | /* The stream to which debugging output should be written. */ |
271 | static FILE *cp_lexer_debug_stream; |
272 | |
273 | /* Nonzero if we are parsing an unevaluated operand: an operand to |
274 | sizeof, typeof, or alignof. */ |
275 | int cp_unevaluated_operand; |
276 | |
277 | /* Dump up to NUM tokens in BUFFER to FILE starting with token |
278 | START_TOKEN. If START_TOKEN is NULL, the dump starts with the |
279 | first token in BUFFER. If NUM is 0, dump all the tokens. If |
280 | CURR_TOKEN is set and it is one of the tokens in BUFFER, it will be |
281 | highlighted by surrounding it in [[ ]]. */ |
282 | |
283 | static void |
284 | cp_lexer_dump_tokens (FILE *file, vec<cp_token, va_gc> *buffer, |
285 | cp_token *start_token, unsigned num, |
286 | cp_token *curr_token) |
287 | { |
288 | unsigned i, nprinted; |
289 | cp_token *token; |
290 | bool do_print; |
291 | |
292 | fprintf (file, "%u tokens\n", vec_safe_length (buffer)); |
293 | |
294 | if (buffer == NULL__null) |
295 | return; |
296 | |
297 | if (num == 0) |
298 | num = buffer->length (); |
299 | |
300 | if (start_token == NULL__null) |
301 | start_token = buffer->address (); |
302 | |
303 | if (start_token > buffer->address ()) |
304 | { |
305 | cp_lexer_print_token (file, &(*buffer)[0]); |
306 | fprintf (file, " ... "); |
307 | } |
308 | |
309 | do_print = false; |
310 | nprinted = 0; |
311 | for (i = 0; buffer->iterate (i, &token) && nprinted < num; i++) |
312 | { |
313 | if (token == start_token) |
314 | do_print = true; |
315 | |
316 | if (!do_print) |
317 | continue; |
318 | |
319 | nprinted++; |
320 | if (token == curr_token) |
321 | fprintf (file, "[["); |
322 | |
323 | cp_lexer_print_token (file, token); |
324 | |
325 | if (token == curr_token) |
326 | fprintf (file, "]]"); |
327 | |
328 | switch (token->type) |
329 | { |
330 | case CPP_SEMICOLON: |
331 | case CPP_OPEN_BRACE: |
332 | case CPP_CLOSE_BRACE: |
333 | case CPP_EOF: |
334 | fputc ('\n', file); |
335 | break; |
336 | |
337 | default: |
338 | fputc (' ', file); |
339 | } |
340 | } |
341 | |
342 | if (i == num && i < buffer->length ()) |
343 | { |
344 | fprintf (file, " ... "); |
345 | cp_lexer_print_token (file, &buffer->last ()); |
346 | } |
347 | |
348 | fprintf (file, "\n"); |
349 | } |
350 | |
351 | |
352 | /* Dump all tokens in BUFFER to stderr. */ |
353 | |
354 | void |
355 | cp_lexer_debug_tokens (vec<cp_token, va_gc> *buffer) |
356 | { |
357 | cp_lexer_dump_tokens (stderrstderr, buffer, NULL__null, 0, NULL__null); |
358 | } |
359 | |
360 | DEBUG_FUNCTION__attribute__ ((__used__)) void |
361 | debug (vec<cp_token, va_gc> &ref) |
362 | { |
363 | cp_lexer_dump_tokens (stderrstderr, &ref, NULL__null, 0, NULL__null); |
364 | } |
365 | |
366 | DEBUG_FUNCTION__attribute__ ((__used__)) void |
367 | debug (vec<cp_token, va_gc> *ptr) |
368 | { |
369 | if (ptr) |
370 | debug (*ptr); |
371 | else |
372 | fprintf (stderrstderr, "<nil>\n"); |
373 | } |
374 | |
375 | |
376 | /* Dump the cp_parser tree field T to FILE if T is non-NULL. DESC is the |
377 | description for T. */ |
378 | |
379 | static void |
380 | cp_debug_print_tree_if_set (FILE *file, const char *desc, tree t) |
381 | { |
382 | if (t) |
383 | { |
384 | fprintf (file, "%s: ", desc); |
385 | print_node_brief (file, "", t, 0); |
386 | } |
387 | } |
388 | |
389 | |
390 | /* Dump parser context C to FILE. */ |
391 | |
392 | static void |
393 | cp_debug_print_context (FILE *file, cp_parser_context *c) |
394 | { |
395 | const char *status_s[] = { "OK", "ERROR", "COMMITTED" }; |
396 | fprintf (file, "{ status = %s, scope = ", status_s[c->status]); |
397 | print_node_brief (file, "", c->object_type, 0); |
398 | fprintf (file, "}\n"); |
399 | } |
400 | |
401 | |
402 | /* Print the stack of parsing contexts to FILE starting with FIRST. */ |
403 | |
404 | static void |
405 | cp_debug_print_context_stack (FILE *file, cp_parser_context *first) |
406 | { |
407 | unsigned i; |
408 | cp_parser_context *c; |
409 | |
410 | fprintf (file, "Parsing context stack:\n"); |
411 | for (i = 0, c = first; c; c = c->next, i++) |
412 | { |
413 | fprintf (file, "\t#%u: ", i); |
414 | cp_debug_print_context (file, c); |
415 | } |
416 | } |
417 | |
418 | |
419 | /* Print the value of FLAG to FILE. DESC is a string describing the flag. */ |
420 | |
421 | static void |
422 | cp_debug_print_flag (FILE *file, const char *desc, bool flag) |
423 | { |
424 | if (flag) |
425 | fprintf (file, "%s: true\n", desc); |
426 | } |
427 | |
428 | |
429 | /* Print an unparsed function entry UF to FILE. */ |
430 | |
431 | static void |
432 | cp_debug_print_unparsed_function (FILE *file, cp_unparsed_functions_entry *uf) |
433 | { |
434 | unsigned i; |
435 | cp_default_arg_entry *default_arg_fn; |
436 | tree fn; |
437 | |
438 | fprintf (file, "\tFunctions with default args:\n"); |
439 | for (i = 0; |
440 | vec_safe_iterate (uf->funs_with_default_args, i, &default_arg_fn); |
441 | i++) |
442 | { |
443 | fprintf (file, "\t\tClass type: "); |
444 | print_node_brief (file, "", default_arg_fn->class_type, 0); |
445 | fprintf (file, "\t\tDeclaration: "); |
446 | print_node_brief (file, "", default_arg_fn->decl, 0); |
447 | fprintf (file, "\n"); |
448 | } |
449 | |
450 | fprintf (file, "\n\tFunctions with definitions that require " |
451 | "post-processing\n\t\t"); |
452 | for (i = 0; vec_safe_iterate (uf->funs_with_definitions, i, &fn); i++) |
453 | { |
454 | print_node_brief (file, "", fn, 0); |
455 | fprintf (file, " "); |
456 | } |
457 | fprintf (file, "\n"); |
458 | |
459 | fprintf (file, "\n\tNon-static data members with initializers that require " |
460 | "post-processing\n\t\t"); |
461 | for (i = 0; vec_safe_iterate (uf->nsdmis, i, &fn); i++) |
462 | { |
463 | print_node_brief (file, "", fn, 0); |
464 | fprintf (file, " "); |
465 | } |
466 | fprintf (file, "\n"); |
467 | } |
468 | |
469 | |
470 | /* Print the stack of unparsed member functions S to FILE. */ |
471 | |
472 | static void |
473 | cp_debug_print_unparsed_queues (FILE *file, |
474 | vec<cp_unparsed_functions_entry, va_gc> *s) |
475 | { |
476 | unsigned i; |
477 | cp_unparsed_functions_entry *uf; |
478 | |
479 | fprintf (file, "Unparsed functions\n"); |
480 | for (i = 0; vec_safe_iterate (s, i, &uf); i++) |
481 | { |
482 | fprintf (file, "#%u:\n", i); |
483 | cp_debug_print_unparsed_function (file, uf); |
484 | } |
485 | } |
486 | |
487 | |
488 | /* Dump the tokens in a window of size WINDOW_SIZE around the next_token for |
489 | the given PARSER. If FILE is NULL, the output is printed on stderr. */ |
490 | |
491 | static void |
492 | cp_debug_parser_tokens (FILE *file, cp_parser *parser, int window_size) |
493 | { |
494 | cp_token *next_token, *first_token, *start_token; |
495 | |
496 | if (file == NULL__null) |
497 | file = stderrstderr; |
498 | |
499 | next_token = parser->lexer->next_token; |
500 | first_token = parser->lexer->buffer->address (); |
501 | start_token = (next_token > first_token + window_size / 2) |
502 | ? next_token - window_size / 2 |
503 | : first_token; |
504 | cp_lexer_dump_tokens (file, parser->lexer->buffer, start_token, window_size, |
505 | next_token); |
506 | } |
507 | |
508 | |
509 | /* Dump debugging information for the given PARSER. If FILE is NULL, |
510 | the output is printed on stderr. */ |
511 | |
512 | void |
513 | cp_debug_parser (FILE *file, cp_parser *parser) |
514 | { |
515 | const size_t window_size = 20; |
516 | cp_token *token; |
517 | expanded_location eloc; |
518 | |
519 | if (file == NULL__null) |
520 | file = stderrstderr; |
521 | |
522 | fprintf (file, "Parser state\n\n"); |
523 | fprintf (file, "Number of tokens: %u\n", |
524 | vec_safe_length (parser->lexer->buffer)); |
525 | cp_debug_print_tree_if_set (file, "Lookup scope", parser->scope); |
526 | cp_debug_print_tree_if_set (file, "Object scope", |
527 | parser->object_scope); |
528 | cp_debug_print_tree_if_set (file, "Qualifying scope", |
529 | parser->qualifying_scope); |
530 | cp_debug_print_context_stack (file, parser->context); |
531 | cp_debug_print_flag (file, "Allow GNU extensions", |
532 | parser->allow_gnu_extensions_p); |
533 | cp_debug_print_flag (file, "'>' token is greater-than", |
534 | parser->greater_than_is_operator_p); |
535 | cp_debug_print_flag (file, "Default args allowed in current " |
536 | "parameter list", parser->default_arg_ok_p); |
537 | cp_debug_print_flag (file, "Parsing integral constant-expression", |
538 | parser->integral_constant_expression_p); |
539 | cp_debug_print_flag (file, "Allow non-constant expression in current " |
540 | "constant-expression", |
541 | parser->allow_non_integral_constant_expression_p); |
542 | cp_debug_print_flag (file, "Seen non-constant expression", |
543 | parser->non_integral_constant_expression_p); |
544 | cp_debug_print_flag (file, "Local names forbidden in current context", |
545 | (parser->local_variables_forbidden_p |
546 | & LOCAL_VARS_FORBIDDEN(1 << 0))); |
547 | cp_debug_print_flag (file, "'this' forbidden in current context", |
548 | (parser->local_variables_forbidden_p |
549 | & THIS_FORBIDDEN(1 << 1))); |
550 | cp_debug_print_flag (file, "In unbraced linkage specification", |
551 | parser->in_unbraced_linkage_specification_p); |
552 | cp_debug_print_flag (file, "Parsing a declarator", |
553 | parser->in_declarator_p); |
554 | cp_debug_print_flag (file, "In template argument list", |
555 | parser->in_template_argument_list_p); |
556 | cp_debug_print_flag (file, "Parsing an iteration statement", |
557 | parser->in_statement & IN_ITERATION_STMT2); |
558 | cp_debug_print_flag (file, "Parsing a switch statement", |
559 | parser->in_statement & IN_SWITCH_STMT1); |
560 | cp_debug_print_flag (file, "Parsing a structured OpenMP block", |
561 | parser->in_statement & IN_OMP_BLOCK4); |
562 | cp_debug_print_flag (file, "Parsing an OpenMP loop", |
563 | parser->in_statement & IN_OMP_FOR8); |
564 | cp_debug_print_flag (file, "Parsing an if statement", |
565 | parser->in_statement & IN_IF_STMT16); |
566 | cp_debug_print_flag (file, "Parsing a type-id in an expression " |
567 | "context", parser->in_type_id_in_expr_p); |
568 | cp_debug_print_flag (file, "String expressions should be translated " |
569 | "to execution character set", |
570 | parser->translate_strings_p); |
571 | cp_debug_print_flag (file, "Parsing function body outside of a " |
572 | "local class", parser->in_function_body); |
573 | cp_debug_print_flag (file, "Auto correct a colon to a scope operator", |
574 | parser->colon_corrects_to_scope_p); |
575 | cp_debug_print_flag (file, "Colon doesn't start a class definition", |
576 | parser->colon_doesnt_start_class_def_p); |
577 | cp_debug_print_flag (file, "Parsing an Objective-C++ message context", |
578 | parser->objective_c_message_context_p); |
579 | if (parser->type_definition_forbidden_message) |
580 | fprintf (file, "Error message for forbidden type definitions: %s %s\n", |
581 | parser->type_definition_forbidden_message, |
582 | parser->type_definition_forbidden_message_arg |
583 | ? parser->type_definition_forbidden_message_arg : "<none>"); |
584 | cp_debug_print_unparsed_queues (file, parser->unparsed_queues); |
585 | fprintf (file, "Number of class definitions in progress: %u\n", |
586 | parser->num_classes_being_defined); |
587 | fprintf (file, "Number of template parameter lists for the current " |
588 | "declaration: %u\n", parser->num_template_parameter_lists); |
589 | cp_debug_parser_tokens (file, parser, window_size); |
590 | token = parser->lexer->next_token; |
591 | fprintf (file, "Next token to parse:\n"); |
592 | fprintf (file, "\tToken: "); |
593 | cp_lexer_print_token (file, token); |
594 | eloc = expand_location (token->location); |
595 | fprintf (file, "\n\tFile: %s\n", eloc.file); |
596 | fprintf (file, "\tLine: %d\n", eloc.line); |
597 | fprintf (file, "\tColumn: %d\n", eloc.column); |
598 | } |
599 | |
600 | DEBUG_FUNCTION__attribute__ ((__used__)) void |
601 | debug (cp_parser &ref) |
602 | { |
603 | cp_debug_parser (stderrstderr, &ref); |
604 | } |
605 | |
606 | DEBUG_FUNCTION__attribute__ ((__used__)) void |
607 | debug (cp_parser *ptr) |
608 | { |
609 | if (ptr) |
610 | debug (*ptr); |
611 | else |
612 | fprintf (stderrstderr, "<nil>\n"); |
613 | } |
614 | |
615 | /* Allocate memory for a new lexer object and return it. */ |
616 | |
617 | static cp_lexer * |
618 | cp_lexer_alloc (void) |
619 | { |
620 | /* Allocate the memory. */ |
621 | cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> (); |
622 | |
623 | /* Initially we are not debugging. */ |
624 | lexer->debugging_p = false; |
625 | |
626 | lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK5); |
627 | |
628 | /* Create the buffer. */ |
629 | vec_alloc (lexer->buffer, CP_LEXER_BUFFER_SIZE((256 * 1024) / sizeof (cp_token))); |
630 | |
631 | return lexer; |
632 | } |
633 | |
634 | /* Return TRUE if token is the start of a module declaration that will be |
635 | terminated by a CPP_PRAGMA_EOL token. */ |
636 | static inline bool |
637 | cp_token_is_module_directive (cp_token *token) |
638 | { |
639 | return token->keyword == RID__EXPORT |
640 | || token->keyword == RID__MODULE |
641 | || token->keyword == RID__IMPORT; |
642 | } |
643 | |
644 | /* Return TOKEN's pragma_kind if it is CPP_PRAGMA, otherwise |
645 | PRAGMA_NONE. */ |
646 | |
647 | static enum pragma_kind |
648 | cp_parser_pragma_kind (cp_token *token) |
649 | { |
650 | if (token->type != CPP_PRAGMA) |
651 | return PRAGMA_NONE; |
652 | /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ |
653 | return (enum pragma_kind) TREE_INT_CST_LOW (token->u.value)((unsigned long) (*tree_int_cst_elt_check ((token->u.value ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 653, __FUNCTION__))); |
654 | } |
655 | |
656 | /* Handle early pragmas such as #pragma GCC diagnostic, which needs to be done |
657 | during preprocessing for the case of preprocessing-related diagnostics. This |
658 | is called immediately after pushing the CPP_PRAGMA_EOL token onto |
659 | lexer->buffer. */ |
660 | |
661 | static void |
662 | cp_lexer_handle_early_pragma (cp_lexer *lexer) |
663 | { |
664 | const auto first_token = lexer->buffer->address (); |
665 | const auto last_token = first_token + lexer->buffer->length () - 1; |
666 | |
667 | /* Back up to the start of the pragma so pragma_lex () can parse it when |
668 | c-pragma lib asks it to. */ |
669 | auto begin = last_token; |
670 | gcc_assert (begin->type == CPP_PRAGMA_EOL)((void)(!(begin->type == CPP_PRAGMA_EOL) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 670, __FUNCTION__), 0 : 0)); |
671 | while (begin->type != CPP_PRAGMA) |
672 | { |
673 | if (cp_token_is_module_directive (begin)) |
674 | return; |
675 | gcc_assert (begin != first_token)((void)(!(begin != first_token) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 675, __FUNCTION__), 0 : 0)); |
676 | --begin; |
677 | } |
678 | gcc_assert (!lexer->next_token)((void)(!(!lexer->next_token) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 678, __FUNCTION__), 0 : 0)); |
679 | gcc_assert (!lexer->last_token)((void)(!(!lexer->last_token) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 679, __FUNCTION__), 0 : 0)); |
680 | lexer->next_token = begin; |
681 | lexer->last_token = last_token; |
682 | |
683 | /* Dispatch it. */ |
684 | const unsigned int id |
685 | = cp_parser_pragma_kind (cp_lexer_consume_token (lexer)); |
686 | if (id >= PRAGMA_FIRST_EXTERNAL) |
687 | c_invoke_early_pragma_handler (id); |
688 | |
689 | /* Reset to normal state. */ |
690 | lexer->next_token = lexer->last_token = nullptr; |
691 | } |
692 | |
693 | /* The parser. */ |
694 | static cp_parser *cp_parser_new (cp_lexer *); |
695 | static GTY (()) cp_parser *the_parser; |
696 | |
697 | /* Create a new main C++ lexer, the lexer that gets tokens from the |
698 | preprocessor, and also create the main parser. */ |
699 | |
700 | static cp_lexer * |
701 | cp_lexer_new_main (void) |
702 | { |
703 | cp_token token; |
704 | |
705 | /* It's possible that parsing the first pragma will load a PCH file, |
706 | which is a GC collection point. So we have to do that before |
707 | allocating any memory. */ |
708 | cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN2, &token); |
709 | cp_parser_initial_pragma (&token); |
710 | c_common_no_more_pch (); |
711 | |
712 | cp_lexer *lexer = cp_lexer_alloc (); |
713 | /* Put the first token in the buffer. */ |
714 | cp_token *tok = lexer->buffer->quick_push (token); |
715 | |
716 | uintptr_t filter = 0; |
717 | if (modules_p ()) |
718 | filter = module_token_cdtor (parse_in, filter); |
719 | |
720 | /* Create the parser now, so we can use it to handle early pragmas. */ |
721 | gcc_assert (!the_parser)((void)(!(!the_parser) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 721, __FUNCTION__), 0 : 0)); |
722 | the_parser = cp_parser_new (lexer); |
723 | |
724 | /* Get the remaining tokens from the preprocessor. */ |
725 | while (tok->type != CPP_EOF) |
726 | { |
727 | if (filter) |
728 | /* Process the previous token. */ |
729 | module_token_lang (tok->type, tok->keyword, tok->u.value, |
730 | tok->location, filter); |
731 | |
732 | /* Check for early pragmas that need to be handled now. */ |
733 | if (tok->type == CPP_PRAGMA_EOL) |
734 | cp_lexer_handle_early_pragma (lexer); |
735 | |
736 | tok = vec_safe_push (lexer->buffer, cp_token ()); |
737 | cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN2, tok); |
738 | } |
739 | |
740 | lexer->next_token = lexer->buffer->address (); |
741 | lexer->last_token = lexer->next_token |
742 | + lexer->buffer->length () |
743 | - 1; |
744 | |
745 | if (lexer->buffer->length () != 1) |
746 | { |
747 | /* Set the EOF token's location to be the just after the previous |
748 | token's range. That way 'at-eof' diagnostics point at something |
749 | meaninful. */ |
750 | auto range = get_range_from_loc (line_table, tok[-1].location); |
751 | tok[0].location |
752 | = linemap_position_for_loc_and_offset (line_table, range.m_finish, 1); |
753 | } |
754 | |
755 | if (filter) |
756 | module_token_cdtor (parse_in, filter); |
757 | |
758 | /* Subsequent preprocessor diagnostics should use compiler |
759 | diagnostic functions to get the compiler source location. */ |
760 | override_libcpp_locations = true; |
761 | |
762 | maybe_check_all_macros (parse_in); |
763 | |
764 | gcc_assert (!lexer->next_token->purged_p)((void)(!(!lexer->next_token->purged_p) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 764, __FUNCTION__), 0 : 0)); |
765 | return lexer; |
766 | } |
767 | |
768 | /* Create a new lexer whose token stream is primed with the tokens in |
769 | CACHE. When these tokens are exhausted, no new tokens will be read. */ |
770 | |
771 | static cp_lexer * |
772 | cp_lexer_new_from_tokens (cp_token_cache *cache) |
773 | { |
774 | cp_token *first = cache->first; |
775 | cp_token *last = cache->last; |
776 | cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> (); |
777 | |
778 | /* We do not own the buffer. */ |
779 | lexer->buffer = NULL__null; |
780 | |
781 | /* Insert an EOF token. */ |
782 | lexer->saved_type = last->type; |
783 | lexer->saved_keyword = last->keyword; |
784 | last->type = CPP_EOF; |
785 | last->keyword = RID_MAX; |
786 | |
787 | lexer->next_token = first; |
788 | lexer->last_token = last; |
789 | |
790 | lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK5); |
791 | |
792 | /* Initially we are not debugging. */ |
793 | lexer->debugging_p = false; |
794 | |
795 | gcc_assert (!lexer->next_token->purged_p((void)(!(!lexer->next_token->purged_p && !lexer ->last_token->purged_p) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 796, __FUNCTION__), 0 : 0)) |
796 | && !lexer->last_token->purged_p)((void)(!(!lexer->next_token->purged_p && !lexer ->last_token->purged_p) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 796, __FUNCTION__), 0 : 0)); |
797 | return lexer; |
798 | } |
799 | |
800 | /* Frees all resources associated with LEXER. */ |
801 | |
802 | static void |
803 | cp_lexer_destroy (cp_lexer *lexer) |
804 | { |
805 | if (lexer->buffer) |
806 | vec_free (lexer->buffer); |
807 | else |
808 | { |
809 | /* Restore the token we overwrite with EOF. */ |
810 | lexer->last_token->type = lexer->saved_type; |
811 | lexer->last_token->keyword = lexer->saved_keyword; |
812 | } |
813 | lexer->saved_tokens.release (); |
814 | ggc_free (lexer); |
815 | } |
816 | |
817 | /* This needs to be set to TRUE before the lexer-debugging infrastructure can |
818 | be used. The point of this flag is to help the compiler to fold away calls |
819 | to cp_lexer_debugging_p within this source file at compile time, when the |
820 | lexer is not being debugged. */ |
821 | |
822 | #define LEXER_DEBUGGING_ENABLED_Pfalse false |
823 | |
824 | /* Returns nonzero if debugging information should be output. */ |
825 | |
826 | static inline bool |
827 | cp_lexer_debugging_p (cp_lexer *lexer) |
828 | { |
829 | if (!LEXER_DEBUGGING_ENABLED_Pfalse) |
830 | return false; |
831 | |
832 | return lexer->debugging_p; |
833 | } |
834 | |
835 | |
836 | static inline cp_token_position |
837 | cp_lexer_token_position (cp_lexer *lexer, bool previous_p) |
838 | { |
839 | return lexer->next_token - previous_p; |
840 | } |
841 | |
842 | static inline cp_token * |
843 | cp_lexer_token_at (cp_lexer * /*lexer*/, cp_token_position pos) |
844 | { |
845 | return pos; |
846 | } |
847 | |
848 | static inline void |
849 | cp_lexer_set_token_position (cp_lexer *lexer, cp_token_position pos) |
850 | { |
851 | lexer->next_token = cp_lexer_token_at (lexer, pos); |
852 | } |
853 | |
854 | static inline cp_token_position |
855 | cp_lexer_previous_token_position (cp_lexer *lexer) |
856 | { |
857 | return cp_lexer_token_position (lexer, true); |
858 | } |
859 | |
860 | static inline cp_token * |
861 | cp_lexer_previous_token (cp_lexer *lexer) |
862 | { |
863 | cp_token_position tp = cp_lexer_previous_token_position (lexer); |
864 | |
865 | /* Skip past purged tokens. */ |
866 | while (tp->purged_p) |
867 | { |
868 | gcc_assert (tp != vec_safe_address (lexer->buffer))((void)(!(tp != vec_safe_address (lexer->buffer)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 868, __FUNCTION__), 0 : 0)); |
869 | tp--; |
870 | } |
871 | |
872 | return cp_lexer_token_at (lexer, tp); |
873 | } |
874 | |
875 | /* Same as above, but return NULL when the lexer doesn't own the token |
876 | buffer or if the next_token is at the start of the token |
877 | vector or if all previous tokens are purged. */ |
878 | |
879 | static cp_token * |
880 | cp_lexer_safe_previous_token (cp_lexer *lexer) |
881 | { |
882 | if (lexer->buffer |
883 | && lexer->next_token != lexer->buffer->address ()) |
884 | { |
885 | cp_token_position tp = cp_lexer_previous_token_position (lexer); |
886 | |
887 | /* Skip past purged tokens. */ |
888 | while (tp->purged_p) |
889 | { |
890 | if (tp == lexer->buffer->address ()) |
891 | return NULL__null; |
892 | tp--; |
893 | } |
894 | return cp_lexer_token_at (lexer, tp); |
895 | } |
896 | |
897 | return NULL__null; |
898 | } |
899 | |
900 | /* Overload for make_location, taking the lexer to mean the location of the |
901 | previous token. */ |
902 | |
903 | static inline location_t |
904 | make_location (location_t caret, location_t start, cp_lexer *lexer) |
905 | { |
906 | cp_token *t = cp_lexer_previous_token (lexer); |
907 | return make_location (caret, start, t->location); |
908 | } |
909 | |
910 | /* Overload for make_location taking tokens instead of locations. */ |
911 | |
912 | static inline location_t |
913 | make_location (cp_token *caret, cp_token *start, cp_token *end) |
914 | { |
915 | return make_location (caret->location, start->location, end->location); |
916 | } |
917 | |
918 | /* nonzero if we are presently saving tokens. */ |
919 | |
920 | static inline int |
921 | cp_lexer_saving_tokens (const cp_lexer* lexer) |
922 | { |
923 | return lexer->saved_tokens.length () != 0; |
924 | } |
925 | |
926 | /* Store the next token from the preprocessor in *TOKEN. Return true |
927 | if we reach EOF. If LEXER is NULL, assume we are handling an |
928 | initial #pragma pch_preprocess, and thus want the lexer to return |
929 | processed strings. |
930 | |
931 | Diagnostics issued from this function must have their controlling option (if |
932 | any) in c.opt annotated as a libcpp option via the CppReason property. */ |
933 | |
934 | static void |
935 | cp_lexer_get_preprocessor_token (unsigned flags, cp_token *token) |
936 | { |
937 | static int is_extern_c = 0; |
938 | |
939 | /* Get a new token from the preprocessor. */ |
940 | token->type |
941 | = c_lex_with_flags (&token->u.value, &token->location, &token->flags, |
942 | flags); |
943 | token->keyword = RID_MAX; |
944 | token->purged_p = false; |
945 | token->error_reported = false; |
946 | token->tree_check_p = false; |
947 | /* Usually never see a zero, but just in case ... */ |
948 | token->main_source_p = line_table->depth <= 1; |
949 | |
950 | /* On some systems, some header files are surrounded by an |
951 | implicit extern "C" block. Set a flag in the token if it |
952 | comes from such a header. */ |
953 | is_extern_c += pending_lang_change; |
954 | pending_lang_change = 0; |
955 | token->implicit_extern_c = is_extern_c > 0; |
956 | |
957 | /* Check to see if this token is a keyword. */ |
958 | if (token->type == CPP_NAME) |
959 | { |
960 | if (IDENTIFIER_KEYWORD_P (token->u.value)((!((tree_not_check2 (((tree_check ((token->u.value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 960, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 960, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_2)) & (!((tree_not_check2 (((tree_check ((token ->u.value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 960, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 960, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_1)) & ((tree_not_check2 (((tree_check ((token-> u.value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 960, __FUNCTION__, (IDENTIFIER_NODE)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 960, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits .lang_flag_0))) |
961 | { |
962 | /* Mark this token as a keyword. */ |
963 | token->type = CPP_KEYWORD; |
964 | /* Record which keyword. */ |
965 | token->keyword = C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)); |
966 | } |
967 | else |
968 | { |
969 | if (warn_cxx11_compatglobal_options.x_warn_cxx11_compat |
970 | && ((C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)) >= RID_FIRST_CXX11 |
971 | && C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)) <= RID_LAST_CXX11) |
972 | /* These are outside the CXX11 range. */ |
973 | || C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)) == RID_ALIGNOF |
974 | || C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)) == RID_ALIGNAS |
975 | || C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code))== RID_THREAD)) |
976 | { |
977 | /* Warn about the C++11 keyword (but still treat it as |
978 | an identifier). */ |
979 | warning_at (token->location, OPT_Wc__11_compat, |
980 | "identifier %qE is a keyword in C++11", |
981 | token->u.value); |
982 | |
983 | /* Clear out the C_RID_CODE so we don't warn about this |
984 | particular identifier-turned-keyword again. */ |
985 | C_SET_RID_CODE (token->u.value, RID_MAX)(((struct c_common_identifier *) (token->u.value))->node .rid_code = (unsigned char) RID_MAX); |
986 | } |
987 | if (warn_cxx20_compatglobal_options.x_warn_cxx20_compat |
988 | && C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)) >= RID_FIRST_CXX20 |
989 | && C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)) <= RID_LAST_CXX20) |
990 | { |
991 | /* Warn about the C++20 keyword (but still treat it as |
992 | an identifier). */ |
993 | warning_at (token->location, OPT_Wc__20_compat, |
994 | "identifier %qE is a keyword in C++20", |
995 | token->u.value); |
996 | |
997 | /* Clear out the C_RID_CODE so we don't warn about this |
998 | particular identifier-turned-keyword again. */ |
999 | C_SET_RID_CODE (token->u.value, RID_MAX)(((struct c_common_identifier *) (token->u.value))->node .rid_code = (unsigned char) RID_MAX); |
1000 | } |
1001 | |
1002 | token->keyword = RID_MAX; |
1003 | } |
1004 | } |
1005 | else if (token->type == CPP_AT_NAME) |
1006 | { |
1007 | /* This only happens in Objective-C++; it must be a keyword. */ |
1008 | token->type = CPP_KEYWORD; |
1009 | switch (C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code))) |
1010 | { |
1011 | /* Replace 'class' with '@class', 'private' with '@private', |
1012 | etc. This prevents confusion with the C++ keyword |
1013 | 'class', and makes the tokens consistent with other |
1014 | Objective-C 'AT' keywords. For example '@class' is |
1015 | reported as RID_AT_CLASS which is consistent with |
1016 | '@synchronized', which is reported as |
1017 | RID_AT_SYNCHRONIZED. |
1018 | */ |
1019 | case RID_CLASS: token->keyword = RID_AT_CLASS; break; |
1020 | case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break; |
1021 | case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break; |
1022 | case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break; |
1023 | case RID_THROW: token->keyword = RID_AT_THROW; break; |
1024 | case RID_TRY: token->keyword = RID_AT_TRY; break; |
1025 | case RID_CATCH: token->keyword = RID_AT_CATCH; break; |
1026 | case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break; |
1027 | default: token->keyword = C_RID_CODE (token->u.value)((enum rid) (((struct c_common_identifier *) (token->u.value ))->node.rid_code)); |
1028 | } |
1029 | } |
1030 | } |
1031 | |
1032 | /* Update the globals input_location and the input file stack from TOKEN. */ |
1033 | static inline void |
1034 | cp_lexer_set_source_position_from_token (cp_token *token) |
1035 | { |
1036 | input_location = token->location; |
1037 | } |
1038 | |
1039 | /* Update the globals input_location and the input file stack from LEXER. */ |
1040 | static inline void |
1041 | cp_lexer_set_source_position (cp_lexer *lexer) |
1042 | { |
1043 | cp_token *token = cp_lexer_peek_token (lexer); |
1044 | cp_lexer_set_source_position_from_token (token); |
1045 | } |
1046 | |
1047 | /* Return a pointer to the next token in the token stream, but do not |
1048 | consume it. */ |
1049 | |
1050 | static inline cp_token * |
1051 | cp_lexer_peek_token (cp_lexer *lexer) |
1052 | { |
1053 | if (cp_lexer_debugging_p (lexer)) |
1054 | { |
1055 | fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream); |
1056 | cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token); |
1057 | putc ('\n', cp_lexer_debug_stream); |
1058 | } |
1059 | return lexer->next_token; |
1060 | } |
1061 | |
1062 | /* Return true if the next token has the indicated TYPE. */ |
1063 | |
1064 | static inline bool |
1065 | cp_lexer_next_token_is (cp_lexer* lexer, enum cpp_ttype type) |
1066 | { |
1067 | return cp_lexer_peek_token (lexer)->type == type; |
1068 | } |
1069 | |
1070 | /* Return true if the next token does not have the indicated TYPE. */ |
1071 | |
1072 | static inline bool |
1073 | cp_lexer_next_token_is_not (cp_lexer* lexer, enum cpp_ttype type) |
1074 | { |
1075 | return !cp_lexer_next_token_is (lexer, type); |
1076 | } |
1077 | |
1078 | /* Return true if the next token is the indicated KEYWORD. */ |
1079 | |
1080 | static inline bool |
1081 | cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword) |
1082 | { |
1083 | return cp_lexer_peek_token (lexer)->keyword == keyword; |
1084 | } |
1085 | |
1086 | static inline bool |
1087 | cp_lexer_nth_token_is (cp_lexer* lexer, size_t n, enum cpp_ttype type) |
1088 | { |
1089 | return cp_lexer_peek_nth_token (lexer, n)->type == type; |
1090 | } |
1091 | |
1092 | static inline bool |
1093 | cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword) |
1094 | { |
1095 | return cp_lexer_peek_nth_token (lexer, n)->keyword == keyword; |
1096 | } |
1097 | |
1098 | /* Return true if KEYWORD can start a decl-specifier. */ |
1099 | |
1100 | bool |
1101 | cp_keyword_starts_decl_specifier_p (enum rid keyword) |
1102 | { |
1103 | switch (keyword) |
1104 | { |
1105 | /* auto specifier: storage-class-specifier in C++, |
1106 | simple-type-specifier in C++0x. */ |
1107 | case RID_AUTO: |
1108 | /* Storage classes. */ |
1109 | case RID_REGISTER: |
1110 | case RID_STATIC: |
1111 | case RID_EXTERN: |
1112 | case RID_MUTABLE: |
1113 | case RID_THREAD: |
1114 | /* Elaborated type specifiers. */ |
1115 | case RID_ENUM: |
1116 | case RID_CLASS: |
1117 | case RID_STRUCT: |
1118 | case RID_UNION: |
1119 | case RID_TYPENAME: |
1120 | /* Simple type specifiers. */ |
1121 | case RID_CHAR: |
1122 | case RID_CHAR8: |
1123 | case RID_CHAR16: |
1124 | case RID_CHAR32: |
1125 | case RID_WCHAR: |
1126 | case RID_BOOL: |
1127 | case RID_SHORT: |
1128 | case RID_INT: |
1129 | case RID_LONG: |
1130 | case RID_SIGNED: |
1131 | case RID_UNSIGNED: |
1132 | case RID_FLOAT: |
1133 | case RID_DOUBLE: |
1134 | CASE_RID_FLOATN_NXcase RID_FLOAT16: case RID_FLOAT32: case RID_FLOAT64: case RID_FLOAT128 : case RID_FLOAT32X: case RID_FLOAT64X: case RID_FLOAT128X: |
1135 | case RID_VOID: |
1136 | /* CV qualifiers. */ |
1137 | case RID_CONST: |
1138 | case RID_VOLATILE: |
1139 | /* Function specifiers. */ |
1140 | case RID_EXPLICIT: |
1141 | case RID_VIRTUAL: |
1142 | /* friend/typdef/inline specifiers. */ |
1143 | case RID_FRIEND: |
1144 | case RID_TYPEDEF: |
1145 | case RID_INLINE: |
1146 | /* GNU extensions. */ |
1147 | case RID_TYPEOF: |
1148 | /* C++11 extensions. */ |
1149 | case RID_DECLTYPE: |
1150 | case RID_CONSTEXPR: |
1151 | /* C++20 extensions. */ |
1152 | case RID_CONSTINIT: |
1153 | case RID_CONSTEVAL: |
1154 | return true; |
1155 | |
1156 | #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \ |
1157 | case RID_##CODE: |
1158 | #include "cp-trait.def" |
1159 | #undef DEFTRAIT_TYPE |
1160 | return true; |
1161 | |
1162 | default: |
1163 | if (keyword >= RID_FIRST_INT_N |
1164 | && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS1 |
1165 | && int_n_enabled_p[keyword - RID_FIRST_INT_N]) |
1166 | return true; |
1167 | return false; |
1168 | } |
1169 | } |
1170 | |
1171 | /* Return true if the next token is a keyword for a decl-specifier. */ |
1172 | |
1173 | static bool |
1174 | cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer) |
1175 | { |
1176 | cp_token *token; |
1177 | |
1178 | token = cp_lexer_peek_token (lexer); |
1179 | return cp_keyword_starts_decl_specifier_p (token->keyword); |
1180 | } |
1181 | |
1182 | /* Returns TRUE iff the token T begins a decltype type. */ |
1183 | |
1184 | static bool |
1185 | token_is_decltype (cp_token *t) |
1186 | { |
1187 | return (t->keyword == RID_DECLTYPE |
1188 | || t->type == CPP_DECLTYPE((enum cpp_ttype) (((enum cpp_ttype) (((enum cpp_ttype) (CPP_KEYWORD + 1)) + 1)) + 1))); |
1189 | } |
1190 | |
1191 | /* Returns TRUE iff the next token begins a decltype type. */ |
1192 | |
1193 | static bool |
1194 | cp_lexer_next_token_is_decltype (cp_lexer *lexer) |
1195 | { |
1196 | cp_token *t = cp_lexer_peek_token (lexer); |
1197 | return token_is_decltype (t); |
1198 | } |
1199 | |
1200 | /* Called when processing a token with tree_check_value; perform or defer the |
1201 | associated checks and return the value. */ |
1202 | |
1203 | static tree |
1204 | saved_checks_value (struct tree_check *check_value) |
1205 | { |
1206 | /* Perform any access checks that were deferred. */ |
1207 | vec<deferred_access_check, va_gc> *checks; |
1208 | deferred_access_check *chk; |
1209 | checks = check_value->checks; |
1210 | if (checks) |
1211 | { |
1212 | int i; |
1213 | FOR_EACH_VEC_SAFE_ELT (checks, i, chk)for (i = 0; vec_safe_iterate ((checks), (i), &(chk)); ++( i)) |
1214 | perform_or_defer_access_check (chk->binfo, |
1215 | chk->decl, |
1216 | chk->diag_decl, tf_warning_or_error); |
1217 | } |
1218 | /* Return the stored value. */ |
1219 | return check_value->value; |
1220 | } |
1221 | |
1222 | /* Return a pointer to the Nth token in the token stream. If N is 1, |
1223 | then this is precisely equivalent to cp_lexer_peek_token (except |
1224 | that it is not inline). One would like to disallow that case, but |
1225 | there is one case (cp_parser_nth_token_starts_template_id) where |
1226 | the caller passes a variable for N and it might be 1. */ |
1227 | |
1228 | static cp_token * |
1229 | cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n) |
1230 | { |
1231 | cp_token *token; |
1232 | |
1233 | /* N is 1-based, not zero-based. */ |
1234 | gcc_assert (n > 0)((void)(!(n > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1234, __FUNCTION__), 0 : 0)); |
1235 | |
1236 | if (cp_lexer_debugging_p (lexer)) |
1237 | fprintf (cp_lexer_debug_stream, |
1238 | "cp_lexer: peeking ahead %ld at token: ", (long)n); |
1239 | |
1240 | --n; |
1241 | token = lexer->next_token; |
1242 | while (n && token->type != CPP_EOF) |
1243 | { |
1244 | ++token; |
1245 | if (!token->purged_p) |
1246 | --n; |
1247 | } |
1248 | |
1249 | if (cp_lexer_debugging_p (lexer)) |
1250 | { |
1251 | cp_lexer_print_token (cp_lexer_debug_stream, token); |
1252 | putc ('\n', cp_lexer_debug_stream); |
1253 | } |
1254 | |
1255 | return token; |
1256 | } |
1257 | |
1258 | /* Return the next token, and advance the lexer's next_token pointer |
1259 | to point to the next non-purged token. */ |
1260 | |
1261 | static cp_token * |
1262 | cp_lexer_consume_token (cp_lexer* lexer) |
1263 | { |
1264 | cp_token *token = lexer->next_token; |
1265 | |
1266 | do |
1267 | { |
1268 | gcc_assert (token->type != CPP_EOF)((void)(!(token->type != CPP_EOF) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1268, __FUNCTION__), 0 : 0)); |
1269 | lexer->next_token++; |
1270 | } |
1271 | while (lexer->next_token->purged_p); |
1272 | |
1273 | cp_lexer_set_source_position_from_token (token); |
1274 | |
1275 | /* Provide debugging output. */ |
1276 | if (cp_lexer_debugging_p (lexer)) |
1277 | { |
1278 | fputs ("cp_lexer: consuming token: ", cp_lexer_debug_stream); |
1279 | cp_lexer_print_token (cp_lexer_debug_stream, token); |
1280 | putc ('\n', cp_lexer_debug_stream); |
1281 | } |
1282 | |
1283 | return token; |
1284 | } |
1285 | |
1286 | /* Permanently remove the next token from the token stream, and |
1287 | advance the next_token pointer to refer to the next non-purged |
1288 | token. */ |
1289 | |
1290 | static void |
1291 | cp_lexer_purge_token (cp_lexer *lexer) |
1292 | { |
1293 | cp_token *tok = lexer->next_token; |
1294 | |
1295 | gcc_assert (tok->type != CPP_EOF)((void)(!(tok->type != CPP_EOF) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1295, __FUNCTION__), 0 : 0)); |
1296 | tok->purged_p = true; |
1297 | tok->location = UNKNOWN_LOCATION((location_t) 0); |
1298 | tok->u.value = NULL_TREE(tree) __null; |
1299 | tok->keyword = RID_MAX; |
1300 | |
1301 | do |
1302 | tok++; |
1303 | while (tok->purged_p); |
1304 | lexer->next_token = tok; |
1305 | } |
1306 | |
1307 | /* Permanently remove all tokens after TOK, up to, but not |
1308 | including, the token that will be returned next by |
1309 | cp_lexer_peek_token. */ |
1310 | |
1311 | static void |
1312 | cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok) |
1313 | { |
1314 | cp_token *peek = lexer->next_token; |
1315 | |
1316 | gcc_assert (tok < peek)((void)(!(tok < peek) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1316, __FUNCTION__), 0 : 0)); |
1317 | |
1318 | for (tok++; tok != peek; tok++) |
1319 | { |
1320 | tok->purged_p = true; |
1321 | tok->location = UNKNOWN_LOCATION((location_t) 0); |
1322 | tok->u.value = NULL_TREE(tree) __null; |
1323 | tok->keyword = RID_MAX; |
1324 | } |
1325 | } |
1326 | |
1327 | /* Begin saving tokens. All tokens consumed after this point will be |
1328 | preserved. */ |
1329 | |
1330 | static void |
1331 | cp_lexer_save_tokens (cp_lexer* lexer) |
1332 | { |
1333 | /* Provide debugging output. */ |
1334 | if (cp_lexer_debugging_p (lexer)) |
1335 | fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n"); |
1336 | |
1337 | lexer->saved_tokens.safe_push (lexer->next_token); |
1338 | } |
1339 | |
1340 | /* Commit to the portion of the token stream most recently saved. */ |
1341 | |
1342 | static void |
1343 | cp_lexer_commit_tokens (cp_lexer* lexer) |
1344 | { |
1345 | /* Provide debugging output. */ |
1346 | if (cp_lexer_debugging_p (lexer)) |
1347 | fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n"); |
1348 | |
1349 | lexer->saved_tokens.pop (); |
1350 | } |
1351 | |
1352 | /* Return all tokens saved since the last call to cp_lexer_save_tokens |
1353 | to the token stream. Stop saving tokens. */ |
1354 | |
1355 | static void |
1356 | cp_lexer_rollback_tokens (cp_lexer* lexer) |
1357 | { |
1358 | /* Provide debugging output. */ |
1359 | if (cp_lexer_debugging_p (lexer)) |
1360 | fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n"); |
1361 | |
1362 | lexer->next_token = lexer->saved_tokens.pop (); |
1363 | } |
1364 | |
1365 | /* Determines what saved_token_sentinel does when going out of scope. */ |
1366 | |
1367 | enum saved_token_sentinel_mode { |
1368 | STS_COMMIT, |
1369 | STS_ROLLBACK, |
1370 | STS_DONOTHING |
1371 | }; |
1372 | |
1373 | /* RAII wrapper around the above functions, with sanity checking (the token |
1374 | stream should be the same at the point of instantiation as it is at the |
1375 | point of destruction). |
1376 | |
1377 | Creating a variable saves tokens. MODE determines what happens when the |
1378 | object is destroyed. STS_COMMIT commits tokens (default), |
1379 | STS_ROLLBACK rolls-back and STS_DONOTHING does nothing. Calling |
1380 | rollback() will immediately roll-back tokens and set MODE to |
1381 | STS_DONOTHING. */ |
1382 | |
1383 | struct saved_token_sentinel |
1384 | { |
1385 | cp_lexer *lexer; |
1386 | unsigned len; |
1387 | saved_token_sentinel_mode mode; |
1388 | saved_token_sentinel (cp_lexer *_lexer, |
1389 | saved_token_sentinel_mode _mode = STS_COMMIT) |
1390 | : lexer (_lexer), mode (_mode) |
1391 | { |
1392 | len = lexer->saved_tokens.length (); |
1393 | cp_lexer_save_tokens (lexer); |
1394 | } |
1395 | void rollback () |
1396 | { |
1397 | cp_lexer_rollback_tokens (lexer); |
1398 | cp_lexer_set_source_position_from_token |
1399 | (cp_lexer_previous_token (lexer)); |
1400 | mode = STS_DONOTHING; |
1401 | } |
1402 | ~saved_token_sentinel () |
1403 | { |
1404 | if (mode == STS_COMMIT) |
1405 | cp_lexer_commit_tokens (lexer); |
1406 | else if (mode == STS_ROLLBACK) |
1407 | rollback (); |
1408 | |
1409 | gcc_assert (lexer->saved_tokens.length () == len)((void)(!(lexer->saved_tokens.length () == len) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1409, __FUNCTION__), 0 : 0)); |
1410 | } |
1411 | }; |
1412 | |
1413 | /* Print a representation of the TOKEN on the STREAM. */ |
1414 | |
1415 | static void |
1416 | cp_lexer_print_token (FILE * stream, cp_token *token) |
1417 | { |
1418 | /* We don't use cpp_type2name here because the parser defines |
1419 | a few tokens of its own. */ |
1420 | static const char *const token_names[] = { |
1421 | /* cpplib-defined token types */ |
1422 | #define OP(e, s) #e, |
1423 | #define TK(e, s) #e, |
1424 | TTYPE_TABLEOP(EQ, "=") OP(NOT, "!") OP(GREATER, ">") OP(LESS, "<") OP(PLUS, "+") OP(MINUS, "-") OP(MULT, "*") OP(DIV, "/") OP(MOD , "%") OP(AND, "&") OP(OR, "|") OP(XOR, "^") OP(RSHIFT, ">>" ) OP(LSHIFT, "<<") OP(COMPL, "~") OP(AND_AND, "&&" ) OP(OR_OR, "||") OP(QUERY, "?") OP(COLON, ":") OP(COMMA, "," ) OP(OPEN_PAREN, "(") OP(CLOSE_PAREN, ")") TK((-1), NONE) OP( EQ_EQ, "==") OP(NOT_EQ, "!=") OP(GREATER_EQ, ">=") OP(LESS_EQ , "<=") OP(SPACESHIP, "<=>") OP(PLUS_EQ, "+=") OP(MINUS_EQ , "-=") OP(MULT_EQ, "*=") OP(DIV_EQ, "/=") OP(MOD_EQ, "%=") OP (AND_EQ, "&=") OP(OR_EQ, "|=") OP(XOR_EQ, "^=") OP(RSHIFT_EQ , ">>=") OP(LSHIFT_EQ, "<<=") OP(HASH, "#") OP(PASTE , "##") OP(OPEN_SQUARE, "[") OP(CLOSE_SQUARE, "]") OP(OPEN_BRACE , "{") OP(CLOSE_BRACE, "}") OP(SEMICOLON, ";") OP(ELLIPSIS, "..." ) OP(PLUS_PLUS, "++") OP(MINUS_MINUS, "--") OP(DEREF, "->" ) OP(DOT, ".") OP(SCOPE, "::") OP(DEREF_STAR, "->*") OP(DOT_STAR , ".*") OP(ATSIGN, "@") TK(NAME, IDENT) TK(AT_NAME, IDENT) TK (NUMBER, LITERAL) TK(CHAR, LITERAL) TK(WCHAR, LITERAL) TK(CHAR16 , LITERAL) TK(CHAR32, LITERAL) TK(UTF8CHAR, LITERAL) TK(OTHER , LITERAL) TK(STRING, LITERAL) TK(WSTRING, LITERAL) TK(STRING16 , LITERAL) TK(STRING32, LITERAL) TK(UTF8STRING, LITERAL) TK(OBJC_STRING , LITERAL) TK(HEADER_NAME, LITERAL) TK(CHAR_USERDEF, LITERAL) TK(WCHAR_USERDEF, LITERAL) TK(CHAR16_USERDEF, LITERAL) TK(CHAR32_USERDEF , LITERAL) TK(UTF8CHAR_USERDEF, LITERAL) TK(STRING_USERDEF, LITERAL ) TK(WSTRING_USERDEF, LITERAL) TK(STRING16_USERDEF, LITERAL) TK (STRING32_USERDEF, LITERAL) TK(UTF8STRING_USERDEF,LITERAL) TK (COMMENT, LITERAL) TK(MACRO_ARG, NONE) TK(PRAGMA, NONE) TK(PRAGMA_EOL , NONE) TK(PADDING, NONE) |
1425 | #undef OP |
1426 | #undef TK |
1427 | /* C++ parser token types - see "Manifest constants", above. */ |
1428 | "KEYWORD", |
1429 | "TEMPLATE_ID", |
1430 | "NESTED_NAME_SPECIFIER", |
1431 | }; |
1432 | |
1433 | /* For some tokens, print the associated data. */ |
1434 | switch (token->type) |
1435 | { |
1436 | case CPP_KEYWORD: |
1437 | /* Some keywords have a value that is not an IDENTIFIER_NODE. |
1438 | For example, `struct' is mapped to an INTEGER_CST. */ |
1439 | if (!identifier_p (token->u.value)) |
1440 | break; |
1441 | /* fall through */ |
1442 | case CPP_NAME: |
1443 | fputs (IDENTIFIER_POINTER (token->u.value)((const char *) (tree_check ((token->u.value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1443, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), stream); |
1444 | break; |
1445 | |
1446 | case CPP_STRING: |
1447 | case CPP_STRING16: |
1448 | case CPP_STRING32: |
1449 | case CPP_WSTRING: |
1450 | case CPP_UTF8STRING: |
1451 | fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value)((const char *)((tree_check ((token->u.value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1451, __FUNCTION__, (STRING_CST)))->string.str))); |
1452 | break; |
1453 | |
1454 | case CPP_NUMBER: |
1455 | print_generic_expr (stream, token->u.value); |
1456 | break; |
1457 | |
1458 | default: |
1459 | /* If we have a name for the token, print it out. Otherwise, we |
1460 | simply give the numeric code. */ |
1461 | if (token->type < ARRAY_SIZE(token_names)(sizeof (token_names) / sizeof ((token_names)[0]))) |
1462 | fputs (token_names[token->type], stream); |
1463 | else |
1464 | fprintf (stream, "[%d]", token->type); |
1465 | break; |
1466 | } |
1467 | } |
1468 | |
1469 | DEBUG_FUNCTION__attribute__ ((__used__)) void |
1470 | debug (cp_token &ref) |
1471 | { |
1472 | cp_lexer_print_token (stderrstderr, &ref); |
1473 | fprintf (stderrstderr, "\n"); |
1474 | } |
1475 | |
1476 | DEBUG_FUNCTION__attribute__ ((__used__)) void |
1477 | debug (cp_token *ptr) |
1478 | { |
1479 | if (ptr) |
1480 | debug (*ptr); |
1481 | else |
1482 | fprintf (stderrstderr, "<nil>\n"); |
1483 | } |
1484 | |
1485 | |
1486 | /* Start emitting debugging information. */ |
1487 | |
1488 | static void |
1489 | cp_lexer_start_debugging (cp_lexer* lexer) |
1490 | { |
1491 | if (!LEXER_DEBUGGING_ENABLED_Pfalse) |
1492 | fatal_error (input_location, |
1493 | "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true"); |
1494 | |
1495 | lexer->debugging_p = true; |
1496 | cp_lexer_debug_stream = stderrstderr; |
1497 | } |
1498 | |
1499 | /* Stop emitting debugging information. */ |
1500 | |
1501 | static void |
1502 | cp_lexer_stop_debugging (cp_lexer* lexer) |
1503 | { |
1504 | if (!LEXER_DEBUGGING_ENABLED_Pfalse) |
1505 | fatal_error (input_location, |
1506 | "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true"); |
1507 | |
1508 | lexer->debugging_p = false; |
1509 | cp_lexer_debug_stream = NULL__null; |
1510 | } |
1511 | |
1512 | /* Create a new cp_token_cache, representing a range of tokens. */ |
1513 | |
1514 | static cp_token_cache * |
1515 | cp_token_cache_new (cp_token *first, cp_token *last) |
1516 | { |
1517 | cp_token_cache *cache = ggc_alloc<cp_token_cache> (); |
1518 | cache->first = first; |
1519 | cache->last = last; |
1520 | return cache; |
1521 | } |
1522 | |
1523 | /* Diagnose if #pragma omp declare simd isn't followed immediately |
1524 | by function declaration or definition. */ |
1525 | |
1526 | static inline void |
1527 | cp_ensure_no_omp_declare_simd (cp_parser *parser) |
1528 | { |
1529 | if (parser->omp_declare_simd && !parser->omp_declare_simd->error_seen) |
1530 | { |
1531 | error ("%<#pragma omp declare %s%> not immediately followed by " |
1532 | "function declaration or definition", |
1533 | parser->omp_declare_simd->variant_p ? "variant" : "simd"); |
1534 | parser->omp_declare_simd = NULL__null; |
1535 | } |
1536 | } |
1537 | |
1538 | /* Finalize #pragma omp declare simd clauses after FNDECL has been parsed, |
1539 | and put that into "omp declare simd" attribute. */ |
1540 | |
1541 | static inline void |
1542 | cp_finalize_omp_declare_simd (cp_parser *parser, tree fndecl) |
1543 | { |
1544 | if (UNLIKELY (parser->omp_declare_simd != NULL)(__builtin_expect ((parser->omp_declare_simd != __null), 0 ))) |
1545 | { |
1546 | if (fndecl == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
1547 | { |
1548 | parser->omp_declare_simd = NULL__null; |
1549 | return; |
1550 | } |
1551 | if (TREE_CODE (fndecl)((enum tree_code) (fndecl)->base.code) != FUNCTION_DECL) |
1552 | { |
1553 | cp_ensure_no_omp_declare_simd (parser); |
1554 | return; |
1555 | } |
1556 | } |
1557 | } |
1558 | |
1559 | /* Similarly, but for use in declaration parsing functions |
1560 | which call cp_parser_handle_directive_omp_attributes. */ |
1561 | |
1562 | static inline void |
1563 | cp_finalize_omp_declare_simd (cp_parser *parser, cp_omp_declare_simd_data *data) |
1564 | { |
1565 | if (parser->omp_declare_simd != data) |
1566 | return; |
1567 | |
1568 | if (!parser->omp_declare_simd->error_seen |
1569 | && !parser->omp_declare_simd->fndecl_seen) |
1570 | error_at (parser->omp_declare_simd->loc, |
1571 | "%<declare %s%> directive not immediately followed by " |
1572 | "function declaration or definition", |
1573 | parser->omp_declare_simd->variant_p ? "variant" : "simd"); |
1574 | parser->omp_declare_simd = NULL__null; |
1575 | } |
1576 | |
1577 | /* Diagnose if #pragma acc routine isn't followed immediately by function |
1578 | declaration or definition. */ |
1579 | |
1580 | static inline void |
1581 | cp_ensure_no_oacc_routine (cp_parser *parser) |
1582 | { |
1583 | if (parser->oacc_routine && !parser->oacc_routine->error_seen) |
1584 | { |
1585 | error_at (parser->oacc_routine->loc, |
1586 | "%<#pragma acc routine%> not immediately followed by " |
1587 | "function declaration or definition"); |
1588 | parser->oacc_routine = NULL__null; |
1589 | } |
1590 | } |
1591 | |
1592 | /* Decl-specifiers. */ |
1593 | |
1594 | /* Set *DECL_SPECS to represent an empty decl-specifier-seq. */ |
1595 | |
1596 | static void |
1597 | clear_decl_specs (cp_decl_specifier_seq *decl_specs) |
1598 | { |
1599 | memset (decl_specs, 0, sizeof (cp_decl_specifier_seq)); |
1600 | } |
1601 | |
1602 | /* Declarators. */ |
1603 | |
1604 | /* Nothing other than the parser should be creating declarators; |
1605 | declarators are a semi-syntactic representation of C++ entities. |
1606 | Other parts of the front end that need to create entities (like |
1607 | VAR_DECLs or FUNCTION_DECLs) should do that directly. */ |
1608 | |
1609 | static cp_declarator *make_call_declarator |
1610 | (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier, |
1611 | tree, tree, tree, tree, tree, location_t); |
1612 | static cp_declarator *make_array_declarator |
1613 | (cp_declarator *, tree); |
1614 | static cp_declarator *make_pointer_declarator |
1615 | (cp_cv_quals, cp_declarator *, tree); |
1616 | static cp_declarator *make_reference_declarator |
1617 | (cp_cv_quals, cp_declarator *, bool, tree); |
1618 | static cp_declarator *make_ptrmem_declarator |
1619 | (cp_cv_quals, tree, cp_declarator *, tree); |
1620 | |
1621 | /* An erroneous declarator. */ |
1622 | static cp_declarator *cp_error_declarator; |
1623 | |
1624 | /* The obstack on which declarators and related data structures are |
1625 | allocated. */ |
1626 | static struct obstack declarator_obstack; |
1627 | |
1628 | /* Alloc BYTES from the declarator memory pool. */ |
1629 | |
1630 | static inline void * |
1631 | alloc_declarator (size_t bytes) |
1632 | { |
1633 | return obstack_alloc (&declarator_obstack, bytes)__extension__ ({ struct obstack *__h = (&declarator_obstack ); __extension__ ({ struct obstack *__o = (__h); size_t __len = ((bytes)); if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1->next_free ); }) < __len) _obstack_newchunk (__o, __len); ((void) ((__o )->next_free += (__len))); }); __extension__ ({ struct obstack *__o1 = (__h); void *__value = (void *) __o1->object_base ; if (__o1->next_free == __value) __o1->maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1->object_base) + (((__o1->next_free) - (__o1 ->object_base) + (__o1->alignment_mask)) & ~(__o1-> alignment_mask))) : (char *) (((ptrdiff_t) (__o1->next_free ) + (__o1->alignment_mask)) & ~(__o1->alignment_mask ))); if ((size_t) (__o1->next_free - (char *) __o1->chunk ) > (size_t) (__o1->chunk_limit - (char *) __o1->chunk )) __o1->next_free = __o1->chunk_limit; __o1->object_base = __o1->next_free; __value; }); }); |
1634 | } |
1635 | |
1636 | /* Allocate a declarator of the indicated KIND. Clear fields that are |
1637 | common to all declarators. */ |
1638 | |
1639 | static cp_declarator * |
1640 | make_declarator (cp_declarator_kind kind) |
1641 | { |
1642 | cp_declarator *declarator; |
1643 | |
1644 | declarator = (cp_declarator *) alloc_declarator (sizeof (cp_declarator)); |
1645 | declarator->kind = kind; |
1646 | declarator->parenthesized = UNKNOWN_LOCATION((location_t) 0); |
1647 | declarator->attributes = NULL_TREE(tree) __null; |
1648 | declarator->std_attributes = NULL_TREE(tree) __null; |
1649 | declarator->declarator = NULL__null; |
1650 | declarator->parameter_pack_p = false; |
1651 | declarator->id_loc = UNKNOWN_LOCATION((location_t) 0); |
1652 | declarator->init_loc = UNKNOWN_LOCATION((location_t) 0); |
1653 | |
1654 | return declarator; |
1655 | } |
1656 | |
1657 | /* Make a declarator for a generalized identifier. If |
1658 | QUALIFYING_SCOPE is non-NULL, the identifier is |
1659 | QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just |
1660 | UNQUALIFIED_NAME. SFK indicates the kind of special function this |
1661 | is, if any. */ |
1662 | |
1663 | static cp_declarator * |
1664 | make_id_declarator (tree qualifying_scope, tree unqualified_name, |
1665 | special_function_kind sfk, location_t id_location) |
1666 | { |
1667 | cp_declarator *declarator; |
1668 | |
1669 | /* It is valid to write: |
1670 | |
1671 | class C { void f(); }; |
1672 | typedef C D; |
1673 | void D::f(); |
1674 | |
1675 | The standard is not clear about whether `typedef const C D' is |
1676 | legal; as of 2002-09-15 the committee is considering that |
1677 | question. EDG 3.0 allows that syntax. Therefore, we do as |
1678 | well. */ |
1679 | if (qualifying_scope && TYPE_P (qualifying_scope)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (qualifying_scope)->base.code))] == tcc_type)) |
1680 | qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope)((tree_class_check ((qualifying_scope), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1680, __FUNCTION__))->type_common.main_variant); |
1681 | |
1682 | gcc_assert (identifier_p (unqualified_name)((void)(!(identifier_p (unqualified_name) || ((enum tree_code ) (unqualified_name)->base.code) == BIT_NOT_EXPR || ((enum tree_code) (unqualified_name)->base.code) == TEMPLATE_ID_EXPR ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1684, __FUNCTION__), 0 : 0)) |
1683 | || TREE_CODE (unqualified_name) == BIT_NOT_EXPR((void)(!(identifier_p (unqualified_name) || ((enum tree_code ) (unqualified_name)->base.code) == BIT_NOT_EXPR || ((enum tree_code) (unqualified_name)->base.code) == TEMPLATE_ID_EXPR ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1684, __FUNCTION__), 0 : 0)) |
1684 | || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR)((void)(!(identifier_p (unqualified_name) || ((enum tree_code ) (unqualified_name)->base.code) == BIT_NOT_EXPR || ((enum tree_code) (unqualified_name)->base.code) == TEMPLATE_ID_EXPR ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 1684, __FUNCTION__), 0 : 0)); |
1685 | |
1686 | declarator = make_declarator (cdk_id); |
1687 | declarator->u.id.qualifying_scope = qualifying_scope; |
1688 | declarator->u.id.unqualified_name = unqualified_name; |
1689 | declarator->u.id.sfk = sfk; |
1690 | declarator->id_loc = id_location; |
1691 | |
1692 | return declarator; |
1693 | } |
1694 | |
1695 | /* Make a declarator for a pointer to TARGET. CV_QUALIFIERS is a list |
1696 | of modifiers such as const or volatile to apply to the pointer |
1697 | type, represented as identifiers. ATTRIBUTES represent the attributes that |
1698 | appertain to the pointer or reference. */ |
1699 | |
1700 | cp_declarator * |
1701 | make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target, |
1702 | tree attributes) |
1703 | { |
1704 | cp_declarator *declarator; |
1705 | |
1706 | declarator = make_declarator (cdk_pointer); |
1707 | declarator->declarator = target; |
1708 | declarator->u.pointer.qualifiers = cv_qualifiers; |
1709 | declarator->u.pointer.class_type = NULL_TREE(tree) __null; |
1710 | if (target) |
1711 | { |
1712 | declarator->id_loc = target->id_loc; |
1713 | declarator->parameter_pack_p = target->parameter_pack_p; |
1714 | target->parameter_pack_p = false; |
1715 | } |
1716 | else |
1717 | declarator->parameter_pack_p = false; |
1718 | |
1719 | declarator->std_attributes = attributes; |
1720 | |
1721 | return declarator; |
1722 | } |
1723 | |
1724 | /* Like make_pointer_declarator -- but for references. ATTRIBUTES |
1725 | represent the attributes that appertain to the pointer or |
1726 | reference. */ |
1727 | |
1728 | cp_declarator * |
1729 | make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target, |
1730 | bool rvalue_ref, tree attributes) |
1731 | { |
1732 | cp_declarator *declarator; |
1733 | |
1734 | declarator = make_declarator (cdk_reference); |
1735 | declarator->declarator = target; |
1736 | declarator->u.reference.qualifiers = cv_qualifiers; |
1737 | declarator->u.reference.rvalue_ref = rvalue_ref; |
1738 | if (target) |
1739 | { |
1740 | declarator->id_loc = target->id_loc; |
1741 | declarator->parameter_pack_p = target->parameter_pack_p; |
1742 | target->parameter_pack_p = false; |
1743 | } |
1744 | else |
1745 | declarator->parameter_pack_p = false; |
1746 | |
1747 | declarator->std_attributes = attributes; |
1748 | |
1749 | return declarator; |
1750 | } |
1751 | |
1752 | /* Like make_pointer_declarator -- but for a pointer to a non-static |
1753 | member of CLASS_TYPE. ATTRIBUTES represent the attributes that |
1754 | appertain to the pointer or reference. */ |
1755 | |
1756 | cp_declarator * |
1757 | make_ptrmem_declarator (cp_cv_quals cv_qualifiers, tree class_type, |
1758 | cp_declarator *pointee, |
1759 | tree attributes) |
1760 | { |
1761 | cp_declarator *declarator; |
1762 | |
1763 | declarator = make_declarator (cdk_ptrmem); |
1764 | declarator->declarator = pointee; |
1765 | declarator->u.pointer.qualifiers = cv_qualifiers; |
1766 | declarator->u.pointer.class_type = class_type; |
1767 | |
1768 | if (pointee) |
1769 | { |
1770 | declarator->parameter_pack_p = pointee->parameter_pack_p; |
1771 | pointee->parameter_pack_p = false; |
1772 | } |
1773 | else |
1774 | declarator->parameter_pack_p = false; |
1775 | |
1776 | declarator->std_attributes = attributes; |
1777 | |
1778 | return declarator; |
1779 | } |
1780 | |
1781 | /* Make a declarator for the function given by TARGET, with the |
1782 | indicated PARMS. The CV_QUALIFIERS apply to the function, as in |
1783 | "const"-qualified member function. The EXCEPTION_SPECIFICATION |
1784 | indicates what exceptions can be thrown. STD_ATTRS contains |
1785 | attributes that appertain to the function type. */ |
1786 | |
1787 | cp_declarator * |
1788 | make_call_declarator (cp_declarator *target, |
1789 | tree parms, |
1790 | cp_cv_quals cv_qualifiers, |
1791 | cp_virt_specifiers virt_specifiers, |
1792 | cp_ref_qualifier ref_qualifier, |
1793 | tree tx_qualifier, |
1794 | tree exception_specification, |
1795 | tree late_return_type, |
1796 | tree requires_clause, |
1797 | tree std_attrs, |
1798 | location_t parens_loc) |
1799 | { |
1800 | cp_declarator *declarator; |
1801 | |
1802 | declarator = make_declarator (cdk_function); |
1803 | declarator->declarator = target; |
1804 | declarator->u.function.parameters = parms; |
1805 | declarator->u.function.qualifiers = cv_qualifiers; |
1806 | declarator->u.function.virt_specifiers = virt_specifiers; |
1807 | declarator->u.function.ref_qualifier = ref_qualifier; |
1808 | declarator->u.function.tx_qualifier = tx_qualifier; |
1809 | declarator->u.function.exception_specification = exception_specification; |
1810 | declarator->u.function.late_return_type = late_return_type; |
1811 | declarator->u.function.requires_clause = requires_clause; |
1812 | declarator->u.function.parens_loc = parens_loc; |
1813 | if (target) |
1814 | { |
1815 | declarator->id_loc = target->id_loc; |
1816 | declarator->parameter_pack_p = target->parameter_pack_p; |
1817 | target->parameter_pack_p = false; |
1818 | } |
1819 | else |
1820 | declarator->parameter_pack_p = false; |
1821 | |
1822 | declarator->std_attributes = std_attrs; |
1823 | |
1824 | return declarator; |
1825 | } |
1826 | |
1827 | /* Make a declarator for an array of BOUNDS elements, each of which is |
1828 | defined by ELEMENT. */ |
1829 | |
1830 | cp_declarator * |
1831 | make_array_declarator (cp_declarator *element, tree bounds) |
1832 | { |
1833 | cp_declarator *declarator; |
1834 | |
1835 | declarator = make_declarator (cdk_array); |
1836 | declarator->declarator = element; |
1837 | declarator->u.array.bounds = bounds; |
1838 | if (element) |
1839 | { |
1840 | declarator->id_loc = element->id_loc; |
1841 | declarator->parameter_pack_p = element->parameter_pack_p; |
1842 | element->parameter_pack_p = false; |
1843 | } |
1844 | else |
1845 | declarator->parameter_pack_p = false; |
1846 | |
1847 | return declarator; |
1848 | } |
1849 | |
1850 | /* Determine whether the declarator we've seen so far can be a |
1851 | parameter pack, when followed by an ellipsis. */ |
1852 | static bool |
1853 | declarator_can_be_parameter_pack (cp_declarator *declarator) |
1854 | { |
1855 | if (declarator && declarator->parameter_pack_p) |
1856 | /* We already saw an ellipsis. */ |
1857 | return false; |
1858 | |
1859 | /* Search for a declarator name, or any other declarator that goes |
1860 | after the point where the ellipsis could appear in a parameter |
1861 | pack. If we find any of these, then this declarator cannot be |
1862 | made into a parameter pack. */ |
1863 | bool found = false; |
1864 | while (declarator && !found) |
1865 | { |
1866 | switch ((int)declarator->kind) |
1867 | { |
1868 | case cdk_id: |
1869 | case cdk_array: |
1870 | case cdk_decomp: |
1871 | found = true; |
1872 | break; |
1873 | |
1874 | case cdk_error: |
1875 | return true; |
1876 | |
1877 | default: |
1878 | declarator = declarator->declarator; |
1879 | break; |
1880 | } |
1881 | } |
1882 | |
1883 | return !found; |
1884 | } |
1885 | |
1886 | cp_parameter_declarator *no_parameters; |
1887 | |
1888 | /* Create a parameter declarator with the indicated DECL_SPECIFIERS, |
1889 | DECLARATOR and DEFAULT_ARGUMENT. */ |
1890 | |
1891 | cp_parameter_declarator * |
1892 | make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers, |
1893 | cp_declarator *declarator, |
1894 | tree default_argument, |
1895 | location_t loc, |
1896 | bool template_parameter_pack_p = false) |
1897 | { |
1898 | cp_parameter_declarator *parameter; |
1899 | |
1900 | parameter = ((cp_parameter_declarator *) |
1901 | alloc_declarator (sizeof (cp_parameter_declarator))); |
1902 | parameter->next = NULL__null; |
1903 | if (decl_specifiers) |
1904 | parameter->decl_specifiers = *decl_specifiers; |
1905 | else |
1906 | clear_decl_specs (¶meter->decl_specifiers); |
1907 | parameter->declarator = declarator; |
1908 | parameter->default_argument = default_argument; |
1909 | parameter->template_parameter_pack_p = template_parameter_pack_p; |
1910 | parameter->loc = loc; |
1911 | |
1912 | return parameter; |
1913 | } |
1914 | |
1915 | /* Returns true iff DECLARATOR is a declaration for a function. */ |
1916 | |
1917 | static bool |
1918 | function_declarator_p (const cp_declarator *declarator) |
1919 | { |
1920 | while (declarator) |
1921 | { |
1922 | if (declarator->kind == cdk_function |
1923 | && declarator->declarator->kind == cdk_id) |
1924 | return true; |
1925 | if (declarator->kind == cdk_id |
1926 | || declarator->kind == cdk_decomp |
1927 | || declarator->kind == cdk_error) |
1928 | return false; |
1929 | declarator = declarator->declarator; |
1930 | } |
1931 | return false; |
1932 | } |
1933 | |
1934 | /* The parser. */ |
1935 | |
1936 | /* Overview |
1937 | -------- |
1938 | |
1939 | A cp_parser parses the token stream as specified by the C++ |
1940 | grammar. Its job is purely parsing, not semantic analysis. For |
1941 | example, the parser breaks the token stream into declarators, |
1942 | expressions, statements, and other similar syntactic constructs. |
1943 | It does not check that the types of the expressions on either side |
1944 | of an assignment-statement are compatible, or that a function is |
1945 | not declared with a parameter of type `void'. |
1946 | |
1947 | The parser invokes routines elsewhere in the compiler to perform |
1948 | semantic analysis and to build up the abstract syntax tree for the |
1949 | code processed. |
1950 | |
1951 | The parser (and the template instantiation code, which is, in a |
1952 | way, a close relative of parsing) are the only parts of the |
1953 | compiler that should be calling push_scope and pop_scope, or |
1954 | related functions. The parser (and template instantiation code) |
1955 | keeps track of what scope is presently active; everything else |
1956 | should simply honor that. (The code that generates static |
1957 | initializers may also need to set the scope, in order to check |
1958 | access control correctly when emitting the initializers.) |
1959 | |
1960 | Methodology |
1961 | ----------- |
1962 | |
1963 | The parser is of the standard recursive-descent variety. Upcoming |
1964 | tokens in the token stream are examined in order to determine which |
1965 | production to use when parsing a non-terminal. Some C++ constructs |
1966 | require arbitrary look ahead to disambiguate. For example, it is |
1967 | impossible, in the general case, to tell whether a statement is an |
1968 | expression or declaration without scanning the entire statement. |
1969 | Therefore, the parser is capable of "parsing tentatively." When the |
1970 | parser is not sure what construct comes next, it enters this mode. |
1971 | Then, while we attempt to parse the construct, the parser queues up |
1972 | error messages, rather than issuing them immediately, and saves the |
1973 | tokens it consumes. If the construct is parsed successfully, the |
1974 | parser "commits", i.e., it issues any queued error messages and |
1975 | the tokens that were being preserved are permanently discarded. |
1976 | If, however, the construct is not parsed successfully, the parser |
1977 | rolls back its state completely so that it can resume parsing using |
1978 | a different alternative. |
1979 | |
1980 | Future Improvements |
1981 | ------------------- |
1982 | |
1983 | The performance of the parser could probably be improved substantially. |
1984 | We could often eliminate the need to parse tentatively by looking ahead |
1985 | a little bit. In some places, this approach might not entirely eliminate |
1986 | the need to parse tentatively, but it might still speed up the average |
1987 | case. */ |
1988 | |
1989 | /* Flags that are passed to some parsing functions. These values can |
1990 | be bitwise-ored together. */ |
1991 | |
1992 | enum |
1993 | { |
1994 | /* No flags. */ |
1995 | CP_PARSER_FLAGS_NONE = 0x0, |
1996 | /* The construct is optional. If it is not present, then no error |
1997 | should be issued. */ |
1998 | CP_PARSER_FLAGS_OPTIONAL = 0x1, |
1999 | /* When parsing a type-specifier, treat user-defined type-names |
2000 | as non-type identifiers. */ |
2001 | CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2, |
2002 | /* When parsing a type-specifier, do not try to parse a class-specifier |
2003 | or enum-specifier. */ |
2004 | CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4, |
2005 | /* When parsing a decl-specifier-seq, only allow type-specifier or |
2006 | constexpr. */ |
2007 | CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR = 0x8, |
2008 | /* When parsing a decl-specifier-seq, only allow mutable, constexpr or |
2009 | for C++20 consteval or for C++23 static. */ |
2010 | CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10, |
2011 | /* When parsing a decl-specifier-seq, allow missing typename. */ |
2012 | CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20, |
2013 | /* When parsing of the noexcept-specifier should be delayed. */ |
2014 | CP_PARSER_FLAGS_DELAY_NOEXCEPT = 0x40, |
2015 | /* When parsing a consteval declarator. */ |
2016 | CP_PARSER_FLAGS_CONSTEVAL = 0x80 |
2017 | }; |
2018 | |
2019 | /* This type is used for parameters and variables which hold |
2020 | combinations of the above flags. */ |
2021 | typedef int cp_parser_flags; |
2022 | |
2023 | /* The different kinds of declarators we want to parse. */ |
2024 | |
2025 | enum cp_parser_declarator_kind |
2026 | { |
2027 | /* We want an abstract declarator. */ |
2028 | CP_PARSER_DECLARATOR_ABSTRACT, |
2029 | /* We want a named declarator. */ |
2030 | CP_PARSER_DECLARATOR_NAMED, |
2031 | /* We don't mind, but the name must be an unqualified-id. */ |
2032 | CP_PARSER_DECLARATOR_EITHER |
2033 | }; |
2034 | |
2035 | /* The precedence values used to parse binary expressions. The minimum value |
2036 | of PREC must be 1, because zero is reserved to quickly discriminate |
2037 | binary operators from other tokens. */ |
2038 | |
2039 | enum cp_parser_prec |
2040 | { |
2041 | PREC_NOT_OPERATOR, |
2042 | PREC_LOGICAL_OR_EXPRESSION, |
2043 | PREC_LOGICAL_AND_EXPRESSION, |
2044 | PREC_INCLUSIVE_OR_EXPRESSION, |
2045 | PREC_EXCLUSIVE_OR_EXPRESSION, |
2046 | PREC_AND_EXPRESSION, |
2047 | PREC_EQUALITY_EXPRESSION, |
2048 | PREC_RELATIONAL_EXPRESSION, |
2049 | PREC_SPACESHIP_EXPRESSION, |
2050 | PREC_SHIFT_EXPRESSION, |
2051 | PREC_ADDITIVE_EXPRESSION, |
2052 | PREC_MULTIPLICATIVE_EXPRESSION, |
2053 | PREC_PM_EXPRESSION, |
2054 | NUM_PREC_VALUES = PREC_PM_EXPRESSION |
2055 | }; |
2056 | |
2057 | /* A mapping from a token type to a corresponding tree node type, with a |
2058 | precedence value. */ |
2059 | |
2060 | struct cp_parser_binary_operations_map_node |
2061 | { |
2062 | /* The token type. */ |
2063 | enum cpp_ttype token_type; |
2064 | /* The corresponding tree code. */ |
2065 | enum tree_code tree_type; |
2066 | /* The precedence of this operator. */ |
2067 | enum cp_parser_prec prec; |
2068 | }; |
2069 | |
2070 | struct cp_parser_expression_stack_entry |
2071 | { |
2072 | /* Left hand side of the binary operation we are currently |
2073 | parsing. */ |
2074 | cp_expr lhs; |
2075 | /* Original tree code for left hand side, if it was a binary |
2076 | expression itself (used for -Wparentheses). */ |
2077 | enum tree_code lhs_type; |
2078 | /* Tree code for the binary operation we are parsing. */ |
2079 | enum tree_code tree_type; |
2080 | /* Precedence of the binary operation we are parsing. */ |
2081 | enum cp_parser_prec prec; |
2082 | /* Location of the binary operation we are parsing. */ |
2083 | location_t loc; |
2084 | /* Flags from the operator token. */ |
2085 | unsigned char flags; |
2086 | }; |
2087 | |
2088 | /* The stack for storing partial expressions. We only need NUM_PREC_VALUES |
2089 | entries because precedence levels on the stack are monotonically |
2090 | increasing. */ |
2091 | typedef struct cp_parser_expression_stack_entry |
2092 | cp_parser_expression_stack[NUM_PREC_VALUES]; |
2093 | |
2094 | /* Prototypes. */ |
2095 | |
2096 | /* Constructors and destructors. */ |
2097 | |
2098 | static cp_parser_context *cp_parser_context_new |
2099 | (cp_parser_context *); |
2100 | |
2101 | /* Class variables. */ |
2102 | |
2103 | static GTY((deletable)) cp_parser_context* cp_parser_context_free_list; |
2104 | |
2105 | /* The operator-precedence table used by cp_parser_binary_expression. |
2106 | Transformed into an associative array (binops_by_token) by |
2107 | cp_parser_new. */ |
2108 | |
2109 | static const cp_parser_binary_operations_map_node binops[] = { |
2110 | { CPP_DEREF_STAR, MEMBER_REF, PREC_PM_EXPRESSION }, |
2111 | { CPP_DOT_STAR, DOTSTAR_EXPR, PREC_PM_EXPRESSION }, |
2112 | |
2113 | { CPP_MULT, MULT_EXPR, PREC_MULTIPLICATIVE_EXPRESSION }, |
2114 | { CPP_DIV, TRUNC_DIV_EXPR, PREC_MULTIPLICATIVE_EXPRESSION }, |
2115 | { CPP_MOD, TRUNC_MOD_EXPR, PREC_MULTIPLICATIVE_EXPRESSION }, |
2116 | |
2117 | { CPP_PLUS, PLUS_EXPR, PREC_ADDITIVE_EXPRESSION }, |
2118 | { CPP_MINUS, MINUS_EXPR, PREC_ADDITIVE_EXPRESSION }, |
2119 | |
2120 | { CPP_LSHIFT, LSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, |
2121 | { CPP_RSHIFT, RSHIFT_EXPR, PREC_SHIFT_EXPRESSION }, |
2122 | |
2123 | { CPP_SPACESHIP, SPACESHIP_EXPR, PREC_SPACESHIP_EXPRESSION }, |
2124 | |
2125 | { CPP_LESS, LT_EXPR, PREC_RELATIONAL_EXPRESSION }, |
2126 | { CPP_GREATER, GT_EXPR, PREC_RELATIONAL_EXPRESSION }, |
2127 | { CPP_LESS_EQ, LE_EXPR, PREC_RELATIONAL_EXPRESSION }, |
2128 | { CPP_GREATER_EQ, GE_EXPR, PREC_RELATIONAL_EXPRESSION }, |
2129 | |
2130 | { CPP_EQ_EQ, EQ_EXPR, PREC_EQUALITY_EXPRESSION }, |
2131 | { CPP_NOT_EQ, NE_EXPR, PREC_EQUALITY_EXPRESSION }, |
2132 | |
2133 | { CPP_AND, BIT_AND_EXPR, PREC_AND_EXPRESSION }, |
2134 | |
2135 | { CPP_XOR, BIT_XOR_EXPR, PREC_EXCLUSIVE_OR_EXPRESSION }, |
2136 | |
2137 | { CPP_OR, BIT_IOR_EXPR, PREC_INCLUSIVE_OR_EXPRESSION }, |
2138 | |
2139 | { CPP_AND_AND, TRUTH_ANDIF_EXPR, PREC_LOGICAL_AND_EXPRESSION }, |
2140 | |
2141 | { CPP_OR_OR, TRUTH_ORIF_EXPR, PREC_LOGICAL_OR_EXPRESSION } |
2142 | }; |
2143 | |
2144 | /* The same as binops, but initialized by cp_parser_new so that |
2145 | binops_by_token[N].token_type == N. Used in cp_parser_binary_expression |
2146 | for speed. */ |
2147 | static cp_parser_binary_operations_map_node binops_by_token[N_CP_TTYPES((int) (((enum cpp_ttype) (((enum cpp_ttype) (((enum cpp_ttype ) (((enum cpp_ttype) (CPP_KEYWORD + 1)) + 1)) + 1)) + 1)) + 1 ))]; |
2148 | |
2149 | /* Constructors and destructors. */ |
2150 | |
2151 | /* Construct a new context. The context below this one on the stack |
2152 | is given by NEXT. */ |
2153 | |
2154 | static cp_parser_context * |
2155 | cp_parser_context_new (cp_parser_context* next) |
2156 | { |
2157 | cp_parser_context *context; |
2158 | |
2159 | /* Allocate the storage. */ |
2160 | if (cp_parser_context_free_list != NULL__null) |
2161 | { |
2162 | /* Pull the first entry from the free list. */ |
2163 | context = cp_parser_context_free_list; |
2164 | cp_parser_context_free_list = context->next; |
2165 | memset (context, 0, sizeof (*context)); |
2166 | } |
2167 | else |
2168 | context = ggc_cleared_alloc<cp_parser_context> (); |
2169 | |
2170 | /* No errors have occurred yet in this context. */ |
2171 | context->status = CP_PARSER_STATUS_KIND_NO_ERROR; |
2172 | /* If this is not the bottommost context, copy information that we |
2173 | need from the previous context. */ |
2174 | if (next) |
2175 | { |
2176 | /* If, in the NEXT context, we are parsing an `x->' or `x.' |
2177 | expression, then we are parsing one in this context, too. */ |
2178 | context->object_type = next->object_type; |
2179 | /* Thread the stack. */ |
2180 | context->next = next; |
2181 | } |
2182 | |
2183 | return context; |
2184 | } |
2185 | |
2186 | /* Managing the unparsed function queues. */ |
2187 | |
2188 | #define unparsed_funs_with_default_argsparser->unparsed_queues->last ().funs_with_default_args \ |
2189 | parser->unparsed_queues->last ().funs_with_default_args |
2190 | #define unparsed_funs_with_definitionsparser->unparsed_queues->last ().funs_with_definitions \ |
2191 | parser->unparsed_queues->last ().funs_with_definitions |
2192 | #define unparsed_nsdmisparser->unparsed_queues->last ().nsdmis \ |
2193 | parser->unparsed_queues->last ().nsdmis |
2194 | #define unparsed_noexceptsparser->unparsed_queues->last ().noexcepts \ |
2195 | parser->unparsed_queues->last ().noexcepts |
2196 | #define unparsed_contractsparser->unparsed_queues->last ().contracts \ |
2197 | parser->unparsed_queues->last ().contracts |
2198 | |
2199 | static void |
2200 | push_unparsed_function_queues (cp_parser *parser) |
2201 | { |
2202 | cp_unparsed_functions_entry e |
2203 | = { NULL__null, make_tree_vector (), NULL__null, NULL__null, NULL__null }; |
2204 | vec_safe_push (parser->unparsed_queues, e); |
2205 | } |
2206 | |
2207 | static void |
2208 | pop_unparsed_function_queues (cp_parser *parser) |
2209 | { |
2210 | release_tree_vector (unparsed_funs_with_definitionsparser->unparsed_queues->last ().funs_with_definitions); |
2211 | parser->unparsed_queues->pop (); |
2212 | } |
2213 | |
2214 | /* Prototypes. */ |
2215 | |
2216 | /* Routines to parse various constructs. |
2217 | |
2218 | Those that return `tree' will return the error_mark_node (rather |
2219 | than NULL_TREE) if a parse error occurs, unless otherwise noted. |
2220 | Sometimes, they will return an ordinary node if error-recovery was |
2221 | attempted, even though a parse error occurred. So, to check |
2222 | whether or not a parse error occurred, you should always use |
2223 | cp_parser_error_occurred. If the construct is optional (indicated |
2224 | either by an `_opt' in the name of the function that does the |
2225 | parsing or via a FLAGS parameter), then NULL_TREE is returned if |
2226 | the construct is not present. */ |
2227 | |
2228 | /* Lexical conventions [gram.lex] */ |
2229 | |
2230 | static tree finish_userdef_string_literal |
2231 | (tree); |
2232 | |
2233 | /* Basic concepts [gram.basic] */ |
2234 | |
2235 | static void cp_parser_translation_unit (cp_parser *); |
2236 | |
2237 | /* Expressions [gram.expr] */ |
2238 | |
2239 | static cp_expr cp_parser_primary_expression |
2240 | (cp_parser *, bool, bool, bool, cp_id_kind *); |
2241 | static cp_expr cp_parser_id_expression |
2242 | (cp_parser *, bool, bool, bool *, bool, bool); |
2243 | static cp_expr cp_parser_unqualified_id |
2244 | (cp_parser *, bool, bool, bool, bool); |
2245 | static tree cp_parser_nested_name_specifier_opt |
2246 | (cp_parser *, bool, bool, bool, bool, bool = false); |
2247 | static tree cp_parser_nested_name_specifier |
2248 | (cp_parser *, bool, bool, bool, bool); |
2249 | static tree cp_parser_qualifying_entity |
2250 | (cp_parser *, bool, bool, bool, bool, bool); |
2251 | static cp_expr cp_parser_postfix_expression |
2252 | (cp_parser *, bool, bool, bool, bool, cp_id_kind *); |
2253 | static tree cp_parser_postfix_open_square_expression |
2254 | (cp_parser *, tree, bool, bool); |
2255 | static tree cp_parser_postfix_dot_deref_expression |
2256 | (cp_parser *, enum cpp_ttype, cp_expr, bool, cp_id_kind *, location_t); |
2257 | static vec<tree, va_gc> *cp_parser_parenthesized_expression_list |
2258 | (cp_parser *, int, bool, bool, bool *, location_t * = NULL__null, |
2259 | bool = false); |
2260 | /* Values for the second parameter of cp_parser_parenthesized_expression_list. */ |
2261 | enum { non_attr = 0, normal_attr = 1, id_attr = 2, assume_attr = 3 }; |
2262 | static void cp_parser_pseudo_destructor_name |
2263 | (cp_parser *, tree, tree *, tree *); |
2264 | static cp_expr cp_parser_unary_expression |
2265 | (cp_parser *, cp_id_kind * = NULL__null, bool = false, bool = false, bool = false); |
2266 | static enum tree_code cp_parser_unary_operator |
2267 | (cp_token *); |
2268 | static tree cp_parser_has_attribute_expression |
2269 | (cp_parser *); |
2270 | static tree cp_parser_new_expression |
2271 | (cp_parser *); |
2272 | static vec<tree, va_gc> *cp_parser_new_placement |
2273 | (cp_parser *); |
2274 | static tree cp_parser_new_type_id |
2275 | (cp_parser *, tree *); |
2276 | static cp_declarator *cp_parser_new_declarator_opt |
2277 | (cp_parser *); |
2278 | static cp_declarator *cp_parser_direct_new_declarator |
2279 | (cp_parser *); |
2280 | static vec<tree, va_gc> *cp_parser_new_initializer |
2281 | (cp_parser *); |
2282 | static tree cp_parser_delete_expression |
2283 | (cp_parser *); |
2284 | static cp_expr cp_parser_cast_expression |
2285 | (cp_parser *, bool, bool, bool, cp_id_kind *); |
2286 | static cp_expr cp_parser_binary_expression |
2287 | (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *); |
2288 | static tree cp_parser_question_colon_clause |
2289 | (cp_parser *, cp_expr); |
2290 | static cp_expr cp_parser_conditional_expression (cp_parser *); |
2291 | static cp_expr cp_parser_assignment_expression |
2292 | (cp_parser *, cp_id_kind * = NULL__null, bool = false, bool = false); |
2293 | static enum tree_code cp_parser_assignment_operator_opt |
2294 | (cp_parser *); |
2295 | static cp_expr cp_parser_expression |
2296 | (cp_parser *, cp_id_kind * = NULL__null, bool = false, bool = false, bool = false); |
2297 | static cp_expr cp_parser_constant_expression |
2298 | (cp_parser *, int = 0, bool * = NULL__null, bool = false); |
2299 | static cp_expr cp_parser_builtin_offsetof |
2300 | (cp_parser *); |
2301 | static cp_expr cp_parser_lambda_expression |
2302 | (cp_parser *); |
2303 | static void cp_parser_lambda_introducer |
2304 | (cp_parser *, tree); |
2305 | static bool cp_parser_lambda_declarator_opt |
2306 | (cp_parser *, tree); |
2307 | static void cp_parser_lambda_body |
2308 | (cp_parser *, tree); |
2309 | |
2310 | /* Statements [gram.stmt.stmt] */ |
2311 | |
2312 | static void cp_parser_statement |
2313 | (cp_parser *, tree, bool, bool *, vec<tree> * = NULL__null, location_t * = NULL__null); |
2314 | static void cp_parser_label_for_labeled_statement |
2315 | (cp_parser *, tree); |
2316 | static tree cp_parser_expression_statement |
2317 | (cp_parser *, tree); |
2318 | static tree cp_parser_compound_statement |
2319 | (cp_parser *, tree, int, bool); |
2320 | static void cp_parser_statement_seq_opt |
2321 | (cp_parser *, tree); |
2322 | static tree cp_parser_selection_statement |
2323 | (cp_parser *, bool *, vec<tree> *); |
2324 | static tree cp_parser_condition |
2325 | (cp_parser *); |
2326 | static tree cp_parser_iteration_statement |
2327 | (cp_parser *, bool *, bool, unsigned short); |
2328 | static bool cp_parser_init_statement |
2329 | (cp_parser *, tree *decl); |
2330 | static tree cp_parser_for |
2331 | (cp_parser *, bool, unsigned short); |
2332 | static tree cp_parser_c_for |
2333 | (cp_parser *, tree, tree, bool, unsigned short); |
2334 | static tree cp_parser_range_for |
2335 | (cp_parser *, tree, tree, tree, bool, unsigned short, bool); |
2336 | static void do_range_for_auto_deduction |
2337 | (tree, tree, tree, unsigned int); |
2338 | static tree cp_parser_perform_range_for_lookup |
2339 | (tree, tree *, tree *); |
2340 | static tree cp_parser_range_for_member_function |
2341 | (tree, tree); |
2342 | static tree cp_parser_jump_statement |
2343 | (cp_parser *); |
2344 | static void cp_parser_declaration_statement |
2345 | (cp_parser *); |
2346 | |
2347 | static tree cp_parser_implicitly_scoped_statement |
2348 | (cp_parser *, bool *, const token_indent_info &, vec<tree> * = NULL__null); |
2349 | static void cp_parser_already_scoped_statement |
2350 | (cp_parser *, bool *, const token_indent_info &); |
2351 | |
2352 | /* State of module-declaration parsing. */ |
2353 | enum module_parse |
2354 | { |
2355 | MP_NOT_MODULE, /* Not a module. */ |
2356 | |
2357 | _MP_UNUSED, |
2358 | |
2359 | MP_FIRST, /* First declaration of TU. */ |
2360 | MP_GLOBAL, /* Global Module Fragment. */ |
2361 | |
2362 | MP_PURVIEW_IMPORTS, /* Imports of a module. */ |
2363 | MP_PURVIEW, /* Purview of a named module. */ |
2364 | |
2365 | MP_PRIVATE_IMPORTS, /* Imports of a Private Module Fragment. */ |
2366 | MP_PRIVATE, /* Private Module Fragment. */ |
2367 | }; |
2368 | |
2369 | static module_parse cp_parser_module_declaration |
2370 | (cp_parser *parser, module_parse, bool exporting); |
2371 | static void cp_parser_import_declaration |
2372 | (cp_parser *parser, module_parse, bool exporting); |
2373 | |
2374 | /* Declarations [gram.dcl.dcl] */ |
2375 | |
2376 | static void cp_parser_declaration_seq_opt |
2377 | (cp_parser *); |
2378 | static void cp_parser_declaration |
2379 | (cp_parser *, tree); |
2380 | static void cp_parser_toplevel_declaration |
2381 | (cp_parser *); |
2382 | static void cp_parser_block_declaration |
2383 | (cp_parser *, bool); |
2384 | static void cp_parser_simple_declaration |
2385 | (cp_parser *, bool, tree *); |
2386 | static void cp_parser_decl_specifier_seq |
2387 | (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, int *); |
2388 | static tree cp_parser_storage_class_specifier_opt |
2389 | (cp_parser *); |
2390 | static tree cp_parser_function_specifier_opt |
2391 | (cp_parser *, cp_decl_specifier_seq *); |
2392 | static tree cp_parser_type_specifier |
2393 | (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, bool, |
2394 | int *, bool *); |
2395 | static tree cp_parser_simple_type_specifier |
2396 | (cp_parser *, cp_decl_specifier_seq *, cp_parser_flags); |
2397 | static tree cp_parser_placeholder_type_specifier |
2398 | (cp_parser *, location_t, tree, bool); |
2399 | static tree cp_parser_type_name |
2400 | (cp_parser *, bool); |
2401 | static tree cp_parser_nonclass_name |
2402 | (cp_parser* parser); |
2403 | static tree cp_parser_elaborated_type_specifier |
2404 | (cp_parser *, bool, bool); |
2405 | static tree cp_parser_enum_specifier |
2406 | (cp_parser *); |
2407 | static void cp_parser_enumerator_list |
2408 | (cp_parser *, tree); |
2409 | static void cp_parser_enumerator_definition |
2410 | (cp_parser *, tree); |
2411 | static tree cp_parser_namespace_name |
2412 | (cp_parser *); |
2413 | static void cp_parser_namespace_definition |
2414 | (cp_parser *); |
2415 | static void cp_parser_namespace_body |
2416 | (cp_parser *); |
2417 | static tree cp_parser_qualified_namespace_specifier |
2418 | (cp_parser *); |
2419 | static void cp_parser_namespace_alias_definition |
2420 | (cp_parser *); |
2421 | static bool cp_parser_using_declaration |
2422 | (cp_parser *, bool); |
2423 | static void cp_parser_using_directive |
2424 | (cp_parser *); |
2425 | static void cp_parser_using_enum |
2426 | (cp_parser *); |
2427 | static tree cp_parser_alias_declaration |
2428 | (cp_parser *); |
2429 | static void cp_parser_asm_definition |
2430 | (cp_parser *); |
2431 | static void cp_parser_linkage_specification |
2432 | (cp_parser *, tree); |
2433 | static void cp_parser_static_assert |
2434 | (cp_parser *, bool); |
2435 | static tree cp_parser_decltype |
2436 | (cp_parser *); |
2437 | static tree cp_parser_decomposition_declaration |
2438 | (cp_parser *, cp_decl_specifier_seq *, tree *, location_t *); |
2439 | |
2440 | /* Declarators [gram.dcl.decl] */ |
2441 | |
2442 | static tree cp_parser_init_declarator |
2443 | (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, |
2444 | vec<deferred_access_check, va_gc> *, bool, bool, int, bool *, tree *, |
2445 | location_t *, tree *); |
2446 | static cp_declarator *cp_parser_declarator |
2447 | (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *, |
2448 | bool, bool, bool); |
2449 | static cp_declarator *cp_parser_direct_declarator |
2450 | (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool, |
2451 | bool); |
2452 | static enum tree_code cp_parser_ptr_operator |
2453 | (cp_parser *, tree *, cp_cv_quals *, tree *); |
2454 | static cp_cv_quals cp_parser_cv_qualifier_seq_opt |
2455 | (cp_parser *); |
2456 | static cp_virt_specifiers cp_parser_virt_specifier_seq_opt |
2457 | (cp_parser *); |
2458 | static cp_ref_qualifier cp_parser_ref_qualifier_opt |
2459 | (cp_parser *); |
2460 | static tree cp_parser_tx_qualifier_opt |
2461 | (cp_parser *); |
2462 | static tree cp_parser_late_return_type_opt |
2463 | (cp_parser *, cp_declarator *, tree &); |
2464 | static tree cp_parser_declarator_id |
2465 | (cp_parser *, bool); |
2466 | static tree cp_parser_type_id |
2467 | (cp_parser *, cp_parser_flags = CP_PARSER_FLAGS_NONE, location_t * = NULL__null); |
2468 | static tree cp_parser_template_type_arg |
2469 | (cp_parser *); |
2470 | static tree cp_parser_trailing_type_id (cp_parser *); |
2471 | static tree cp_parser_type_id_1 |
2472 | (cp_parser *, cp_parser_flags, bool, bool, location_t *); |
2473 | static void cp_parser_type_specifier_seq |
2474 | (cp_parser *, cp_parser_flags, bool, bool, cp_decl_specifier_seq *); |
2475 | static tree cp_parser_parameter_declaration_clause |
2476 | (cp_parser *, cp_parser_flags); |
2477 | static tree cp_parser_parameter_declaration_list |
2478 | (cp_parser *, cp_parser_flags, auto_vec<tree> *); |
2479 | static cp_parameter_declarator *cp_parser_parameter_declaration |
2480 | (cp_parser *, cp_parser_flags, bool, bool *); |
2481 | static tree cp_parser_default_argument |
2482 | (cp_parser *, bool); |
2483 | static void cp_parser_function_body |
2484 | (cp_parser *, bool); |
2485 | static tree cp_parser_initializer |
2486 | (cp_parser *, bool *, bool *, bool = false); |
2487 | static cp_expr cp_parser_initializer_clause |
2488 | (cp_parser *, bool *); |
2489 | static cp_expr cp_parser_braced_list |
2490 | (cp_parser*, bool*); |
2491 | static vec<constructor_elt, va_gc> *cp_parser_initializer_list |
2492 | (cp_parser *, bool *, bool *); |
2493 | |
2494 | static void cp_parser_ctor_initializer_opt_and_function_body |
2495 | (cp_parser *, bool); |
2496 | |
2497 | static tree cp_parser_late_parsing_omp_declare_simd |
2498 | (cp_parser *, tree); |
2499 | |
2500 | static tree cp_parser_late_parsing_oacc_routine |
2501 | (cp_parser *, tree); |
2502 | |
2503 | static tree synthesize_implicit_template_parm |
2504 | (cp_parser *, tree); |
2505 | static tree finish_fully_implicit_template |
2506 | (cp_parser *, tree); |
2507 | static void abort_fully_implicit_template |
2508 | (cp_parser *); |
2509 | |
2510 | /* Classes [gram.class] */ |
2511 | |
2512 | static tree cp_parser_class_name |
2513 | (cp_parser *, bool, bool, enum tag_types, bool, bool, bool, bool = false); |
2514 | static tree cp_parser_class_specifier |
2515 | (cp_parser *); |
2516 | static tree cp_parser_class_head |
2517 | (cp_parser *, bool *); |
2518 | static enum tag_types cp_parser_class_key |
2519 | (cp_parser *); |
2520 | static void cp_parser_type_parameter_key |
2521 | (cp_parser* parser); |
2522 | static void cp_parser_member_specification_opt |
2523 | (cp_parser *); |
2524 | static void cp_parser_member_declaration |
2525 | (cp_parser *); |
2526 | static tree cp_parser_pure_specifier |
2527 | (cp_parser *); |
2528 | static tree cp_parser_constant_initializer |
2529 | (cp_parser *); |
2530 | |
2531 | /* Derived classes [gram.class.derived] */ |
2532 | |
2533 | static tree cp_parser_base_clause |
2534 | (cp_parser *); |
2535 | static tree cp_parser_base_specifier |
2536 | (cp_parser *); |
2537 | |
2538 | /* Special member functions [gram.special] */ |
2539 | |
2540 | static tree cp_parser_conversion_function_id |
2541 | (cp_parser *); |
2542 | static tree cp_parser_conversion_type_id |
2543 | (cp_parser *); |
2544 | static cp_declarator *cp_parser_conversion_declarator_opt |
2545 | (cp_parser *); |
2546 | static void cp_parser_ctor_initializer_opt |
2547 | (cp_parser *); |
2548 | static void cp_parser_mem_initializer_list |
2549 | (cp_parser *); |
2550 | static tree cp_parser_mem_initializer |
2551 | (cp_parser *); |
2552 | static tree cp_parser_mem_initializer_id |
2553 | (cp_parser *); |
2554 | |
2555 | /* Overloading [gram.over] */ |
2556 | |
2557 | static cp_expr cp_parser_operator_function_id |
2558 | (cp_parser *); |
2559 | static cp_expr cp_parser_operator |
2560 | (cp_parser *, location_t); |
2561 | |
2562 | /* Templates [gram.temp] */ |
2563 | |
2564 | static void cp_parser_template_declaration |
2565 | (cp_parser *, bool); |
2566 | static tree cp_parser_template_parameter_list |
2567 | (cp_parser *); |
2568 | static tree cp_parser_template_parameter |
2569 | (cp_parser *, bool *, bool *); |
2570 | static tree cp_parser_type_parameter |
2571 | (cp_parser *, bool *); |
2572 | static tree cp_parser_template_id |
2573 | (cp_parser *, bool, bool, enum tag_types, bool); |
2574 | static tree cp_parser_template_id_expr |
2575 | (cp_parser *, bool, bool, bool); |
2576 | static tree cp_parser_template_name |
2577 | (cp_parser *, bool, bool, bool, enum tag_types, bool *); |
2578 | static tree cp_parser_template_argument_list |
2579 | (cp_parser *); |
2580 | static tree cp_parser_template_argument |
2581 | (cp_parser *); |
2582 | static void cp_parser_explicit_instantiation |
2583 | (cp_parser *); |
2584 | static void cp_parser_explicit_specialization |
2585 | (cp_parser *); |
2586 | |
2587 | /* Exception handling [gram.except] */ |
2588 | |
2589 | static tree cp_parser_try_block |
2590 | (cp_parser *); |
2591 | static void cp_parser_function_try_block |
2592 | (cp_parser *); |
2593 | static void cp_parser_handler_seq |
2594 | (cp_parser *); |
2595 | static void cp_parser_handler |
2596 | (cp_parser *); |
2597 | static tree cp_parser_exception_declaration |
2598 | (cp_parser *); |
2599 | static tree cp_parser_throw_expression |
2600 | (cp_parser *); |
2601 | static tree cp_parser_exception_specification_opt |
2602 | (cp_parser *, cp_parser_flags); |
2603 | static tree cp_parser_type_id_list |
2604 | (cp_parser *); |
2605 | static tree cp_parser_noexcept_specification_opt |
2606 | (cp_parser *, cp_parser_flags, bool, bool *, bool); |
2607 | |
2608 | /* GNU Extensions */ |
2609 | |
2610 | static tree cp_parser_asm_specification_opt |
2611 | (cp_parser *); |
2612 | static tree cp_parser_asm_operand_list |
2613 | (cp_parser *); |
2614 | static tree cp_parser_asm_clobber_list |
2615 | (cp_parser *); |
2616 | static tree cp_parser_asm_label_list |
2617 | (cp_parser *); |
2618 | static bool cp_next_tokens_can_be_attribute_p |
2619 | (cp_parser *); |
2620 | static bool cp_next_tokens_can_be_gnu_attribute_p |
2621 | (cp_parser *); |
2622 | static bool cp_next_tokens_can_be_std_attribute_p |
2623 | (cp_parser *); |
2624 | static bool cp_nth_tokens_can_be_std_attribute_p |
2625 | (cp_parser *, size_t); |
2626 | static bool cp_nth_tokens_can_be_gnu_attribute_p |
2627 | (cp_parser *, size_t); |
2628 | static bool cp_nth_tokens_can_be_attribute_p |
2629 | (cp_parser *, size_t); |
2630 | static tree cp_parser_attributes_opt |
2631 | (cp_parser *); |
2632 | static tree cp_parser_gnu_attributes_opt |
2633 | (cp_parser *); |
2634 | static tree cp_parser_gnu_attribute_list |
2635 | (cp_parser *, bool = false); |
2636 | static tree cp_parser_std_attribute |
2637 | (cp_parser *, tree); |
2638 | static tree cp_parser_std_attribute_spec |
2639 | (cp_parser *); |
2640 | static tree cp_parser_std_attribute_spec_seq |
2641 | (cp_parser *); |
2642 | static size_t cp_parser_skip_std_attribute_spec_seq |
2643 | (cp_parser *, size_t); |
2644 | static size_t cp_parser_skip_attributes_opt |
2645 | (cp_parser *, size_t); |
2646 | static bool cp_parser_extension_opt |
2647 | (cp_parser *, int *); |
2648 | static void cp_parser_label_declaration |
2649 | (cp_parser *); |
2650 | |
2651 | /* Concept Extensions */ |
2652 | |
2653 | static tree cp_parser_concept_definition |
2654 | (cp_parser *); |
2655 | static tree cp_parser_constraint_expression |
2656 | (cp_parser *); |
2657 | static tree cp_parser_requires_clause_opt |
2658 | (cp_parser *, bool); |
2659 | static tree cp_parser_requires_expression |
2660 | (cp_parser *); |
2661 | static tree cp_parser_requirement_parameter_list |
2662 | (cp_parser *); |
2663 | static tree cp_parser_requirement_body |
2664 | (cp_parser *); |
2665 | static tree cp_parser_requirement_seq |
2666 | (cp_parser *); |
2667 | static tree cp_parser_requirement |
2668 | (cp_parser *); |
2669 | static tree cp_parser_simple_requirement |
2670 | (cp_parser *); |
2671 | static tree cp_parser_compound_requirement |
2672 | (cp_parser *); |
2673 | static tree cp_parser_type_requirement |
2674 | (cp_parser *); |
2675 | static tree cp_parser_nested_requirement |
2676 | (cp_parser *); |
2677 | |
2678 | /* Transactional Memory Extensions */ |
2679 | |
2680 | static tree cp_parser_transaction |
2681 | (cp_parser *, cp_token *); |
2682 | static tree cp_parser_transaction_expression |
2683 | (cp_parser *, enum rid); |
2684 | static void cp_parser_function_transaction |
2685 | (cp_parser *, enum rid); |
2686 | static tree cp_parser_transaction_cancel |
2687 | (cp_parser *); |
2688 | |
2689 | /* Coroutine extensions. */ |
2690 | |
2691 | static tree cp_parser_yield_expression |
2692 | (cp_parser *); |
2693 | |
2694 | /* Contracts */ |
2695 | |
2696 | static void cp_parser_late_contract_condition |
2697 | (cp_parser *, tree, tree); |
2698 | |
2699 | enum pragma_context { |
2700 | pragma_external, |
2701 | pragma_member, |
2702 | pragma_objc_icode, |
2703 | pragma_stmt, |
2704 | pragma_compound |
2705 | }; |
2706 | static bool cp_parser_pragma |
2707 | (cp_parser *, enum pragma_context, bool *); |
2708 | |
2709 | /* Objective-C++ Productions */ |
2710 | |
2711 | static tree cp_parser_objc_message_receiver |
2712 | (cp_parser *); |
2713 | static tree cp_parser_objc_message_args |
2714 | (cp_parser *); |
2715 | static tree cp_parser_objc_message_expression |
2716 | (cp_parser *); |
2717 | static cp_expr cp_parser_objc_encode_expression |
2718 | (cp_parser *); |
2719 | static tree cp_parser_objc_defs_expression |
2720 | (cp_parser *); |
2721 | static tree cp_parser_objc_protocol_expression |
2722 | (cp_parser *); |
2723 | static tree cp_parser_objc_selector_expression |
2724 | (cp_parser *); |
2725 | static cp_expr cp_parser_objc_expression |
2726 | (cp_parser *); |
2727 | static bool cp_parser_objc_selector_p |
2728 | (enum cpp_ttype); |
2729 | static tree cp_parser_objc_selector |
2730 | (cp_parser *); |
2731 | static tree cp_parser_objc_protocol_refs_opt |
2732 | (cp_parser *); |
2733 | static void cp_parser_objc_declaration |
2734 | (cp_parser *, tree); |
2735 | static tree cp_parser_objc_statement |
2736 | (cp_parser *); |
2737 | static bool cp_parser_objc_valid_prefix_attributes |
2738 | (cp_parser *, tree *); |
2739 | static void cp_parser_objc_at_property_declaration |
2740 | (cp_parser *) ; |
2741 | static void cp_parser_objc_at_synthesize_declaration |
2742 | (cp_parser *) ; |
2743 | static void cp_parser_objc_at_dynamic_declaration |
2744 | (cp_parser *) ; |
2745 | static tree cp_parser_objc_struct_declaration |
2746 | (cp_parser *) ; |
2747 | |
2748 | /* Utility Routines */ |
2749 | |
2750 | static cp_expr cp_parser_lookup_name |
2751 | (cp_parser *, tree, enum tag_types, bool, bool, bool, tree *, location_t); |
2752 | static tree cp_parser_lookup_name_simple |
2753 | (cp_parser *, tree, location_t); |
2754 | static tree cp_parser_maybe_treat_template_as_class |
2755 | (tree, bool); |
2756 | static bool cp_parser_check_declarator_template_parameters |
2757 | (cp_parser *, cp_declarator *, location_t); |
2758 | static bool cp_parser_check_template_parameters |
2759 | (cp_parser *, unsigned, bool, location_t, cp_declarator *); |
2760 | static cp_expr cp_parser_simple_cast_expression |
2761 | (cp_parser *); |
2762 | static tree cp_parser_global_scope_opt |
2763 | (cp_parser *, bool); |
2764 | static bool cp_parser_constructor_declarator_p |
2765 | (cp_parser *, cp_parser_flags, bool); |
2766 | static tree cp_parser_function_definition_from_specifiers_and_declarator |
2767 | (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *); |
2768 | static tree cp_parser_function_definition_after_declarator |
2769 | (cp_parser *, bool); |
2770 | static bool cp_parser_template_declaration_after_export |
2771 | (cp_parser *, bool); |
2772 | static void cp_parser_perform_template_parameter_access_checks |
2773 | (vec<deferred_access_check, va_gc> *); |
2774 | static tree cp_parser_single_declaration |
2775 | (cp_parser *, vec<deferred_access_check, va_gc> *, bool, bool, bool *); |
2776 | static cp_expr cp_parser_functional_cast |
2777 | (cp_parser *, tree); |
2778 | static tree cp_parser_save_member_function_body |
2779 | (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree); |
2780 | static tree cp_parser_save_nsdmi |
2781 | (cp_parser *); |
2782 | static tree cp_parser_enclosed_template_argument_list |
2783 | (cp_parser *); |
2784 | static void cp_parser_save_default_args |
2785 | (cp_parser *, tree); |
2786 | static void cp_parser_late_parsing_for_member |
2787 | (cp_parser *, tree); |
2788 | static tree cp_parser_late_parse_one_default_arg |
2789 | (cp_parser *, tree, tree, tree); |
2790 | static void cp_parser_late_parsing_nsdmi |
2791 | (cp_parser *, tree); |
2792 | static void cp_parser_late_parsing_default_args |
2793 | (cp_parser *, tree); |
2794 | static tree cp_parser_sizeof_operand |
2795 | (cp_parser *, enum rid); |
2796 | static cp_expr cp_parser_trait |
2797 | (cp_parser *, enum rid); |
2798 | static bool cp_parser_declares_only_class_p |
2799 | (cp_parser *); |
2800 | static void cp_parser_set_storage_class |
2801 | (cp_parser *, cp_decl_specifier_seq *, enum rid, cp_token *); |
2802 | static void cp_parser_set_decl_spec_type |
2803 | (cp_decl_specifier_seq *, tree, cp_token *, bool); |
2804 | static void set_and_check_decl_spec_loc |
2805 | (cp_decl_specifier_seq *decl_specs, |
2806 | cp_decl_spec ds, cp_token *); |
2807 | static bool cp_parser_friend_p |
2808 | (const cp_decl_specifier_seq *); |
2809 | static void cp_parser_required_error |
2810 | (cp_parser *, required_token, bool, location_t); |
2811 | static cp_token *cp_parser_require |
2812 | (cp_parser *, enum cpp_ttype, required_token, location_t = UNKNOWN_LOCATION((location_t) 0)); |
2813 | static cp_token *cp_parser_require_keyword |
2814 | (cp_parser *, enum rid, required_token); |
2815 | static bool cp_parser_token_starts_function_definition_p |
2816 | (cp_token *); |
2817 | static bool cp_parser_next_token_starts_class_definition_p |
2818 | (cp_parser *); |
2819 | static bool cp_parser_next_token_ends_template_argument_p |
2820 | (cp_parser *); |
2821 | static bool cp_parser_nth_token_starts_template_argument_list_p |
2822 | (cp_parser *, size_t); |
2823 | static enum tag_types cp_parser_token_is_class_key |
2824 | (cp_token *); |
2825 | static enum tag_types cp_parser_token_is_type_parameter_key |
2826 | (cp_token *); |
2827 | static void cp_parser_maybe_warn_enum_key (cp_parser *, location_t, tree, rid); |
2828 | static void cp_parser_check_class_key |
2829 | (cp_parser *, location_t, enum tag_types, tree type, bool, bool); |
2830 | static void cp_parser_check_access_in_redeclaration |
2831 | (tree type, location_t location); |
2832 | static bool cp_parser_optional_template_keyword |
2833 | (cp_parser *); |
2834 | static void cp_parser_pre_parsed_nested_name_specifier |
2835 | (cp_parser *); |
2836 | static bool cp_parser_cache_group |
2837 | (cp_parser *, enum cpp_ttype, unsigned); |
2838 | static tree cp_parser_cache_defarg |
2839 | (cp_parser *parser, bool nsdmi); |
2840 | static void cp_parser_parse_tentatively |
2841 | (cp_parser *); |
2842 | static void cp_parser_commit_to_tentative_parse |
2843 | (cp_parser *); |
2844 | static void cp_parser_commit_to_topmost_tentative_parse |
2845 | (cp_parser *); |
2846 | static void cp_parser_abort_tentative_parse |
2847 | (cp_parser *); |
2848 | static bool cp_parser_parse_definitely |
2849 | (cp_parser *); |
2850 | static inline bool cp_parser_parsing_tentatively |
2851 | (cp_parser *); |
2852 | static bool cp_parser_uncommitted_to_tentative_parse_p |
2853 | (cp_parser *); |
2854 | static void cp_parser_error |
2855 | (cp_parser *, const char *); |
2856 | static void cp_parser_name_lookup_error |
2857 | (cp_parser *, tree, tree, name_lookup_error, location_t); |
2858 | static bool cp_parser_simulate_error |
2859 | (cp_parser *); |
2860 | static bool cp_parser_check_type_definition |
2861 | (cp_parser *); |
2862 | static void cp_parser_check_for_definition_in_return_type |
2863 | (cp_declarator *, tree, location_t type_location); |
2864 | static void cp_parser_check_for_invalid_template_id |
2865 | (cp_parser *, tree, enum tag_types, location_t location); |
2866 | static bool cp_parser_non_integral_constant_expression |
2867 | (cp_parser *, non_integral_constant); |
2868 | static void cp_parser_diagnose_invalid_type_name |
2869 | (cp_parser *, tree, location_t); |
2870 | static bool cp_parser_parse_and_diagnose_invalid_type_name |
2871 | (cp_parser *); |
2872 | static int cp_parser_skip_to_closing_parenthesis |
2873 | (cp_parser *, bool, bool, bool); |
2874 | static void cp_parser_skip_to_end_of_statement |
2875 | (cp_parser *); |
2876 | static void cp_parser_consume_semicolon_at_end_of_statement |
2877 | (cp_parser *); |
2878 | static void cp_parser_skip_to_end_of_block_or_statement |
2879 | (cp_parser *); |
2880 | static bool cp_parser_skip_to_closing_brace |
2881 | (cp_parser *); |
2882 | static bool cp_parser_skip_entire_template_parameter_list |
2883 | (cp_parser *); |
2884 | static void cp_parser_require_end_of_template_parameter_list |
2885 | (cp_parser *); |
2886 | static bool cp_parser_skip_to_end_of_template_parameter_list |
2887 | (cp_parser *); |
2888 | static void cp_parser_skip_to_pragma_eol |
2889 | (cp_parser*, cp_token *); |
2890 | static bool cp_parser_error_occurred |
2891 | (cp_parser *); |
2892 | static bool cp_parser_allow_gnu_extensions_p |
2893 | (cp_parser *); |
2894 | static bool cp_parser_is_pure_string_literal |
2895 | (cp_token *); |
2896 | static bool cp_parser_is_string_literal |
2897 | (cp_token *); |
2898 | static bool cp_parser_is_keyword |
2899 | (cp_token *, enum rid); |
2900 | static tree cp_parser_make_typename_type |
2901 | (cp_parser *, tree, location_t location); |
2902 | static cp_declarator * cp_parser_make_indirect_declarator |
2903 | (enum tree_code, tree, cp_cv_quals, cp_declarator *, tree); |
2904 | static bool cp_parser_compound_literal_p |
2905 | (cp_parser *); |
2906 | static bool cp_parser_array_designator_p |
2907 | (cp_parser *); |
2908 | static bool cp_parser_init_statement_p |
2909 | (cp_parser *); |
2910 | static bool cp_parser_skip_up_to_closing_square_bracket |
2911 | (cp_parser *); |
2912 | static bool cp_parser_skip_to_closing_square_bracket |
2913 | (cp_parser *); |
2914 | static size_t cp_parser_skip_balanced_tokens (cp_parser *, size_t); |
2915 | |
2916 | // -------------------------------------------------------------------------- // |
2917 | // Unevaluated Operand Guard |
2918 | // |
2919 | // Implementation of an RAII helper for unevaluated operand parsing. |
2920 | cp_unevaluated::cp_unevaluated () |
2921 | { |
2922 | ++cp_unevaluated_operand; |
2923 | ++c_inhibit_evaluation_warnings; |
2924 | } |
2925 | |
2926 | cp_unevaluated::~cp_unevaluated () |
2927 | { |
2928 | --c_inhibit_evaluation_warnings; |
2929 | --cp_unevaluated_operand; |
2930 | } |
2931 | |
2932 | // -------------------------------------------------------------------------- // |
2933 | // Tentative Parsing |
2934 | |
2935 | /* Returns nonzero if we are parsing tentatively. */ |
2936 | |
2937 | static inline bool |
2938 | cp_parser_parsing_tentatively (cp_parser* parser) |
2939 | { |
2940 | return parser->context->next != NULL__null; |
2941 | } |
2942 | |
2943 | /* Returns nonzero if TOKEN is a string literal. */ |
2944 | |
2945 | static bool |
2946 | cp_parser_is_pure_string_literal (cp_token* token) |
2947 | { |
2948 | return (token->type == CPP_STRING || |
2949 | token->type == CPP_STRING16 || |
2950 | token->type == CPP_STRING32 || |
2951 | token->type == CPP_WSTRING || |
2952 | token->type == CPP_UTF8STRING); |
2953 | } |
2954 | |
2955 | /* Returns nonzero if TOKEN is a string literal |
2956 | of a user-defined string literal. */ |
2957 | |
2958 | static bool |
2959 | cp_parser_is_string_literal (cp_token* token) |
2960 | { |
2961 | return (cp_parser_is_pure_string_literal (token) || |
2962 | token->type == CPP_STRING_USERDEF || |
2963 | token->type == CPP_STRING16_USERDEF || |
2964 | token->type == CPP_STRING32_USERDEF || |
2965 | token->type == CPP_WSTRING_USERDEF || |
2966 | token->type == CPP_UTF8STRING_USERDEF); |
2967 | } |
2968 | |
2969 | /* Returns nonzero if TOKEN is the indicated KEYWORD. */ |
2970 | |
2971 | static bool |
2972 | cp_parser_is_keyword (cp_token* token, enum rid keyword) |
2973 | { |
2974 | return token->keyword == keyword; |
2975 | } |
2976 | |
2977 | /* Helper function for cp_parser_error. |
2978 | Having peeked a token of kind TOK1_KIND that might signify |
2979 | a conflict marker, peek successor tokens to determine |
2980 | if we actually do have a conflict marker. |
2981 | Specifically, we consider a run of 7 '<', '=' or '>' characters |
2982 | at the start of a line as a conflict marker. |
2983 | These come through the lexer as three pairs and a single, |
2984 | e.g. three CPP_LSHIFT tokens ("<<") and a CPP_LESS token ('<'). |
2985 | If it returns true, *OUT_LOC is written to with the location/range |
2986 | of the marker. */ |
2987 | |
2988 | static bool |
2989 | cp_lexer_peek_conflict_marker (cp_lexer *lexer, enum cpp_ttype tok1_kind, |
2990 | location_t *out_loc) |
2991 | { |
2992 | cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2); |
2993 | if (token2->type != tok1_kind) |
2994 | return false; |
2995 | cp_token *token3 = cp_lexer_peek_nth_token (lexer, 3); |
2996 | if (token3->type != tok1_kind) |
2997 | return false; |
2998 | cp_token *token4 = cp_lexer_peek_nth_token (lexer, 4); |
2999 | if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind)) |
3000 | return false; |
3001 | |
3002 | /* It must be at the start of the line. */ |
3003 | location_t start_loc = cp_lexer_peek_token (lexer)->location; |
3004 | if (LOCATION_COLUMN (start_loc)((expand_location (start_loc)).column) != 1) |
3005 | return false; |
3006 | |
3007 | /* We have a conflict marker. Construct a location of the form: |
3008 | <<<<<<< |
3009 | ^~~~~~~ |
3010 | with start == caret, finishing at the end of the marker. */ |
3011 | location_t finish_loc = get_finish (token4->location); |
3012 | *out_loc = make_location (start_loc, start_loc, finish_loc); |
3013 | |
3014 | return true; |
3015 | } |
3016 | |
3017 | /* Get a description of the matching symbol to TOKEN_DESC e.g. "(" for |
3018 | RT_CLOSE_PAREN. */ |
3019 | |
3020 | static const char * |
3021 | get_matching_symbol (required_token token_desc) |
3022 | { |
3023 | switch (token_desc) |
3024 | { |
3025 | default: |
3026 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3026, __FUNCTION__)); |
3027 | return ""; |
3028 | case RT_CLOSE_BRACE: |
3029 | return "{"; |
3030 | case RT_CLOSE_PAREN: |
3031 | return "("; |
3032 | } |
3033 | } |
3034 | |
3035 | /* Attempt to convert TOKEN_DESC from a required_token to an |
3036 | enum cpp_ttype, returning CPP_EOF if there is no good conversion. */ |
3037 | |
3038 | static enum cpp_ttype |
3039 | get_required_cpp_ttype (required_token token_desc) |
3040 | { |
3041 | switch (token_desc) |
3042 | { |
3043 | case RT_SEMICOLON: |
3044 | return CPP_SEMICOLON; |
3045 | case RT_OPEN_PAREN: |
3046 | return CPP_OPEN_PAREN; |
3047 | case RT_CLOSE_BRACE: |
3048 | return CPP_CLOSE_BRACE; |
3049 | case RT_OPEN_BRACE: |
3050 | return CPP_OPEN_BRACE; |
3051 | case RT_CLOSE_SQUARE: |
3052 | return CPP_CLOSE_SQUARE; |
3053 | case RT_OPEN_SQUARE: |
3054 | return CPP_OPEN_SQUARE; |
3055 | case RT_COMMA: |
3056 | return CPP_COMMA; |
3057 | case RT_COLON: |
3058 | return CPP_COLON; |
3059 | case RT_CLOSE_PAREN: |
3060 | return CPP_CLOSE_PAREN; |
3061 | |
3062 | default: |
3063 | /* Use CPP_EOF as a "no completions possible" code. */ |
3064 | return CPP_EOF; |
3065 | } |
3066 | } |
3067 | |
3068 | |
3069 | /* Subroutine of cp_parser_error and cp_parser_required_error. |
3070 | |
3071 | Issue a diagnostic of the form |
3072 | FILE:LINE: MESSAGE before TOKEN |
3073 | where TOKEN is the next token in the input stream. MESSAGE |
3074 | (specified by the caller) is usually of the form "expected |
3075 | OTHER-TOKEN". |
3076 | |
3077 | This bypasses the check for tentative passing, and potentially |
3078 | adds material needed by cp_parser_required_error. |
3079 | |
3080 | If MISSING_TOKEN_DESC is not RT_NONE, then potentially add fix-it hints |
3081 | suggesting insertion of the missing token. |
3082 | |
3083 | Additionally, if MATCHING_LOCATION is not UNKNOWN_LOCATION, then we |
3084 | have an unmatched symbol at MATCHING_LOCATION; highlight this secondary |
3085 | location. */ |
3086 | |
3087 | static void |
3088 | cp_parser_error_1 (cp_parser* parser, const char* gmsgid, |
3089 | required_token missing_token_desc, |
3090 | location_t matching_location) |
3091 | { |
3092 | cp_token *token = cp_lexer_peek_token (parser->lexer); |
3093 | /* This diagnostic makes more sense if it is tagged to the line |
3094 | of the token we just peeked at. */ |
3095 | cp_lexer_set_source_position_from_token (token); |
3096 | |
3097 | if (token->type == CPP_PRAGMA) |
3098 | { |
3099 | error_at (token->location, |
3100 | "%<#pragma%> is not allowed here"); |
3101 | cp_parser_skip_to_pragma_eol (parser, token); |
3102 | return; |
3103 | } |
3104 | |
3105 | /* If this is actually a conflict marker, report it as such. */ |
3106 | if (token->type == CPP_LSHIFT |
3107 | || token->type == CPP_RSHIFT |
3108 | || token->type == CPP_EQ_EQ) |
3109 | { |
3110 | location_t loc; |
3111 | if (cp_lexer_peek_conflict_marker (parser->lexer, token->type, &loc)) |
3112 | { |
3113 | error_at (loc, "version control conflict marker in file"); |
3114 | expanded_location token_exploc = expand_location (token->location); |
3115 | /* Consume tokens until the end of the source line. */ |
3116 | for (;;) |
3117 | { |
3118 | cp_lexer_consume_token (parser->lexer); |
3119 | cp_token *next = cp_lexer_peek_token (parser->lexer); |
3120 | if (next->type == CPP_EOF) |
3121 | break; |
3122 | if (next->location == UNKNOWN_LOCATION((location_t) 0) |
3123 | || loc == UNKNOWN_LOCATION((location_t) 0)) |
3124 | break; |
3125 | |
3126 | expanded_location next_exploc = expand_location (next->location); |
3127 | if (next_exploc.file != token_exploc.file) |
3128 | break; |
3129 | if (next_exploc.line != token_exploc.line) |
3130 | break; |
3131 | } |
3132 | return; |
3133 | } |
3134 | } |
3135 | |
3136 | auto_diagnostic_group d; |
3137 | gcc_rich_location richloc (input_location); |
3138 | |
3139 | bool added_matching_location = false; |
3140 | |
3141 | if (missing_token_desc != RT_NONE) |
3142 | if (cp_token *prev_token = cp_lexer_safe_previous_token (parser->lexer)) |
3143 | { |
3144 | /* Potentially supply a fix-it hint, suggesting to add the |
3145 | missing token immediately after the *previous* token. |
3146 | This may move the primary location within richloc. */ |
3147 | enum cpp_ttype ttype = get_required_cpp_ttype (missing_token_desc); |
3148 | location_t prev_token_loc = prev_token->location; |
3149 | maybe_suggest_missing_token_insertion (&richloc, ttype, |
3150 | prev_token_loc); |
3151 | |
3152 | /* If matching_location != UNKNOWN_LOCATION, highlight it. |
3153 | Attempt to consolidate diagnostics by printing it as a |
3154 | secondary range within the main diagnostic. */ |
3155 | if (matching_location != UNKNOWN_LOCATION((location_t) 0)) |
3156 | added_matching_location |
3157 | = richloc.add_location_if_nearby (matching_location); |
3158 | } |
3159 | |
3160 | /* If we were parsing a string-literal and there is an unknown name |
3161 | token right after, then check to see if that could also have been |
3162 | a literal string by checking the name against a list of known |
3163 | standard string literal constants defined in header files. If |
3164 | there is one, then add that as an hint to the error message. */ |
3165 | name_hint h; |
3166 | if (token->type == CPP_NAME) |
3167 | if (cp_token *prev_token = cp_lexer_safe_previous_token (parser->lexer)) |
3168 | if (cp_parser_is_string_literal (prev_token)) |
3169 | { |
3170 | tree name = token->u.value; |
3171 | const char *token_name = IDENTIFIER_POINTER (name)((const char *) (tree_check ((name), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3171, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
3172 | const char *header_hint |
3173 | = get_cp_stdlib_header_for_string_macro_name (token_name); |
3174 | if (header_hint != NULL__null) |
3175 | h = name_hint (NULL__null, new suggest_missing_header (token->location, |
3176 | token_name, |
3177 | header_hint)); |
3178 | } |
3179 | |
3180 | /* Actually emit the error. */ |
3181 | c_parse_error (gmsgid, |
3182 | /* Because c_parser_error does not understand |
3183 | CPP_KEYWORD, keywords are treated like |
3184 | identifiers. */ |
3185 | (token->type == CPP_KEYWORD ? CPP_NAME : token->type), |
3186 | token->u.value, token->flags, &richloc); |
3187 | |
3188 | if (missing_token_desc != RT_NONE) |
3189 | { |
3190 | /* If we weren't able to consolidate matching_location, then |
3191 | print it as a secondary diagnostic. */ |
3192 | if (matching_location != UNKNOWN_LOCATION((location_t) 0) |
3193 | && !added_matching_location) |
3194 | inform (matching_location, "to match this %qs", |
3195 | get_matching_symbol (missing_token_desc)); |
3196 | } |
3197 | } |
3198 | |
3199 | /* If not parsing tentatively, issue a diagnostic of the form |
3200 | FILE:LINE: MESSAGE before TOKEN |
3201 | where TOKEN is the next token in the input stream. MESSAGE |
3202 | (specified by the caller) is usually of the form "expected |
3203 | OTHER-TOKEN". */ |
3204 | |
3205 | static void |
3206 | cp_parser_error (cp_parser* parser, const char* gmsgid) |
3207 | { |
3208 | if (!cp_parser_simulate_error (parser)) |
3209 | cp_parser_error_1 (parser, gmsgid, RT_NONE, UNKNOWN_LOCATION((location_t) 0)); |
3210 | } |
3211 | |
3212 | /* Issue an error about name-lookup failing. NAME is the |
3213 | IDENTIFIER_NODE DECL is the result of |
3214 | the lookup (as returned from cp_parser_lookup_name). DESIRED is |
3215 | the thing that we hoped to find. */ |
3216 | |
3217 | static void |
3218 | cp_parser_name_lookup_error (cp_parser* parser, |
3219 | tree name, |
3220 | tree decl, |
3221 | name_lookup_error desired, |
3222 | location_t location) |
3223 | { |
3224 | /* If name lookup completely failed, tell the user that NAME was not |
3225 | declared. */ |
3226 | if (decl == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
3227 | { |
3228 | if (parser->scope && parser->scope != global_namespacecp_global_trees[CPTI_GLOBAL]) |
3229 | error_at (location, "%<%E::%E%> has not been declared", |
3230 | parser->scope, name); |
3231 | else if (parser->scope == global_namespacecp_global_trees[CPTI_GLOBAL]) |
3232 | error_at (location, "%<::%E%> has not been declared", name); |
3233 | else if (parser->object_scope |
3234 | && !CLASS_TYPE_P (parser->object_scope)(((((enum tree_code) (parser->object_scope)->base.code) ) == RECORD_TYPE || (((enum tree_code) (parser->object_scope )->base.code)) == UNION_TYPE) && ((tree_class_check ((parser->object_scope), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3234, __FUNCTION__))->type_common.lang_flag_5))) |
3235 | error_at (location, "request for member %qE in non-class type %qT", |
3236 | name, parser->object_scope); |
3237 | else if (parser->object_scope) |
3238 | error_at (location, "%<%T::%E%> has not been declared", |
3239 | parser->object_scope, name); |
3240 | else |
3241 | error_at (location, "%qE has not been declared", name); |
3242 | } |
3243 | else if (parser->scope && parser->scope != global_namespacecp_global_trees[CPTI_GLOBAL]) |
3244 | { |
3245 | switch (desired) |
3246 | { |
3247 | case NLE_TYPE: |
3248 | error_at (location, "%<%E::%E%> is not a type", |
3249 | parser->scope, name); |
3250 | break; |
3251 | case NLE_CXX98: |
3252 | error_at (location, "%<%E::%E%> is not a class or namespace", |
3253 | parser->scope, name); |
3254 | break; |
3255 | case NLE_NOT_CXX98: |
3256 | error_at (location, |
3257 | "%<%E::%E%> is not a class, namespace, or enumeration", |
3258 | parser->scope, name); |
3259 | break; |
3260 | default: |
3261 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3261, __FUNCTION__)); |
3262 | |
3263 | } |
3264 | } |
3265 | else if (parser->scope == global_namespacecp_global_trees[CPTI_GLOBAL]) |
3266 | { |
3267 | switch (desired) |
3268 | { |
3269 | case NLE_TYPE: |
3270 | error_at (location, "%<::%E%> is not a type", name); |
3271 | break; |
3272 | case NLE_CXX98: |
3273 | error_at (location, "%<::%E%> is not a class or namespace", name); |
3274 | break; |
3275 | case NLE_NOT_CXX98: |
3276 | error_at (location, |
3277 | "%<::%E%> is not a class, namespace, or enumeration", |
3278 | name); |
3279 | break; |
3280 | default: |
3281 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3281, __FUNCTION__)); |
3282 | } |
3283 | } |
3284 | else |
3285 | { |
3286 | switch (desired) |
3287 | { |
3288 | case NLE_TYPE: |
3289 | error_at (location, "%qE is not a type", name); |
3290 | break; |
3291 | case NLE_CXX98: |
3292 | error_at (location, "%qE is not a class or namespace", name); |
3293 | break; |
3294 | case NLE_NOT_CXX98: |
3295 | error_at (location, |
3296 | "%qE is not a class, namespace, or enumeration", name); |
3297 | break; |
3298 | default: |
3299 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3299, __FUNCTION__)); |
3300 | } |
3301 | } |
3302 | } |
3303 | |
3304 | /* If we are parsing tentatively, remember that an error has occurred |
3305 | during this tentative parse. Returns true if the error was |
3306 | simulated; false if a message should be issued by the caller. */ |
3307 | |
3308 | static bool |
3309 | cp_parser_simulate_error (cp_parser* parser) |
3310 | { |
3311 | if (cp_parser_uncommitted_to_tentative_parse_p (parser)) |
3312 | { |
3313 | parser->context->status = CP_PARSER_STATUS_KIND_ERROR; |
3314 | return true; |
3315 | } |
3316 | return false; |
3317 | } |
3318 | |
3319 | /* This function is called when a type is defined. If type |
3320 | definitions are forbidden at this point, an error message is |
3321 | issued. */ |
3322 | |
3323 | static bool |
3324 | cp_parser_check_type_definition (cp_parser* parser) |
3325 | { |
3326 | /* If types are forbidden here, issue a message. */ |
3327 | if (parser->type_definition_forbidden_message) |
3328 | { |
3329 | /* Don't use `%s' to print the string, because quotations (`%<', `%>') |
3330 | or %qs in the message need to be interpreted. */ |
3331 | error (parser->type_definition_forbidden_message, |
3332 | parser->type_definition_forbidden_message_arg); |
3333 | return false; |
3334 | } |
3335 | return true; |
3336 | } |
3337 | |
3338 | /* This function is called when the DECLARATOR is processed. The TYPE |
3339 | was a type defined in the decl-specifiers. If it is invalid to |
3340 | define a type in the decl-specifiers for DECLARATOR, an error is |
3341 | issued. TYPE_LOCATION is the location of TYPE and is used |
3342 | for error reporting. */ |
3343 | |
3344 | static void |
3345 | cp_parser_check_for_definition_in_return_type (cp_declarator *declarator, |
3346 | tree type, location_t type_location) |
3347 | { |
3348 | /* [dcl.fct] forbids type definitions in return types. |
3349 | Unfortunately, it's not easy to know whether or not we are |
3350 | processing a return type until after the fact. */ |
3351 | while (declarator |
3352 | && (declarator->kind == cdk_pointer |
3353 | || declarator->kind == cdk_reference |
3354 | || declarator->kind == cdk_ptrmem)) |
3355 | declarator = declarator->declarator; |
3356 | if (declarator |
3357 | && declarator->kind == cdk_function) |
3358 | { |
3359 | error_at (type_location, |
3360 | "new types may not be defined in a return type"); |
3361 | inform (type_location, |
3362 | "(perhaps a semicolon is missing after the definition of %qT)", |
3363 | type); |
3364 | } |
3365 | } |
3366 | |
3367 | /* A type-specifier (TYPE) has been parsed which cannot be followed by |
3368 | "<" in any valid C++ program. If the next token is indeed "<", |
3369 | issue a message warning the user about what appears to be an |
3370 | invalid attempt to form a template-id. LOCATION is the location |
3371 | of the type-specifier (TYPE) */ |
3372 | |
3373 | static void |
3374 | cp_parser_check_for_invalid_template_id (cp_parser* parser, |
3375 | tree type, |
3376 | enum tag_types tag_type, |
3377 | location_t location) |
3378 | { |
3379 | cp_token_position start = 0; |
3380 | |
3381 | if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) |
3382 | { |
3383 | if (TREE_CODE (type)((enum tree_code) (type)->base.code) == TYPE_DECL) |
3384 | type = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3384, __FUNCTION__))->typed.type); |
3385 | if (TYPE_P (type)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (type)->base.code))] == tcc_type) && !template_placeholder_p (type)) |
3386 | error_at (location, "%qT is not a template", type); |
3387 | else if (identifier_p (type)) |
3388 | { |
3389 | if (tag_type != none_type) |
3390 | error_at (location, "%qE is not a class template", type); |
3391 | else |
3392 | error_at (location, "%qE is not a template", type); |
3393 | } |
3394 | else |
3395 | error_at (location, "invalid template-id"); |
3396 | /* Remember the location of the invalid "<". */ |
3397 | if (cp_parser_uncommitted_to_tentative_parse_p (parser)) |
3398 | start = cp_lexer_token_position (parser->lexer, true); |
3399 | /* Consume the "<". */ |
3400 | cp_lexer_consume_token (parser->lexer); |
3401 | /* Parse the template arguments. */ |
3402 | cp_parser_enclosed_template_argument_list (parser); |
3403 | /* Permanently remove the invalid template arguments so that |
3404 | this error message is not issued again. */ |
3405 | if (start) |
3406 | cp_lexer_purge_tokens_after (parser->lexer, start); |
3407 | } |
3408 | } |
3409 | |
3410 | /* If parsing an integral constant-expression, issue an error message |
3411 | about the fact that THING appeared and return true. Otherwise, |
3412 | return false. In either case, set |
3413 | PARSER->NON_INTEGRAL_CONSTANT_EXPRESSION_P. */ |
3414 | |
3415 | static bool |
3416 | cp_parser_non_integral_constant_expression (cp_parser *parser, |
3417 | non_integral_constant thing) |
3418 | { |
3419 | parser->non_integral_constant_expression_p = true; |
3420 | if (parser->integral_constant_expression_p) |
3421 | { |
3422 | if (!parser->allow_non_integral_constant_expression_p) |
3423 | { |
3424 | const char *msg = NULL__null; |
3425 | switch (thing) |
3426 | { |
3427 | case NIC_FLOAT: |
3428 | pedwarn (input_location, OPT_Wpedantic, |
3429 | "ISO C++ forbids using a floating-point literal " |
3430 | "in a constant-expression"); |
3431 | return true; |
3432 | case NIC_CAST: |
3433 | error ("a cast to a type other than an integral or " |
3434 | "enumeration type cannot appear in a " |
3435 | "constant-expression"); |
3436 | return true; |
3437 | case NIC_TYPEID: |
3438 | error ("%<typeid%> operator " |
3439 | "cannot appear in a constant-expression"); |
3440 | return true; |
3441 | case NIC_NCC: |
3442 | error ("non-constant compound literals " |
3443 | "cannot appear in a constant-expression"); |
3444 | return true; |
3445 | case NIC_FUNC_CALL: |
3446 | error ("a function call " |
3447 | "cannot appear in a constant-expression"); |
3448 | return true; |
3449 | case NIC_INC: |
3450 | error ("an increment " |
3451 | "cannot appear in a constant-expression"); |
3452 | return true; |
3453 | case NIC_DEC: |
3454 | error ("an decrement " |
3455 | "cannot appear in a constant-expression"); |
3456 | return true; |
3457 | case NIC_ARRAY_REF: |
3458 | error ("an array reference " |
3459 | "cannot appear in a constant-expression"); |
3460 | return true; |
3461 | case NIC_ADDR_LABEL: |
3462 | error ("the address of a label " |
3463 | "cannot appear in a constant-expression"); |
3464 | return true; |
3465 | case NIC_OVERLOADED: |
3466 | error ("calls to overloaded operators " |
3467 | "cannot appear in a constant-expression"); |
3468 | return true; |
3469 | case NIC_ASSIGNMENT: |
3470 | error ("an assignment cannot appear in a constant-expression"); |
3471 | return true; |
3472 | case NIC_COMMA: |
3473 | error ("a comma operator " |
3474 | "cannot appear in a constant-expression"); |
3475 | return true; |
3476 | case NIC_CONSTRUCTOR: |
3477 | error ("a call to a constructor " |
3478 | "cannot appear in a constant-expression"); |
3479 | return true; |
3480 | case NIC_TRANSACTION: |
3481 | error ("a transaction expression " |
3482 | "cannot appear in a constant-expression"); |
3483 | return true; |
3484 | case NIC_THIS: |
3485 | msg = "this"; |
3486 | break; |
3487 | case NIC_FUNC_NAME: |
3488 | msg = "__FUNCTION__"; |
3489 | break; |
3490 | case NIC_PRETTY_FUNC: |
3491 | msg = "__PRETTY_FUNCTION__"; |
3492 | break; |
3493 | case NIC_C99_FUNC: |
3494 | msg = "__func__"; |
3495 | break; |
3496 | case NIC_VA_ARG: |
3497 | msg = "va_arg"; |
3498 | break; |
3499 | case NIC_ARROW: |
3500 | msg = "->"; |
3501 | break; |
3502 | case NIC_POINT: |
3503 | msg = "."; |
3504 | break; |
3505 | case NIC_STAR: |
3506 | msg = "*"; |
3507 | break; |
3508 | case NIC_ADDR: |
3509 | msg = "&"; |
3510 | break; |
3511 | case NIC_PREINCREMENT: |
3512 | msg = "++"; |
3513 | break; |
3514 | case NIC_PREDECREMENT: |
3515 | msg = "--"; |
3516 | break; |
3517 | case NIC_NEW: |
3518 | msg = "new"; |
3519 | break; |
3520 | case NIC_DEL: |
3521 | msg = "delete"; |
3522 | break; |
3523 | default: |
3524 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3524, __FUNCTION__)); |
3525 | } |
3526 | if (msg) |
3527 | error ("%qs cannot appear in a constant-expression", msg); |
3528 | return true; |
3529 | } |
3530 | } |
3531 | return false; |
3532 | } |
3533 | |
3534 | /* Emit a diagnostic for an invalid type name. This function commits |
3535 | to the current active tentative parse, if any. (Otherwise, the |
3536 | problematic construct might be encountered again later, resulting |
3537 | in duplicate error messages.) LOCATION is the location of ID. */ |
3538 | |
3539 | static void |
3540 | cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id, |
3541 | location_t location) |
3542 | { |
3543 | tree decl, ambiguous_decls; |
3544 | cp_parser_commit_to_tentative_parse (parser); |
3545 | /* Try to lookup the identifier. */ |
3546 | decl = cp_parser_lookup_name (parser, id, none_type, |
3547 | /*is_template=*/false, |
3548 | /*is_namespace=*/false, |
3549 | /*check_dependency=*/true, |
3550 | &ambiguous_decls, location); |
3551 | if (ambiguous_decls) |
3552 | /* If the lookup was ambiguous, an error will already have |
3553 | been issued. */ |
3554 | return; |
3555 | /* If the lookup found a template-name, it means that the user forgot |
3556 | to specify an argument list. Emit a useful error message. */ |
3557 | if (DECL_TYPE_TEMPLATE_P (decl)(((enum tree_code) (decl)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3557, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((decl ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3557, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == TYPE_DECL)) |
3558 | { |
3559 | auto_diagnostic_group d; |
3560 | error_at (location, |
3561 | "invalid use of template-name %qE without an argument list", |
3562 | decl); |
3563 | if (DECL_CLASS_TEMPLATE_P (decl)((((enum tree_code) (decl)->base.code) == TEMPLATE_DECL && ((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3563, __FUNCTION__, (TEMPLATE_DECL))))))))->result != (tree ) __null && ((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> ((((tree_check ((decl ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3563, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == TYPE_DECL) && (((enum tree_code) (((struct tree_template_decl *)(const_cast<union tree_node *> (( ((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3563, __FUNCTION__, (TEMPLATE_DECL))))))))->result)-> base.code) == TYPE_DECL && ((contains_struct_check (( ((struct tree_template_decl *)(const_cast<union tree_node * > ((((tree_check ((decl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3563, __FUNCTION__, (TEMPLATE_DECL))))))))->result), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3563, __FUNCTION__))->decl_common.lang_flag_2))) && cxx_dialect < cxx17) |
3564 | inform (location, "class template argument deduction is only available " |
3565 | "with %<-std=c++17%> or %<-std=gnu++17%>"); |
3566 | inform (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3566, __FUNCTION__))->decl_minimal.locus), "%qD declared here", decl); |
3567 | } |
3568 | else if (TREE_CODE (id)((enum tree_code) (id)->base.code) == BIT_NOT_EXPR) |
3569 | error_at (location, "invalid use of destructor %qD as a type", id); |
3570 | else if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TYPE_DECL) |
3571 | /* Something like 'unsigned A a;' */ |
3572 | error_at (location, "invalid combination of multiple type-specifiers"); |
3573 | else if (!parser->scope) |
3574 | { |
3575 | /* Issue an error message. */ |
3576 | auto_diagnostic_group d; |
3577 | name_hint hint; |
3578 | if (TREE_CODE (id)((enum tree_code) (id)->base.code) == IDENTIFIER_NODE) |
3579 | hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_TYPENAME, location); |
3580 | if (const char *suggestion = hint.suggestion ()) |
3581 | { |
3582 | gcc_rich_location richloc (location); |
3583 | richloc.add_fixit_replace (suggestion); |
3584 | error_at (&richloc, |
3585 | "%qE does not name a type; did you mean %qs?", |
3586 | id, suggestion); |
3587 | } |
3588 | else |
3589 | error_at (location, "%qE does not name a type", id); |
3590 | /* If we're in a template class, it's possible that the user was |
3591 | referring to a type from a base class. For example: |
3592 | |
3593 | template <typename T> struct A { typedef T X; }; |
3594 | template <typename T> struct B : public A<T> { X x; }; |
3595 | |
3596 | The user should have said "typename A<T>::X". */ |
3597 | if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_CONSTEXPR]) |
3598 | inform (location, "C++11 %<constexpr%> only available with " |
3599 | "%<-std=c++11%> or %<-std=gnu++11%>"); |
3600 | else if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_NOEXCEPT]) |
3601 | inform (location, "C++11 %<noexcept%> only available with " |
3602 | "%<-std=c++11%> or %<-std=gnu++11%>"); |
3603 | else if (TREE_CODE (id)((enum tree_code) (id)->base.code) == IDENTIFIER_NODE |
3604 | && (id_equal (id, "module") || id_equal (id, "import"))) |
3605 | { |
3606 | if (modules_p ()) |
3607 | inform (location, "%qE is not recognized as a module control-line", |
3608 | id); |
3609 | else if (cxx_dialect < cxx20) |
3610 | inform (location, "C++20 %qE only available with %<-fmodules-ts%>", |
3611 | id); |
3612 | else |
3613 | inform (location, "C++20 %qE only available with %<-fmodules-ts%>" |
3614 | ", which is not yet enabled with %<-std=c++20%>", id); |
3615 | } |
3616 | else if (cxx_dialect < cxx11 |
3617 | && TREE_CODE (id)((enum tree_code) (id)->base.code) == IDENTIFIER_NODE |
3618 | && id_equal (id, "thread_local")) |
3619 | inform (location, "C++11 %<thread_local%> only available with " |
3620 | "%<-std=c++11%> or %<-std=gnu++11%>"); |
3621 | else if (cxx_dialect < cxx20 && id == ridpointers[(int)RID_CONSTINIT]) |
3622 | inform (location, "C++20 %<constinit%> only available with " |
3623 | "%<-std=c++20%> or %<-std=gnu++20%>"); |
3624 | else if (!flag_conceptsglobal_options.x_flag_concepts && id == ridpointers[(int)RID_CONCEPT]) |
3625 | inform (location, "%<concept%> only available with %<-std=c++20%> or " |
3626 | "%<-fconcepts%>"); |
3627 | else if (!flag_conceptsglobal_options.x_flag_concepts && id == ridpointers[(int)RID_REQUIRES]) |
3628 | inform (location, "%<requires%> only available with %<-std=c++20%> or " |
3629 | "%<-fconcepts%>"); |
3630 | else if (processing_template_declscope_chain->x_processing_template_decl && current_class_typescope_chain->class_type |
3631 | && TYPE_BINFO (current_class_type)((tree_check3 ((scope_chain->class_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3631, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)) |
3632 | { |
3633 | for (tree b = TREE_CHAIN (TYPE_BINFO (current_class_type))((contains_struct_check ((((tree_check3 ((scope_chain->class_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3633, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.maxval)), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3633, __FUNCTION__))->common.chain); |
3634 | b; b = TREE_CHAIN (b)((contains_struct_check ((b), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3634, __FUNCTION__))->common.chain)) |
3635 | { |
3636 | tree base_type = BINFO_TYPE (b)((contains_struct_check (((tree_check ((b), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3636, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3636, __FUNCTION__))->typed.type); |
3637 | if (CLASS_TYPE_P (base_type)(((((enum tree_code) (base_type)->base.code)) == RECORD_TYPE || (((enum tree_code) (base_type)->base.code)) == UNION_TYPE ) && ((tree_class_check ((base_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3637, __FUNCTION__))->type_common.lang_flag_5)) |
3638 | && dependent_type_p (base_type)) |
3639 | { |
3640 | /* Go from a particular instantiation of the |
3641 | template (which will have an empty TYPE_FIELDs), |
3642 | to the main version. */ |
3643 | base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type)((((((tree_class_check (((base_type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__))->type_with_lang_specific.lang_specific ))->use_template) && !(((((tree_class_check (((base_type )), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__))->type_with_lang_specific.lang_specific ))->use_template) == 2)) ? ((contains_struct_check ((((struct tree_template_decl *)(const_cast<union tree_node *> (( ((tree_check ((((((contains_struct_check ((((tree_check ((((struct tree_template_decl *)(const_cast<union tree_node *> (( ((tree_check ((((struct tree_template_info*)(tree_check ((((( tree_class_check (((tree_check3 (((base_type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__))->type_non_common.lang_1))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__, (TEMPLATE_INFO))))->tmpl), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__, (TREE_LIST)))->list.value)), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__))->typed.type)))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__, (TEMPLATE_DECL))))))))->result), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3643, __FUNCTION__))->typed.type) : (base_type)); |
3644 | for (tree field = TYPE_FIELDS (base_type)((tree_check3 ((base_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3644, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE )))->type_non_common.values); |
3645 | field; field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), ( TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3645, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3645, __FUNCTION__))->common.chain))) |
3646 | if (TREE_CODE (field)((enum tree_code) (field)->base.code) == TYPE_DECL |
3647 | && DECL_NAME (field)((contains_struct_check ((field), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3647, __FUNCTION__))->decl_minimal.name) == id) |
3648 | { |
3649 | inform (location, |
3650 | "(perhaps %<typename %T::%E%> was intended)", |
3651 | BINFO_TYPE (b)((contains_struct_check (((tree_check ((b), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3651, __FUNCTION__, (TREE_BINFO)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3651, __FUNCTION__))->typed.type), id); |
3652 | goto found; |
3653 | } |
3654 | } |
3655 | } |
3656 | found:; |
3657 | } |
3658 | } |
3659 | /* Here we diagnose qualified-ids where the scope is actually correct, |
3660 | but the identifier does not resolve to a valid type name. */ |
3661 | else if (parser->scope != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
3662 | { |
3663 | if (TREE_CODE (parser->scope)((enum tree_code) (parser->scope)->base.code) == NAMESPACE_DECL) |
3664 | { |
3665 | auto_diagnostic_group d; |
3666 | name_hint hint; |
3667 | if (decl == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
3668 | hint = suggest_alternative_in_explicit_scope (location, id, |
3669 | parser->scope); |
3670 | const char *suggestion = hint.suggestion (); |
3671 | gcc_rich_location richloc (location_of (id)); |
3672 | if (suggestion) |
3673 | richloc.add_fixit_replace (suggestion); |
3674 | if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) |
3675 | { |
3676 | if (suggestion) |
3677 | error_at (&richloc, |
3678 | "%qE in namespace %qE does not name a template" |
3679 | " type; did you mean %qs?", |
3680 | id, parser->scope, suggestion); |
3681 | else |
3682 | error_at (&richloc, |
3683 | "%qE in namespace %qE does not name a template type", |
3684 | id, parser->scope); |
3685 | } |
3686 | else if (TREE_CODE (id)((enum tree_code) (id)->base.code) == TEMPLATE_ID_EXPR) |
3687 | { |
3688 | if (suggestion) |
3689 | error_at (&richloc, |
3690 | "%qE in namespace %qE does not name a template" |
3691 | " type; did you mean %qs?", |
3692 | TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3692, __FUNCTION__))))), parser->scope, suggestion); |
3693 | else |
3694 | error_at (&richloc, |
3695 | "%qE in namespace %qE does not name a template" |
3696 | " type", |
3697 | TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3697, __FUNCTION__))))), parser->scope); |
3698 | } |
3699 | else |
3700 | { |
3701 | if (suggestion) |
3702 | error_at (&richloc, |
3703 | "%qE in namespace %qE does not name a type" |
3704 | "; did you mean %qs?", |
3705 | id, parser->scope, suggestion); |
3706 | else |
3707 | error_at (&richloc, |
3708 | "%qE in namespace %qE does not name a type", |
3709 | id, parser->scope); |
3710 | } |
3711 | if (DECL_P (decl)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (decl)->base.code))] == tcc_declaration)) |
3712 | inform (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3712, __FUNCTION__))->decl_minimal.locus), "%qD declared here", decl); |
3713 | } |
3714 | else if (CLASS_TYPE_P (parser->scope)(((((enum tree_code) (parser->scope)->base.code)) == RECORD_TYPE || (((enum tree_code) (parser->scope)->base.code)) == UNION_TYPE ) && ((tree_class_check ((parser->scope), (tcc_type ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3714, __FUNCTION__))->type_common.lang_flag_5)) |
3715 | && constructor_name_p (id, parser->scope)) |
3716 | { |
3717 | /* A<T>::A<T>() */ |
3718 | auto_diagnostic_group d; |
3719 | error_at (location, "%<%T::%E%> names the constructor, not" |
3720 | " the type", parser->scope, id); |
3721 | if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) |
3722 | error_at (location, "and %qT has no template constructors", |
3723 | parser->scope); |
3724 | } |
3725 | else if (TYPE_P (parser->scope)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (parser->scope)->base.code))] == tcc_type) |
3726 | && dependent_scope_p (parser->scope)) |
3727 | { |
3728 | gcc_rich_location richloc (location); |
3729 | richloc.add_fixit_insert_before ("typename "); |
3730 | if (TREE_CODE (parser->scope)((enum tree_code) (parser->scope)->base.code) == TYPENAME_TYPE) |
3731 | error_at (&richloc, |
3732 | "need %<typename%> before %<%T::%D::%E%> because " |
3733 | "%<%T::%D%> is a dependent scope", |
3734 | TYPE_CONTEXT (parser->scope)((tree_class_check ((parser->scope), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3734, __FUNCTION__))->type_common.context), |
3735 | TYPENAME_TYPE_FULLNAME (parser->scope)(((tree_class_check (((tree_check ((parser->scope), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3735, __FUNCTION__, (TYPENAME_TYPE)))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3735, __FUNCTION__))->type_non_common.values)), |
3736 | id, |
3737 | TYPE_CONTEXT (parser->scope)((tree_class_check ((parser->scope), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3737, __FUNCTION__))->type_common.context), |
3738 | TYPENAME_TYPE_FULLNAME (parser->scope)(((tree_class_check (((tree_check ((parser->scope), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3738, __FUNCTION__, (TYPENAME_TYPE)))), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3738, __FUNCTION__))->type_non_common.values))); |
3739 | else |
3740 | error_at (&richloc, "need %<typename%> before %<%T::%E%> because " |
3741 | "%qT is a dependent scope", |
3742 | parser->scope, id, parser->scope); |
3743 | } |
3744 | else if (TYPE_P (parser->scope)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (parser->scope)->base.code))] == tcc_type)) |
3745 | { |
3746 | auto_diagnostic_group d; |
3747 | if (!COMPLETE_TYPE_P (parser->scope)(((tree_class_check ((parser->scope), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3747, __FUNCTION__))->type_common.size) != (tree) __null )) |
3748 | cxx_incomplete_type_error (location_of (id), NULL_TREE(tree) __null, |
3749 | parser->scope); |
3750 | else if (cp_lexer_next_token_is (parser->lexer, CPP_LESS)) |
3751 | error_at (location_of (id), |
3752 | "%qE in %q#T does not name a template type", |
3753 | id, parser->scope); |
3754 | else if (TREE_CODE (id)((enum tree_code) (id)->base.code) == TEMPLATE_ID_EXPR) |
3755 | error_at (location_of (id), |
3756 | "%qE in %q#T does not name a template type", |
3757 | TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3757, __FUNCTION__))))), parser->scope); |
3758 | else |
3759 | error_at (location_of (id), |
3760 | "%qE in %q#T does not name a type", |
3761 | id, parser->scope); |
3762 | if (DECL_P (decl)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (decl)->base.code))] == tcc_declaration)) |
3763 | inform (DECL_SOURCE_LOCATION (decl)((contains_struct_check ((decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3763, __FUNCTION__))->decl_minimal.locus), "%qD declared here", decl); |
3764 | } |
3765 | else |
3766 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 3766, __FUNCTION__)); |
3767 | } |
3768 | } |
3769 | |
3770 | /* Check for a common situation where a type-name should be present, |
3771 | but is not, and issue a sensible error message. Returns true if an |
3772 | invalid type-name was detected. |
3773 | |
3774 | The situation handled by this function are variable declarations of the |
3775 | form `ID a', where `ID' is an id-expression and `a' is a plain identifier. |
3776 | Usually, `ID' should name a type, but if we got here it means that it |
3777 | does not. We try to emit the best possible error message depending on |
3778 | how exactly the id-expression looks like. */ |
3779 | |
3780 | static bool |
3781 | cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser) |
3782 | { |
3783 | tree id; |
3784 | cp_token *token = cp_lexer_peek_token (parser->lexer); |
3785 | |
3786 | /* Avoid duplicate error about ambiguous lookup. */ |
3787 | if (token->type == CPP_NESTED_NAME_SPECIFIER((enum cpp_ttype) (((enum cpp_ttype) (CPP_KEYWORD + 1)) + 1))) |
3788 | { |
3789 | cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2); |
3790 | if (next->type == CPP_NAME && next->error_reported) |
3791 | goto out; |
3792 | } |
3793 | |
3794 | cp_parser_parse_tentatively (parser); |
3795 | id = cp_parser_id_expression (parser, |
3796 | /*template_keyword_p=*/false, |
3797 | /*check_dependency_p=*/true, |
3798 | /*template_p=*/NULL__null, |
3799 | /*declarator_p=*/true, |
3800 | /*optional_p=*/false); |
3801 | /* If the next token is a (, this is a function with no explicit return |
3802 | type, i.e. constructor, destructor or conversion op. */ |
3803 | if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN) |
3804 | || TREE_CODE (id)((enum tree_code) (id)->base.code) == TYPE_DECL) |
3805 | { |
3806 | cp_parser_abort_tentative_parse (parser); |
3807 | return false; |
3808 | } |
3809 | if (!cp_parser_parse_definitely (parser)) |
3810 | return false; |
3811 | |
3812 | /* Emit a diagnostic for the invalid type. */ |
3813 | cp_parser_diagnose_invalid_type_name (parser, id, token->location); |
3814 | out: |
3815 | /* If we aren't in the middle of a declarator (i.e. in a |
3816 | parameter-declaration-clause), skip to the end of the declaration; |
3817 | there's no point in trying to process it. */ |
3818 | if (!parser->in_declarator_p) |
3819 | cp_parser_skip_to_end_of_block_or_statement (parser); |
3820 | return true; |
3821 | } |
3822 | |
3823 | /* Consume tokens up to, and including, the next non-nested closing `)'. |
3824 | Returns 1 iff we found a closing `)'. RECOVERING is true, if we |
3825 | are doing error recovery. Returns -1 if OR_TTYPE is not CPP_EOF and we |
3826 | found an unnested token of that type. */ |
3827 | |
3828 | static int |
3829 | cp_parser_skip_to_closing_parenthesis_1 (cp_parser *parser, |
3830 | bool recovering, |
3831 | cpp_ttype or_ttype, |
3832 | bool consume_paren) |
3833 | { |
3834 | unsigned paren_depth = 0; |
3835 | unsigned brace_depth = 0; |
3836 | unsigned square_depth = 0; |
3837 | unsigned condop_depth = 0; |
3838 | |
3839 | if (recovering && or_ttype == CPP_EOF |
3840 | && cp_parser_uncommitted_to_tentative_parse_p (parser)) |
3841 | return 0; |
3842 | |
3843 | while (true) |
3844 | { |
3845 | cp_token * token = cp_lexer_peek_token (parser->lexer); |
3846 | |
3847 | /* Have we found what we're looking for before the closing paren? */ |
3848 | if (token->type == or_ttype && or_ttype != CPP_EOF |
3849 | && !brace_depth && !paren_depth && !square_depth && !condop_depth) |
3850 | return -1; |
3851 | |
3852 | switch (token->type) |
3853 | { |
3854 | case CPP_PRAGMA_EOL: |
3855 | if (!parser->lexer->in_pragma) |
3856 | break; |
3857 | /* FALLTHRU */ |
3858 | case CPP_EOF: |
3859 | /* If we've run out of tokens, then there is no closing `)'. */ |
3860 | return 0; |
3861 | |
3862 | /* This is good for lambda expression capture-lists. */ |
3863 | case CPP_OPEN_SQUARE: |
3864 | ++square_depth; |
3865 | break; |
3866 | case CPP_CLOSE_SQUARE: |
3867 | if (!square_depth--) |
3868 | return 0; |
3869 | break; |
3870 | |
3871 | case CPP_SEMICOLON: |
3872 | /* This matches the processing in skip_to_end_of_statement. */ |
3873 | if (!brace_depth) |
3874 | return 0; |
3875 | break; |
3876 | |
3877 | case CPP_OPEN_BRACE: |
3878 | ++brace_depth; |
3879 | break; |
3880 | case CPP_CLOSE_BRACE: |
3881 | if (!brace_depth--) |
3882 | return 0; |
3883 | break; |
3884 | |
3885 | case CPP_OPEN_PAREN: |
3886 | if (!brace_depth) |
3887 | ++paren_depth; |
3888 | break; |
3889 | |
3890 | case CPP_CLOSE_PAREN: |
3891 | if (!brace_depth && !paren_depth--) |
3892 | { |
3893 | if (consume_paren) |
3894 | cp_lexer_consume_token (parser->lexer); |
3895 | return 1; |
3896 | } |
3897 | break; |
3898 | |
3899 | case CPP_QUERY: |
3900 | if (!brace_depth && !paren_depth && !square_depth) |
3901 | ++condop_depth; |
3902 | break; |
3903 | |
3904 | case CPP_COLON: |
3905 | if (!brace_depth && !paren_depth && !square_depth && condop_depth > 0) |
3906 | condop_depth--; |
3907 | break; |
3908 | |
3909 | case CPP_KEYWORD: |
3910 | if (!cp_token_is_module_directive (token)) |
3911 | break; |
3912 | /* FALLTHROUGH */ |
3913 | |
3914 | case CPP_PRAGMA: |
3915 | /* We fell into a pragma. Skip it, and continue. */ |
3916 | cp_parser_skip_to_pragma_eol (parser, recovering ? token : nullptr); |
3917 | continue; |
3918 | |
3919 | default: |
3920 | break; |
3921 | } |
3922 | |
3923 | /* Consume the token. */ |
3924 | cp_lexer_consume_token (parser->lexer); |
3925 | } |
3926 | } |
3927 | |
3928 | /* Consume tokens up to, and including, the next non-nested closing `)'. |
3929 | Returns 1 iff we found a closing `)'. RECOVERING is true, if we |
3930 | are doing error recovery. Returns -1 if OR_COMMA is true and we |
3931 | found an unnested token of that type. */ |
3932 | |
3933 | static int |
3934 | cp_parser_skip_to_closing_parenthesis (cp_parser *parser, |
3935 | bool recovering, |
3936 | bool or_comma, |
3937 | bool consume_paren) |
3938 | { |
3939 | cpp_ttype ttype = or_comma ? CPP_COMMA : CPP_EOF; |
3940 | return cp_parser_skip_to_closing_parenthesis_1 (parser, recovering, |
3941 | ttype, consume_paren); |
3942 | } |
3943 | |
3944 | /* Consume tokens until we reach the end of the current statement. |
3945 | Normally, that will be just before consuming a `;'. However, if a |
3946 | non-nested `}' comes first, then we stop before consuming that. */ |
3947 | |
3948 | static void |
3949 | cp_parser_skip_to_end_of_statement (cp_parser* parser) |
3950 | { |
3951 | unsigned nesting_depth = 0; |
3952 | |
3953 | /* Unwind generic function template scope if necessary. */ |
3954 | if (parser->fully_implicit_function_template_p) |
3955 | abort_fully_implicit_template (parser); |
3956 | |
3957 | while (true) |
3958 | { |
3959 | cp_token *token = cp_lexer_peek_token (parser->lexer); |
3960 | |
3961 | switch (token->type) |
3962 | { |
3963 | case CPP_PRAGMA_EOL: |
3964 | if (!parser->lexer->in_pragma) |
3965 | break; |
3966 | /* FALLTHRU */ |
3967 | case CPP_EOF: |
3968 | /* If we've run out of tokens, stop. */ |
3969 | return; |
3970 | |
3971 | case CPP_SEMICOLON: |
3972 | /* If the next token is a `;', we have reached the end of the |
3973 | statement. */ |
3974 | if (!nesting_depth) |
3975 | return; |
3976 | break; |
3977 | |
3978 | case CPP_CLOSE_BRACE: |
3979 | /* If this is a non-nested '}', stop before consuming it. |
3980 | That way, when confronted with something like: |
3981 | |
3982 | { 3 + } |
3983 | |
3984 | we stop before consuming the closing '}', even though we |
3985 | have not yet reached a `;'. */ |
3986 | if (nesting_depth == 0) |
3987 | return; |
3988 | |
3989 | /* If it is the closing '}' for a block that we have |
3990 | scanned, stop -- but only after consuming the token. |
3991 | That way given: |
3992 | |
3993 | void f g () { ... } |
3994 | typedef int I; |
3995 | |
3996 | we will stop after the body of the erroneously declared |
3997 | function, but before consuming the following `typedef' |
3998 | declaration. */ |
3999 | if (--nesting_depth == 0) |
4000 | { |
4001 | cp_lexer_consume_token (parser->lexer); |
4002 | return; |
4003 | } |
4004 | break; |
4005 | |
4006 | case CPP_OPEN_BRACE: |
4007 | ++nesting_depth; |
4008 | break; |
4009 | |
4010 | case CPP_KEYWORD: |
4011 | if (!cp_token_is_module_directive (token)) |
4012 | break; |
4013 | /* FALLTHROUGH */ |
4014 | |
4015 | case CPP_PRAGMA: |
4016 | /* We fell into a pragma. Skip it, and continue or return. */ |
4017 | cp_parser_skip_to_pragma_eol (parser, token); |
4018 | if (!nesting_depth) |
4019 | return; |
4020 | continue; |
4021 | |
4022 | default: |
4023 | break; |
4024 | } |
4025 | |
4026 | /* Consume the token. */ |
4027 | cp_lexer_consume_token (parser->lexer); |
4028 | } |
4029 | } |
4030 | |
4031 | /* This function is called at the end of a statement or declaration. |
4032 | If the next token is a semicolon, it is consumed; otherwise, error |
4033 | recovery is attempted. */ |
4034 | |
4035 | static void |
4036 | cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser) |
4037 | { |
4038 | /* Look for the trailing `;'. */ |
4039 | if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)) |
4040 | { |
4041 | /* If there is additional (erroneous) input, skip to the end of |
4042 | the statement. */ |
4043 | cp_parser_skip_to_end_of_statement (parser); |
4044 | /* If the next token is now a `;', consume it. */ |
4045 | if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) |
4046 | cp_lexer_consume_token (parser->lexer); |
4047 | } |
4048 | } |
4049 | |
4050 | /* Skip tokens until we have consumed an entire block, or until we |
4051 | have consumed a non-nested `;'. */ |
4052 | |
4053 | static void |
4054 | cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser) |
4055 | { |
4056 | int nesting_depth = 0; |
4057 | |
4058 | /* Unwind generic function template scope if necessary. */ |
4059 | if (parser->fully_implicit_function_template_p) |
4060 | abort_fully_implicit_template (parser); |
4061 | |
4062 | while (nesting_depth >= 0) |
4063 | { |
4064 | cp_token *token = cp_lexer_peek_token (parser->lexer); |
4065 | |
4066 | switch (token->type) |
4067 | { |
4068 | case CPP_PRAGMA_EOL: |
4069 | if (!parser->lexer->in_pragma) |
4070 | break; |
4071 | /* FALLTHRU */ |
4072 | case CPP_EOF: |
4073 | /* If we've run out of tokens, stop. */ |
4074 | return; |
4075 | |
4076 | case CPP_SEMICOLON: |
4077 | /* Stop if this is an unnested ';'. */ |
4078 | if (!nesting_depth) |
4079 | nesting_depth = -1; |
4080 | break; |
4081 | |
4082 | case CPP_CLOSE_BRACE: |
4083 | /* Stop if this is an unnested '}', or closes the outermost |
4084 | nesting level. */ |
4085 | nesting_depth--; |
4086 | if (nesting_depth < 0) |
4087 | return; |
4088 | if (!nesting_depth) |
4089 | nesting_depth = -1; |
4090 | break; |
4091 | |
4092 | case CPP_OPEN_BRACE: |
4093 | /* Nest. */ |
4094 | nesting_depth++; |
4095 | break; |
4096 | |
4097 | case CPP_KEYWORD: |
4098 | if (!cp_token_is_module_directive (token)) |
4099 | break; |
4100 | /* FALLTHROUGH */ |
4101 | |
4102 | case CPP_PRAGMA: |
4103 | /* Skip it, and continue or return. */ |
4104 | cp_parser_skip_to_pragma_eol (parser, token); |
4105 | if (!nesting_depth) |
4106 | return; |
4107 | continue; |
4108 | |
4109 | default: |
4110 | break; |
4111 | } |
4112 | |
4113 | /* Consume the token. */ |
4114 | cp_lexer_consume_token (parser->lexer); |
4115 | } |
4116 | } |
4117 | |
4118 | /* Skip tokens until a non-nested closing curly brace is the next |
4119 | token, or there are no more tokens. Return true in the first case, |
4120 | false otherwise. */ |
4121 | |
4122 | static bool |
4123 | cp_parser_skip_to_closing_brace (cp_parser *parser) |
4124 | { |
4125 | unsigned nesting_depth = 0; |
4126 | |
4127 | while (true) |
4128 | { |
4129 | cp_token *token = cp_lexer_peek_token (parser->lexer); |
4130 | |
4131 | switch (token->type) |
4132 | { |
4133 | case CPP_PRAGMA_EOL: |
4134 | if (!parser->lexer->in_pragma) |
4135 | break; |
4136 | /* FALLTHRU */ |
4137 | case CPP_EOF: |
4138 | /* If we've run out of tokens, stop. */ |
4139 | return false; |
4140 | |
4141 | case CPP_CLOSE_BRACE: |
4142 | /* If the next token is a non-nested `}', then we have reached |
4143 | the end of the current block. */ |
4144 | if (nesting_depth-- == 0) |
4145 | return true; |
4146 | break; |
4147 | |
4148 | case CPP_OPEN_BRACE: |
4149 | /* If it the next token is a `{', then we are entering a new |
4150 | block. Consume the entire block. */ |
4151 | ++nesting_depth; |
4152 | break; |
4153 | |
4154 | default: |
4155 | break; |
4156 | } |
4157 | |
4158 | /* Consume the token. */ |
4159 | cp_lexer_consume_token (parser->lexer); |
4160 | } |
4161 | } |
4162 | |
4163 | /* Consume tokens until we reach the end of the pragma. The PRAGMA_TOK |
4164 | parameter is the PRAGMA token, allowing us to purge the entire pragma |
4165 | sequence. PRAGMA_TOK can be NULL, if we're speculatively scanning |
4166 | forwards (not error recovery). */ |
4167 | |
4168 | static void |
4169 | cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok) |
4170 | { |
4171 | cp_token *token; |
4172 | |
4173 | do |
4174 | { |
4175 | /* The preprocessor makes sure that a PRAGMA_EOL token appears |
4176 | before an EOF token, even when the EOF is on the pragma line. |
4177 | We should never get here without being inside a deferred |
4178 | pragma. */ |
4179 | gcc_checking_assert (cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))((void)(!(cp_lexer_next_token_is_not (parser->lexer, CPP_EOF )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4179, __FUNCTION__), 0 : 0)); |
4180 | token = cp_lexer_consume_token (parser->lexer); |
4181 | } |
4182 | while (token->type != CPP_PRAGMA_EOL); |
4183 | |
4184 | if (pragma_tok) |
4185 | { |
4186 | parser->lexer->in_pragma = false; |
4187 | if (parser->lexer->in_omp_attribute_pragma |
4188 | && cp_lexer_next_token_is (parser->lexer, CPP_EOF)) |
4189 | { |
4190 | parser->lexer = parser->lexer->next; |
4191 | /* Put the current source position back where it was before this |
4192 | lexer was pushed. */ |
4193 | cp_lexer_set_source_position_from_token (parser->lexer->next_token); |
4194 | } |
4195 | } |
4196 | } |
4197 | |
4198 | /* Require pragma end of line, resyncing with it as necessary. The |
4199 | arguments are as for cp_parser_skip_to_pragma_eol. */ |
4200 | |
4201 | static void |
4202 | cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok) |
4203 | { |
4204 | parser->lexer->in_pragma = false; |
4205 | if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL)) |
4206 | cp_parser_skip_to_pragma_eol (parser, pragma_tok); |
4207 | else if (parser->lexer->in_omp_attribute_pragma |
4208 | && cp_lexer_next_token_is (parser->lexer, CPP_EOF)) |
4209 | { |
4210 | parser->lexer = parser->lexer->next; |
4211 | /* Put the current source position back where it was before this |
4212 | lexer was pushed. */ |
4213 | cp_lexer_set_source_position_from_token (parser->lexer->next_token); |
4214 | } |
4215 | } |
4216 | |
4217 | /* This is a simple wrapper around make_typename_type. When the id is |
4218 | an unresolved identifier node, we can provide a superior diagnostic |
4219 | using cp_parser_diagnose_invalid_type_name. */ |
4220 | |
4221 | static tree |
4222 | cp_parser_make_typename_type (cp_parser *parser, tree id, |
4223 | location_t id_location) |
4224 | { |
4225 | tree result; |
4226 | if (identifier_p (id)) |
4227 | { |
4228 | result = make_typename_type (parser->scope, id, typename_type, |
4229 | /*complain=*/tf_none); |
4230 | if (result == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4231 | cp_parser_diagnose_invalid_type_name (parser, id, id_location); |
4232 | return result; |
4233 | } |
4234 | return make_typename_type (parser->scope, id, typename_type, tf_error); |
4235 | } |
4236 | |
4237 | /* This is a wrapper around the |
4238 | make_{pointer,ptrmem,reference}_declarator functions that decides |
4239 | which one to call based on the CODE and CLASS_TYPE arguments. The |
4240 | CODE argument should be one of the values returned by |
4241 | cp_parser_ptr_operator. ATTRIBUTES represent the attributes that |
4242 | appertain to the pointer or reference. */ |
4243 | |
4244 | static cp_declarator * |
4245 | cp_parser_make_indirect_declarator (enum tree_code code, tree class_type, |
4246 | cp_cv_quals cv_qualifiers, |
4247 | cp_declarator *target, |
4248 | tree attributes) |
4249 | { |
4250 | if (code == ERROR_MARK || target == cp_error_declarator) |
4251 | return cp_error_declarator; |
4252 | |
4253 | if (code == INDIRECT_REF) |
4254 | if (class_type == NULL_TREE(tree) __null) |
4255 | return make_pointer_declarator (cv_qualifiers, target, attributes); |
4256 | else |
4257 | return make_ptrmem_declarator (cv_qualifiers, class_type, |
4258 | target, attributes); |
4259 | else if (code == ADDR_EXPR && class_type == NULL_TREE(tree) __null) |
4260 | return make_reference_declarator (cv_qualifiers, target, |
4261 | false, attributes); |
4262 | else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE(tree) __null) |
4263 | return make_reference_declarator (cv_qualifiers, target, |
4264 | true, attributes); |
4265 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4265, __FUNCTION__)); |
4266 | } |
4267 | |
4268 | /* Create a new C++ parser. */ |
4269 | |
4270 | static cp_parser * |
4271 | cp_parser_new (cp_lexer *lexer) |
4272 | { |
4273 | /* Initialize the binops_by_token so that we can get the tree |
4274 | directly from the token. */ |
4275 | for (unsigned i = 0; i < ARRAY_SIZE (binops)(sizeof (binops) / sizeof ((binops)[0])); i++) |
4276 | binops_by_token[binops[i].token_type] = binops[i]; |
4277 | |
4278 | cp_parser *parser = ggc_cleared_alloc<cp_parser> (); |
4279 | parser->lexer = lexer; |
4280 | parser->context = cp_parser_context_new (NULL__null); |
4281 | |
4282 | /* For now, we always accept GNU extensions. */ |
4283 | parser->allow_gnu_extensions_p = 1; |
4284 | |
4285 | /* The `>' token is a greater-than operator, not the end of a |
4286 | template-id. */ |
4287 | parser->greater_than_is_operator_p = true; |
4288 | |
4289 | parser->default_arg_ok_p = true; |
4290 | |
4291 | /* We are not parsing a constant-expression. */ |
4292 | parser->integral_constant_expression_p = false; |
4293 | parser->allow_non_integral_constant_expression_p = false; |
4294 | parser->non_integral_constant_expression_p = false; |
4295 | |
4296 | /* Local variable names are not forbidden. */ |
4297 | parser->local_variables_forbidden_p = 0; |
4298 | |
4299 | /* We are not processing an `extern "C"' declaration. */ |
4300 | parser->in_unbraced_linkage_specification_p = false; |
4301 | |
4302 | /* We are not processing a declarator. */ |
4303 | parser->in_declarator_p = false; |
4304 | |
4305 | /* We are not processing a template-argument-list. */ |
4306 | parser->in_template_argument_list_p = false; |
4307 | |
4308 | /* We are not in an iteration statement. */ |
4309 | parser->in_statement = 0; |
4310 | |
4311 | /* We are not in a switch statement. */ |
4312 | parser->in_switch_statement_p = false; |
4313 | |
4314 | /* We are not parsing a type-id inside an expression. */ |
4315 | parser->in_type_id_in_expr_p = false; |
4316 | |
4317 | /* String literals should be translated to the execution character set. */ |
4318 | parser->translate_strings_p = true; |
4319 | |
4320 | /* We are not parsing a function body. */ |
4321 | parser->in_function_body = false; |
4322 | |
4323 | /* We can correct until told otherwise. */ |
4324 | parser->colon_corrects_to_scope_p = true; |
4325 | |
4326 | /* The unparsed function queue is empty. */ |
4327 | push_unparsed_function_queues (parser); |
4328 | |
4329 | /* There are no classes being defined. */ |
4330 | parser->num_classes_being_defined = 0; |
4331 | |
4332 | /* No template parameters apply. */ |
4333 | parser->num_template_parameter_lists = 0; |
4334 | |
4335 | /* Special parsing data structures. */ |
4336 | parser->omp_declare_simd = NULL__null; |
4337 | parser->oacc_routine = NULL__null; |
4338 | |
4339 | /* Not declaring an implicit function template. */ |
4340 | parser->auto_is_implicit_function_template_parm_p = false; |
4341 | parser->fully_implicit_function_template_p = false; |
4342 | parser->implicit_template_parms = 0; |
4343 | parser->implicit_template_scope = 0; |
4344 | |
4345 | /* Allow constrained-type-specifiers. */ |
4346 | parser->prevent_constrained_type_specifiers = 0; |
4347 | |
4348 | /* We haven't yet seen an 'extern "C"'. */ |
4349 | parser->innermost_linkage_specification_location = UNKNOWN_LOCATION((location_t) 0); |
4350 | |
4351 | return parser; |
4352 | } |
4353 | |
4354 | /* Create a cp_lexer structure which will emit the tokens in CACHE |
4355 | and push it onto the parser's lexer stack. This is used for delayed |
4356 | parsing of in-class method bodies and default arguments, and should |
4357 | not be confused with tentative parsing. */ |
4358 | static void |
4359 | cp_parser_push_lexer_for_tokens (cp_parser *parser, cp_token_cache *cache) |
4360 | { |
4361 | cp_lexer *lexer = cp_lexer_new_from_tokens (cache); |
4362 | lexer->next = parser->lexer; |
4363 | parser->lexer = lexer; |
4364 | |
4365 | /* Move the current source position to that of the first token in the |
4366 | new lexer. */ |
4367 | cp_lexer_set_source_position_from_token (lexer->next_token); |
4368 | } |
4369 | |
4370 | /* Pop the top lexer off the parser stack. This is never used for the |
4371 | "main" lexer, only for those pushed by cp_parser_push_lexer_for_tokens. */ |
4372 | static void |
4373 | cp_parser_pop_lexer (cp_parser *parser) |
4374 | { |
4375 | cp_lexer *lexer = parser->lexer; |
4376 | parser->lexer = lexer->next; |
4377 | cp_lexer_destroy (lexer); |
4378 | |
4379 | /* Put the current source position back where it was before this |
4380 | lexer was pushed. */ |
4381 | cp_lexer_set_source_position_from_token (parser->lexer->next_token); |
4382 | } |
4383 | |
4384 | /* Lexical conventions [gram.lex] */ |
4385 | |
4386 | /* Parse an identifier. Returns an IDENTIFIER_NODE representing the |
4387 | identifier. */ |
4388 | |
4389 | static cp_expr |
4390 | cp_parser_identifier (cp_parser* parser) |
4391 | { |
4392 | cp_token *token; |
4393 | |
4394 | /* Look for the identifier. */ |
4395 | token = cp_parser_require (parser, CPP_NAME, RT_NAME); |
4396 | /* Return the value. */ |
4397 | if (token) |
4398 | return cp_expr (token->u.value, token->location); |
4399 | else |
4400 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4401 | } |
4402 | |
4403 | /* Worker for cp_parser_string_literal and cp_parser_userdef_string_literal. |
4404 | Do not call this directly; use either of the above. |
4405 | |
4406 | Parse a sequence of adjacent string constants. Return a |
4407 | TREE_STRING representing the combined, nul-terminated string |
4408 | constant. If TRANSLATE is true, translate the string to the |
4409 | execution character set. If WIDE_OK is true, a wide string is |
4410 | valid here. If UDL_OK is true, a string literal with user-defined |
4411 | suffix can be used in this context. |
4412 | |
4413 | C++98 [lex.string] says that if a narrow string literal token is |
4414 | adjacent to a wide string literal token, the behavior is undefined. |
4415 | However, C99 6.4.5p4 says that this results in a wide string literal. |
4416 | We follow C99 here, for consistency with the C front end. |
4417 | |
4418 | This code is largely lifted from lex_string() in c-lex.cc. |
4419 | |
4420 | FUTURE: ObjC++ will need to handle @-strings here. */ |
4421 | |
4422 | static cp_expr |
4423 | cp_parser_string_literal_common (cp_parser *parser, bool translate, |
4424 | bool wide_ok, bool udl_ok, |
4425 | bool lookup_udlit) |
4426 | { |
4427 | tree value; |
4428 | size_t count; |
4429 | struct obstack str_ob; |
4430 | struct obstack loc_ob; |
4431 | cpp_string str, istr, *strs; |
4432 | cp_token *tok; |
4433 | enum cpp_ttype type, curr_type; |
4434 | int have_suffix_p = 0; |
4435 | tree string_tree; |
4436 | tree suffix_id = NULL_TREE(tree) __null; |
4437 | bool curr_tok_is_userdef_p = false; |
4438 | |
4439 | tok = cp_lexer_peek_token (parser->lexer); |
4440 | if (!cp_parser_is_string_literal (tok)) |
4441 | { |
4442 | cp_parser_error (parser, "expected string-literal"); |
4443 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4444 | } |
4445 | |
4446 | location_t loc = tok->location; |
4447 | |
4448 | if (cpp_userdef_string_p (tok->type)) |
4449 | { |
4450 | if (!udl_ok) |
4451 | { |
4452 | error_at (loc, "string literal with user-defined suffix " |
4453 | "is invalid in this context"); |
4454 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4455 | } |
4456 | string_tree = USERDEF_LITERAL_VALUE (tok->u.value)(((struct tree_userdef_literal *)(tree_check ((tok->u.value ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4456, __FUNCTION__, (USERDEF_LITERAL))))->value); |
4457 | curr_type = cpp_userdef_string_remove_type (tok->type); |
4458 | curr_tok_is_userdef_p = true; |
4459 | } |
4460 | else |
4461 | { |
4462 | string_tree = tok->u.value; |
4463 | curr_type = tok->type; |
4464 | } |
4465 | type = curr_type; |
4466 | |
4467 | /* Try to avoid the overhead of creating and destroying an obstack |
4468 | for the common case of just one string. */ |
4469 | if (!cp_parser_is_string_literal |
4470 | (cp_lexer_peek_nth_token (parser->lexer, 2))) |
4471 | { |
4472 | cp_lexer_consume_token (parser->lexer); |
4473 | |
4474 | str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree)((const char *)((tree_check ((string_tree), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4474, __FUNCTION__, (STRING_CST)))->string.str)); |
4475 | str.len = TREE_STRING_LENGTH (string_tree)((tree_check ((string_tree), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4475, __FUNCTION__, (STRING_CST)))->string.length); |
4476 | count = 1; |
4477 | |
4478 | if (curr_tok_is_userdef_p) |
4479 | { |
4480 | suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value)(((struct tree_userdef_literal *)(tree_check ((tok->u.value ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4480, __FUNCTION__, (USERDEF_LITERAL))))->suffix_id); |
4481 | have_suffix_p = 1; |
4482 | curr_type = cpp_userdef_string_remove_type (tok->type); |
4483 | } |
4484 | else |
4485 | curr_type = tok->type; |
4486 | |
4487 | strs = &str; |
4488 | } |
4489 | else |
4490 | { |
4491 | location_t last_tok_loc = tok->location; |
4492 | gcc_obstack_init (&str_ob)_obstack_begin (((&str_ob)), (memory_block_pool::block_size ), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free )); |
4493 | gcc_obstack_init (&loc_ob)_obstack_begin (((&loc_ob)), (memory_block_pool::block_size ), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free )); |
4494 | count = 0; |
4495 | |
4496 | do |
4497 | { |
4498 | cp_lexer_consume_token (parser->lexer); |
4499 | count++; |
4500 | str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree)((const char *)((tree_check ((string_tree), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4500, __FUNCTION__, (STRING_CST)))->string.str)); |
4501 | str.len = TREE_STRING_LENGTH (string_tree)((tree_check ((string_tree), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4501, __FUNCTION__, (STRING_CST)))->string.length); |
4502 | |
4503 | if (curr_tok_is_userdef_p) |
4504 | { |
4505 | tree curr_suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value)(((struct tree_userdef_literal *)(tree_check ((tok->u.value ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4505, __FUNCTION__, (USERDEF_LITERAL))))->suffix_id); |
4506 | if (have_suffix_p == 0) |
4507 | { |
4508 | suffix_id = curr_suffix_id; |
4509 | have_suffix_p = 1; |
4510 | } |
4511 | else if (have_suffix_p == 1 |
4512 | && curr_suffix_id != suffix_id) |
4513 | { |
4514 | error ("inconsistent user-defined literal suffixes" |
4515 | " %qD and %qD in string literal", |
4516 | suffix_id, curr_suffix_id); |
4517 | have_suffix_p = -1; |
4518 | } |
4519 | curr_type = cpp_userdef_string_remove_type (tok->type); |
4520 | } |
4521 | else |
4522 | curr_type = tok->type; |
4523 | |
4524 | if (type != curr_type) |
4525 | { |
4526 | if (type == CPP_STRING) |
4527 | type = curr_type; |
4528 | else if (curr_type != CPP_STRING) |
4529 | { |
4530 | rich_location rich_loc (line_table, tok->location); |
4531 | rich_loc.add_range (last_tok_loc); |
4532 | error_at (&rich_loc, |
4533 | "concatenation of string literals with " |
4534 | "conflicting encoding prefixes"); |
4535 | } |
4536 | } |
4537 | |
4538 | obstack_grow (&str_ob, &str, sizeof (cpp_string))__extension__ ({ struct obstack *__o = (&str_ob); size_t __len = (sizeof (cpp_string)); if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1-> next_free); }) < __len) _obstack_newchunk (__o, __len); memcpy (__o->next_free, &str, __len); __o->next_free += __len ; (void) 0; }); |
4539 | obstack_grow (&loc_ob, &tok->location, sizeof (location_t))__extension__ ({ struct obstack *__o = (&loc_ob); size_t __len = (sizeof (location_t)); if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit - __o1-> next_free); }) < __len) _obstack_newchunk (__o, __len); memcpy (__o->next_free, &tok->location, __len); __o->next_free += __len; (void) 0; }); |
4540 | |
4541 | last_tok_loc = tok->location; |
4542 | |
4543 | tok = cp_lexer_peek_token (parser->lexer); |
4544 | if (cpp_userdef_string_p (tok->type)) |
4545 | { |
4546 | if (!udl_ok) |
4547 | { |
4548 | error_at (loc, "string literal with user-defined suffix " |
4549 | "is invalid in this context"); |
4550 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4551 | } |
4552 | string_tree = USERDEF_LITERAL_VALUE (tok->u.value)(((struct tree_userdef_literal *)(tree_check ((tok->u.value ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4552, __FUNCTION__, (USERDEF_LITERAL))))->value); |
4553 | curr_type = cpp_userdef_string_remove_type (tok->type); |
4554 | curr_tok_is_userdef_p = true; |
4555 | } |
4556 | else |
4557 | { |
4558 | string_tree = tok->u.value; |
4559 | curr_type = tok->type; |
4560 | curr_tok_is_userdef_p = false; |
4561 | } |
4562 | } |
4563 | while (cp_parser_is_string_literal (tok)); |
4564 | |
4565 | /* A string literal built by concatenation has its caret=start at |
4566 | the start of the initial string, and its finish at the finish of |
4567 | the final string literal. */ |
4568 | loc = make_location (loc, loc, get_finish (last_tok_loc)); |
4569 | |
4570 | strs = (cpp_string *) obstack_finish (&str_ob)__extension__ ({ struct obstack *__o1 = (&str_ob); void * __value = (void *) __o1->object_base; if (__o1->next_free == __value) __o1->maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1->object_base ) + (((__o1->next_free) - (__o1->object_base) + (__o1-> alignment_mask)) & ~(__o1->alignment_mask))) : (char * ) (((ptrdiff_t) (__o1->next_free) + (__o1->alignment_mask )) & ~(__o1->alignment_mask))); if ((size_t) (__o1-> next_free - (char *) __o1->chunk) > (size_t) (__o1-> chunk_limit - (char *) __o1->chunk)) __o1->next_free = __o1 ->chunk_limit; __o1->object_base = __o1->next_free; __value ; }); |
4571 | } |
4572 | |
4573 | if (type != CPP_STRING && !wide_ok) |
4574 | { |
4575 | cp_parser_error (parser, "a wide string is invalid in this context"); |
4576 | type = CPP_STRING; |
4577 | } |
4578 | |
4579 | if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate) |
4580 | (parse_in, strs, count, &istr, type)) |
4581 | { |
4582 | value = build_string (istr.len, (const char *)istr.text); |
4583 | free (CONST_CAST (unsigned char *, istr.text)(const_cast<unsigned char *> ((istr.text)))); |
4584 | if (count > 1) |
4585 | { |
4586 | location_t *locs = (location_t *)obstack_finish (&loc_ob)__extension__ ({ struct obstack *__o1 = (&loc_ob); void * __value = (void *) __o1->object_base; if (__o1->next_free == __value) __o1->maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1->object_base ) + (((__o1->next_free) - (__o1->object_base) + (__o1-> alignment_mask)) & ~(__o1->alignment_mask))) : (char * ) (((ptrdiff_t) (__o1->next_free) + (__o1->alignment_mask )) & ~(__o1->alignment_mask))); if ((size_t) (__o1-> next_free - (char *) __o1->chunk) > (size_t) (__o1-> chunk_limit - (char *) __o1->chunk)) __o1->next_free = __o1 ->chunk_limit; __o1->object_base = __o1->next_free; __value ; }); |
4587 | gcc_assert (g_string_concat_db)((void)(!(g_string_concat_db) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4587, __FUNCTION__), 0 : 0)); |
4588 | g_string_concat_db->record_string_concatenation (count, locs); |
4589 | } |
4590 | |
4591 | switch (type) |
4592 | { |
4593 | default: |
4594 | case CPP_STRING: |
4595 | TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4595, __FUNCTION__))->typed.type) = char_array_type_nodec_global_trees[CTI_CHAR_ARRAY_TYPE]; |
4596 | break; |
4597 | case CPP_UTF8STRING: |
4598 | if (flag_char8_tglobal_options.x_flag_char8_t) |
4599 | TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4599, __FUNCTION__))->typed.type) = char8_array_type_nodec_global_trees[CTI_CHAR8_ARRAY_TYPE]; |
4600 | else |
4601 | TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4601, __FUNCTION__))->typed.type) = char_array_type_nodec_global_trees[CTI_CHAR_ARRAY_TYPE]; |
4602 | break; |
4603 | case CPP_STRING16: |
4604 | TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4604, __FUNCTION__))->typed.type) = char16_array_type_nodec_global_trees[CTI_CHAR16_ARRAY_TYPE]; |
4605 | break; |
4606 | case CPP_STRING32: |
4607 | TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4607, __FUNCTION__))->typed.type) = char32_array_type_nodec_global_trees[CTI_CHAR32_ARRAY_TYPE]; |
4608 | break; |
4609 | case CPP_WSTRING: |
4610 | TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4610, __FUNCTION__))->typed.type) = wchar_array_type_nodec_global_trees[CTI_WCHAR_ARRAY_TYPE]; |
4611 | break; |
4612 | } |
4613 | |
4614 | value = fix_string_type (value); |
4615 | |
4616 | if (have_suffix_p) |
4617 | { |
4618 | tree literal = build_userdef_literal (suffix_id, value, |
4619 | OT_NONE, NULL_TREE(tree) __null); |
4620 | if (lookup_udlit) |
4621 | value = finish_userdef_string_literal (literal); |
4622 | else |
4623 | value = literal; |
4624 | } |
4625 | } |
4626 | else |
4627 | /* cpp_interpret_string has issued an error. */ |
4628 | value = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4629 | |
4630 | if (count > 1) |
4631 | { |
4632 | obstack_free (&str_ob, 0)__extension__ ({ struct obstack *__o = (&str_ob); void *__obj = (void *) (0); if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o , __obj); }); |
4633 | obstack_free (&loc_ob, 0)__extension__ ({ struct obstack *__o = (&loc_ob); void *__obj = (void *) (0); if (__obj > (void *) __o->chunk && __obj < (void *) __o->chunk_limit) __o->next_free = __o->object_base = (char *) __obj; else _obstack_free (__o , __obj); }); |
4634 | } |
4635 | |
4636 | return cp_expr (value, loc); |
4637 | } |
4638 | |
4639 | /* Parse a sequence of adjacent string constants. Return a TREE_STRING |
4640 | representing the combined, nul-terminated string constant. If |
4641 | TRANSLATE is true, translate the string to the execution character set. |
4642 | If WIDE_OK is true, a wide string is valid here. |
4643 | |
4644 | This function issues an error if a user defined string literal is |
4645 | encountered; use cp_parser_userdef_string_literal if UDLs are allowed. */ |
4646 | |
4647 | static inline cp_expr |
4648 | cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok) |
4649 | { |
4650 | return cp_parser_string_literal_common (parser, translate, wide_ok, |
4651 | /*udl_ok=*/false, |
4652 | /*lookup_udlit=*/false); |
4653 | } |
4654 | |
4655 | /* Parse a string literal or user defined string literal. |
4656 | |
4657 | user-defined-string-literal : |
4658 | string-literal ud-suffix |
4659 | |
4660 | If LOOKUP_UDLIT, perform a lookup for a suitable template function. */ |
4661 | |
4662 | static inline cp_expr |
4663 | cp_parser_userdef_string_literal (cp_parser *parser, bool lookup_udlit) |
4664 | { |
4665 | return cp_parser_string_literal_common (parser, /*translate=*/true, |
4666 | /*wide_ok=*/true, /*udl_ok=*/true, |
4667 | lookup_udlit); |
4668 | } |
4669 | |
4670 | /* Look up a literal operator with the name and the exact arguments. */ |
4671 | |
4672 | static tree |
4673 | lookup_literal_operator (tree name, vec<tree, va_gc> *args) |
4674 | { |
4675 | tree decl = lookup_name (name); |
4676 | if (!decl || !is_overloaded_fn (decl)) |
4677 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4678 | |
4679 | for (lkp_iterator iter (decl); iter; ++iter) |
4680 | { |
4681 | tree fn = *iter; |
4682 | |
4683 | if (tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn))((tree_check2 ((((contains_struct_check ((fn), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4683, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4683, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common .values)) |
4684 | { |
4685 | unsigned int ix; |
4686 | bool found = true; |
4687 | |
4688 | for (ix = 0; |
4689 | found && ix < vec_safe_length (args) && parmtypes != NULL_TREE(tree) __null; |
4690 | ++ix, parmtypes = TREE_CHAIN (parmtypes)((contains_struct_check ((parmtypes), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4690, __FUNCTION__))->common.chain)) |
4691 | { |
4692 | tree tparm = TREE_VALUE (parmtypes)((tree_check ((parmtypes), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4692, __FUNCTION__, (TREE_LIST)))->list.value); |
4693 | tree targ = TREE_TYPE ((*args)[ix])((contains_struct_check (((*args)[ix]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4693, __FUNCTION__))->typed.type); |
4694 | bool ptr = TYPE_PTR_P (tparm)(((enum tree_code) (tparm)->base.code) == POINTER_TYPE); |
4695 | bool arr = TREE_CODE (targ)((enum tree_code) (targ)->base.code) == ARRAY_TYPE; |
4696 | if ((ptr || arr || !same_type_p (tparm, targ)comptypes ((tparm), (targ), 0)) |
4697 | && (!ptr || !arr |
4698 | || !same_type_p (TREE_TYPE (tparm),comptypes ((((contains_struct_check ((tparm), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4698, __FUNCTION__))->typed.type)), (((contains_struct_check ((targ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4699, __FUNCTION__))->typed.type)), 0) |
4699 | TREE_TYPE (targ))comptypes ((((contains_struct_check ((tparm), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4698, __FUNCTION__))->typed.type)), (((contains_struct_check ((targ), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4699, __FUNCTION__))->typed.type)), 0))) |
4700 | found = false; |
4701 | } |
4702 | |
4703 | if (found |
4704 | && ix == vec_safe_length (args) |
4705 | /* May be this should be sufficient_parms_p instead, |
4706 | depending on how exactly should user-defined literals |
4707 | work in presence of default arguments on the literal |
4708 | operator parameters. */ |
4709 | && parmtypes == void_list_nodeglobal_trees[TI_VOID_LIST_NODE]) |
4710 | return decl; |
4711 | } |
4712 | } |
4713 | |
4714 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4715 | } |
4716 | |
4717 | /* Parse a user-defined char constant. Returns a call to a user-defined |
4718 | literal operator taking the character as an argument. */ |
4719 | |
4720 | static cp_expr |
4721 | cp_parser_userdef_char_literal (cp_parser *parser) |
4722 | { |
4723 | cp_token *token = cp_lexer_consume_token (parser->lexer); |
4724 | tree literal = token->u.value; |
4725 | tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4725, __FUNCTION__, (USERDEF_LITERAL))))->suffix_id); |
4726 | tree value = USERDEF_LITERAL_VALUE (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4726, __FUNCTION__, (USERDEF_LITERAL))))->value); |
4727 | tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id)((const char *) (tree_check ((suffix_id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4727, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); |
4728 | tree decl, result; |
4729 | |
4730 | /* Build up a call to the user-defined operator */ |
4731 | /* Lookup the name we got back from the id-expression. */ |
4732 | releasing_vec args; |
4733 | vec_safe_push (args, value); |
4734 | decl = lookup_literal_operator (name, args); |
4735 | if (!decl || decl == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4736 | { |
4737 | error ("unable to find character literal operator %qD with %qT argument", |
4738 | name, TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4738, __FUNCTION__))->typed.type)); |
4739 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4740 | } |
4741 | result = finish_call_expr (decl, &args, false, true, tf_warning_or_error); |
4742 | return result; |
4743 | } |
4744 | |
4745 | /* A subroutine of cp_parser_userdef_numeric_literal to |
4746 | create a char... template parameter pack from a string node. */ |
4747 | |
4748 | static tree |
4749 | make_char_string_pack (tree value) |
4750 | { |
4751 | tree charvec; |
4752 | tree argpack = make_node (NONTYPE_ARGUMENT_PACK); |
4753 | const unsigned char *str |
4754 | = (const unsigned char *) TREE_STRING_POINTER (value)((const char *)((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4754, __FUNCTION__, (STRING_CST)))->string.str)); |
4755 | int i, len = TREE_STRING_LENGTH (value)((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4755, __FUNCTION__, (STRING_CST)))->string.length) - 1; |
4756 | tree argvec = make_tree_vec (1); |
4757 | |
4758 | /* Fill in CHARVEC with all of the parameters. */ |
4759 | charvec = make_tree_vec (len); |
4760 | for (i = 0; i < len; ++i) |
4761 | { |
4762 | unsigned char s[3] = { '\'', str[i], '\'' }; |
4763 | cpp_string in = { 3, s }; |
4764 | cpp_string out = { 0, 0 }; |
4765 | if (!cpp_interpret_string (parse_in, &in, 1, &out, CPP_STRING)) |
4766 | return NULL_TREE(tree) __null; |
4767 | gcc_assert (out.len == 2)((void)(!(out.len == 2) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4767, __FUNCTION__), 0 : 0)); |
4768 | TREE_VEC_ELT (charvec, i)(*((const_cast<tree *> (tree_vec_elt_check ((charvec), ( i), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4768, __FUNCTION__))))) = build_int_cst (char_type_nodeinteger_types[itk_char], |
4769 | out.text[0]); |
4770 | } |
4771 | |
4772 | /* Build the argument packs. */ |
4773 | ARGUMENT_PACK_ARGS (argpack)(((enum tree_code) ((tree_check2 ((argpack), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4773, __FUNCTION__, (TYPE_ARGUMENT_PACK), (NONTYPE_ARGUMENT_PACK ))))->base.code) == TYPE_ARGUMENT_PACK ? ((contains_struct_check ((argpack), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4773, __FUNCTION__))->typed.type) : (*((const_cast<tree *> (tree_operand_check ((argpack), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4773, __FUNCTION__)))))) = charvec; |
4774 | |
4775 | TREE_VEC_ELT (argvec, 0)(*((const_cast<tree *> (tree_vec_elt_check ((argvec), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4775, __FUNCTION__))))) = argpack; |
4776 | |
4777 | return argvec; |
4778 | } |
4779 | |
4780 | /* A subroutine of cp_parser_userdef_numeric_literal to |
4781 | create a char... template parameter pack from a string node. */ |
4782 | |
4783 | static tree |
4784 | make_string_pack (tree value) |
4785 | { |
4786 | tree charvec; |
4787 | tree argpack = make_node (NONTYPE_ARGUMENT_PACK); |
4788 | const unsigned char *str |
4789 | = (const unsigned char *) TREE_STRING_POINTER (value)((const char *)((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4789, __FUNCTION__, (STRING_CST)))->string.str)); |
4790 | int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value))))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((((contains_struct_check ((((contains_struct_check ((value) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4790, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4790, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4790, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4790, __FUNCTION__))); |
4791 | int len = TREE_STRING_LENGTH (value)((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4791, __FUNCTION__, (STRING_CST)))->string.length) / sz - 1; |
4792 | tree argvec = make_tree_vec (2); |
4793 | |
4794 | tree str_char_type_node = TREE_TYPE (TREE_TYPE (value))((contains_struct_check ((((contains_struct_check ((value), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4794, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4794, __FUNCTION__))->typed.type); |
4795 | str_char_type_node = TYPE_MAIN_VARIANT (str_char_type_node)((tree_class_check ((str_char_type_node), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4795, __FUNCTION__))->type_common.main_variant); |
4796 | |
4797 | /* First template parm is character type. */ |
4798 | TREE_VEC_ELT (argvec, 0)(*((const_cast<tree *> (tree_vec_elt_check ((argvec), ( 0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4798, __FUNCTION__))))) = str_char_type_node; |
4799 | |
4800 | /* Fill in CHARVEC with all of the parameters. */ |
4801 | charvec = make_tree_vec (len); |
4802 | for (int i = 0; i < len; ++i) |
4803 | TREE_VEC_ELT (charvec, i)(*((const_cast<tree *> (tree_vec_elt_check ((charvec), ( i), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4803, __FUNCTION__))))) |
4804 | = double_int_to_tree (str_char_type_node, |
4805 | double_int::from_buffer (str + i * sz, sz)); |
4806 | |
4807 | /* Build the argument packs. */ |
4808 | ARGUMENT_PACK_ARGS (argpack)(((enum tree_code) ((tree_check2 ((argpack), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4808, __FUNCTION__, (TYPE_ARGUMENT_PACK), (NONTYPE_ARGUMENT_PACK ))))->base.code) == TYPE_ARGUMENT_PACK ? ((contains_struct_check ((argpack), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4808, __FUNCTION__))->typed.type) : (*((const_cast<tree *> (tree_operand_check ((argpack), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4808, __FUNCTION__)))))) = charvec; |
4809 | |
4810 | TREE_VEC_ELT (argvec, 1)(*((const_cast<tree *> (tree_vec_elt_check ((argvec), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4810, __FUNCTION__))))) = argpack; |
4811 | |
4812 | return argvec; |
4813 | } |
4814 | |
4815 | /* Parse a user-defined numeric constant. returns a call to a user-defined |
4816 | literal operator. */ |
4817 | |
4818 | static cp_expr |
4819 | cp_parser_userdef_numeric_literal (cp_parser *parser) |
4820 | { |
4821 | cp_token *token = cp_lexer_consume_token (parser->lexer); |
4822 | tree literal = token->u.value; |
4823 | tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4823, __FUNCTION__, (USERDEF_LITERAL))))->suffix_id); |
4824 | tree value = USERDEF_LITERAL_VALUE (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4824, __FUNCTION__, (USERDEF_LITERAL))))->value); |
4825 | int overflow = USERDEF_LITERAL_OVERFLOW (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4825, __FUNCTION__, (USERDEF_LITERAL))))->overflow); |
4826 | tree num_string = USERDEF_LITERAL_NUM_STRING (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4826, __FUNCTION__, (USERDEF_LITERAL))))->num_string); |
4827 | tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id)((const char *) (tree_check ((suffix_id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4827, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); |
4828 | tree decl, result; |
4829 | |
4830 | /* Look for a literal operator taking the exact type of numeric argument |
4831 | as the literal value. */ |
4832 | releasing_vec args; |
4833 | vec_safe_push (args, value); |
4834 | decl = lookup_literal_operator (name, args); |
4835 | if (decl && decl != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4836 | { |
4837 | result = finish_call_expr (decl, &args, false, true, |
4838 | tf_warning_or_error); |
4839 | |
4840 | if (TREE_CODE (TREE_TYPE (value))((enum tree_code) (((contains_struct_check ((value), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4840, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE && overflow > 0) |
4841 | { |
4842 | warning_at (token->location, OPT_Woverflow, |
4843 | "integer literal exceeds range of %qT type", |
4844 | long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]); |
4845 | } |
4846 | else |
4847 | { |
4848 | if (overflow > 0) |
4849 | warning_at (token->location, OPT_Woverflow, |
4850 | "floating literal exceeds range of %qT type", |
4851 | long_double_type_nodeglobal_trees[TI_LONG_DOUBLE_TYPE]); |
4852 | else if (overflow < 0) |
4853 | warning_at (token->location, OPT_Woverflow, |
4854 | "floating literal truncated to zero"); |
4855 | } |
4856 | |
4857 | return result; |
4858 | } |
4859 | |
4860 | /* If the numeric argument didn't work, look for a raw literal |
4861 | operator taking a const char* argument consisting of the number |
4862 | in string format. */ |
4863 | args->truncate (0); |
4864 | vec_safe_push (args, num_string); |
4865 | decl = lookup_literal_operator (name, args); |
4866 | if (decl && decl != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4867 | { |
4868 | result = finish_call_expr (decl, &args, false, true, |
4869 | tf_warning_or_error); |
4870 | return result; |
4871 | } |
4872 | |
4873 | /* If the raw literal didn't work, look for a non-type template |
4874 | function with parameter pack char.... Call the function with |
4875 | template parameter characters representing the number. */ |
4876 | args->truncate (0); |
4877 | decl = lookup_literal_operator (name, args); |
4878 | if (decl && decl != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4879 | { |
4880 | tree tmpl_args = make_char_string_pack (num_string); |
4881 | if (tmpl_args == NULL_TREE(tree) __null) |
4882 | { |
4883 | error ("failed to translate literal to execution character set %qT", |
4884 | num_string); |
4885 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4886 | } |
4887 | decl = lookup_template_function (decl, tmpl_args); |
4888 | result = finish_call_expr (decl, &args, false, true, |
4889 | tf_warning_or_error); |
4890 | return result; |
4891 | } |
4892 | |
4893 | /* In C++14 the standard library defines complex number suffixes that |
4894 | conflict with GNU extensions. Prefer them if <complex> is #included. */ |
4895 | bool ext = cpp_get_options (parse_in)->ext_numeric_literals; |
4896 | bool i14 = (cxx_dialect > cxx11 |
4897 | && (id_equal (suffix_id, "i") |
4898 | || id_equal (suffix_id, "if") |
4899 | || id_equal (suffix_id, "il"))); |
4900 | diagnostic_t kind = DK_ERROR; |
4901 | int opt = 0; |
4902 | |
4903 | if (i14 && ext) |
4904 | { |
4905 | tree cxlit = lookup_qualified_name (std_nodecp_global_trees[CPTI_STD], "complex_literals", |
4906 | LOOK_want::NORMAL, false); |
4907 | if (cxlit == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4908 | { |
4909 | /* No <complex>, so pedwarn and use GNU semantics. */ |
4910 | kind = DK_PEDWARN; |
4911 | opt = OPT_Wpedantic; |
4912 | } |
4913 | } |
4914 | |
4915 | bool complained |
4916 | = emit_diagnostic (kind, input_location, opt, |
4917 | "unable to find numeric literal operator %qD", name); |
4918 | |
4919 | if (!complained) |
4920 | /* Don't inform either. */; |
4921 | else if (i14) |
4922 | { |
4923 | inform (token->location, "add %<using namespace std::complex_literals%> " |
4924 | "(from %<<complex>%>) to enable the C++14 user-defined literal " |
4925 | "suffixes"); |
4926 | if (ext) |
4927 | inform (token->location, "or use %<j%> instead of %<i%> for the " |
4928 | "GNU built-in suffix"); |
4929 | } |
4930 | else if (!ext) |
4931 | inform (token->location, "use %<-fext-numeric-literals%> " |
4932 | "to enable more built-in suffixes"); |
4933 | |
4934 | if (kind == DK_ERROR) |
4935 | value = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
4936 | else |
4937 | { |
4938 | /* Use the built-in semantics. */ |
4939 | tree type; |
4940 | if (id_equal (suffix_id, "i")) |
4941 | { |
4942 | if (TREE_CODE (value)((enum tree_code) (value)->base.code) == INTEGER_CST) |
4943 | type = integer_type_nodeinteger_types[itk_int]; |
4944 | else |
4945 | type = double_type_nodeglobal_trees[TI_DOUBLE_TYPE]; |
4946 | } |
4947 | else if (id_equal (suffix_id, "if")) |
4948 | type = float_type_nodeglobal_trees[TI_FLOAT_TYPE]; |
4949 | else /* if (id_equal (suffix_id, "il")) */ |
4950 | type = long_double_type_nodeglobal_trees[TI_LONG_DOUBLE_TYPE]; |
4951 | |
4952 | value = fold_build2 (COMPLEX_EXPR, build_complex_type (type),fold_build2_loc (((location_t) 0), COMPLEX_EXPR, build_complex_type (type), build_zero_cst (type), fold_convert_loc (((location_t ) 0), type, value) ) |
4953 | build_zero_cst (type), fold_convert (type, value))fold_build2_loc (((location_t) 0), COMPLEX_EXPR, build_complex_type (type), build_zero_cst (type), fold_convert_loc (((location_t ) 0), type, value) ); |
4954 | } |
4955 | |
4956 | if (cp_parser_uncommitted_to_tentative_parse_p (parser)) |
4957 | /* Avoid repeated diagnostics. */ |
4958 | token->u.value = value; |
4959 | return value; |
4960 | } |
4961 | |
4962 | /* Parse a user-defined string constant. Returns a call to a user-defined |
4963 | literal operator taking a character pointer and the length of the string |
4964 | as arguments. */ |
4965 | |
4966 | static tree |
4967 | finish_userdef_string_literal (tree literal) |
4968 | { |
4969 | tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4969, __FUNCTION__, (USERDEF_LITERAL))))->suffix_id); |
4970 | tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id)((const char *) (tree_check ((suffix_id), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4970, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); |
4971 | tree value = USERDEF_LITERAL_VALUE (literal)(((struct tree_userdef_literal *)(tree_check ((literal), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4971, __FUNCTION__, (USERDEF_LITERAL))))->value); |
4972 | int len = TREE_STRING_LENGTH (value)((tree_check ((value), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4972, __FUNCTION__, (STRING_CST)))->string.length) |
4973 | / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value))))((unsigned long) (*tree_int_cst_elt_check ((((tree_class_check ((((contains_struct_check ((((contains_struct_check ((value) , (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4973, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4973, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4973, __FUNCTION__))->type_common.size_unit)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4973, __FUNCTION__))) - 1; |
4974 | tree decl; |
4975 | |
4976 | /* Build up a call to the user-defined operator. */ |
4977 | /* Lookup the name we got back from the id-expression. */ |
4978 | releasing_vec args; |
4979 | vec_safe_push (args, value); |
4980 | vec_safe_push (args, build_int_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE], len)); |
4981 | decl = lookup_literal_operator (name, args); |
4982 | |
4983 | if (decl && decl != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4984 | return finish_call_expr (decl, &args, false, true, |
4985 | tf_warning_or_error); |
4986 | |
4987 | /* Look for a suitable template function, either (C++20) with a single |
4988 | parameter of class type, or (N3599) with typename parameter CharT and |
4989 | parameter pack CharT... */ |
4990 | args->truncate (0); |
4991 | decl = lookup_literal_operator (name, args); |
4992 | if (decl && decl != error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
4993 | { |
4994 | /* Use resolve_nondeduced_context to try to choose one form of template |
4995 | or the other. */ |
4996 | tree tmpl_args = make_tree_vec (1); |
4997 | TREE_VEC_ELT (tmpl_args, 0)(*((const_cast<tree *> (tree_vec_elt_check ((tmpl_args) , (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 4997, __FUNCTION__))))) = value; |
4998 | decl = lookup_template_function (decl, tmpl_args); |
4999 | tree res = resolve_nondeduced_context (decl, tf_none); |
5000 | if (DECL_P (res)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (res)->base.code))] == tcc_declaration)) |
5001 | decl = res; |
5002 | else |
5003 | { |
5004 | TREE_OPERAND (decl, 1)(*((const_cast<tree*> (tree_operand_check ((decl), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5004, __FUNCTION__))))) = make_string_pack (value); |
5005 | res = resolve_nondeduced_context (decl, tf_none); |
5006 | if (DECL_P (res)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (res)->base.code))] == tcc_declaration)) |
5007 | decl = res; |
5008 | } |
5009 | if (!DECL_P (decl)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code ) (decl)->base.code))] == tcc_declaration) && cxx_dialect > cxx17) |
5010 | TREE_OPERAND (decl, 1)(*((const_cast<tree*> (tree_operand_check ((decl), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5010, __FUNCTION__))))) = tmpl_args; |
5011 | return finish_call_expr (decl, &args, false, true, |
5012 | tf_warning_or_error); |
5013 | } |
5014 | |
5015 | error ("unable to find string literal operator %qD with %qT, %qT arguments", |
5016 | name, TREE_TYPE (value)((contains_struct_check ((value), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5016, __FUNCTION__))->typed.type), size_type_nodeglobal_trees[TI_SIZE_TYPE]); |
5017 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5018 | } |
5019 | |
5020 | |
5021 | /* Basic concepts [gram.basic] */ |
5022 | |
5023 | /* Parse a translation-unit. |
5024 | |
5025 | translation-unit: |
5026 | declaration-seq [opt] */ |
5027 | |
5028 | static void |
5029 | cp_parser_translation_unit (cp_parser* parser) |
5030 | { |
5031 | gcc_checking_assert (!cp_error_declarator)((void)(!(!cp_error_declarator) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5031, __FUNCTION__), 0 : 0)); |
5032 | |
5033 | /* Create the declarator obstack. */ |
5034 | gcc_obstack_init (&declarator_obstack)_obstack_begin (((&declarator_obstack)), (memory_block_pool ::block_size), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free )); |
5035 | /* Create the error declarator. */ |
5036 | cp_error_declarator = make_declarator (cdk_error); |
5037 | /* Create the empty parameter list. */ |
5038 | no_parameters = make_parameter_declarator (NULL__null, NULL__null, NULL_TREE(tree) __null, |
5039 | UNKNOWN_LOCATION((location_t) 0)); |
5040 | /* Remember where the base of the declarator obstack lies. */ |
5041 | void *declarator_obstack_base = obstack_next_free (&declarator_obstack)((void *) (&declarator_obstack)->next_free); |
5042 | |
5043 | push_deferring_access_checks (flag_access_controlglobal_options.x_flag_access_control |
5044 | ? dk_no_deferred : dk_no_check); |
5045 | |
5046 | module_parse mp_state = MP_NOT_MODULE; |
5047 | if (modules_p () && !header_module_p ()) |
5048 | mp_state = MP_FIRST; |
5049 | |
5050 | bool implicit_extern_c = false; |
5051 | |
5052 | /* Parse until EOF. */ |
5053 | for (;;) |
5054 | { |
5055 | cp_token *token = cp_lexer_peek_token (parser->lexer); |
5056 | |
5057 | /* If we're entering or exiting a region that's implicitly |
5058 | extern "C", modify the lang context appropriately. This is |
5059 | so horrible. Please die. */ |
5060 | if (implicit_extern_c |
5061 | != cp_lexer_peek_token (parser->lexer)->implicit_extern_c) |
5062 | { |
5063 | implicit_extern_c = !implicit_extern_c; |
5064 | if (implicit_extern_c) |
5065 | push_lang_context (lang_name_ccp_global_trees[CPTI_LANG_NAME_C]); |
5066 | else |
5067 | pop_lang_context (); |
5068 | } |
5069 | |
5070 | if (token->type == CPP_EOF) |
5071 | break; |
5072 | |
5073 | if (modules_p ()) |
5074 | { |
5075 | /* Top-level module declarations are ok, and change the |
5076 | portion of file we're in. Top-level import declarations |
5077 | are significant for the import portions. */ |
5078 | |
5079 | cp_token *next = token; |
5080 | bool exporting = token->keyword == RID__EXPORT; |
5081 | if (exporting) |
5082 | { |
5083 | cp_lexer_consume_token (parser->lexer); |
5084 | next = cp_lexer_peek_token (parser->lexer); |
5085 | } |
5086 | if (next->keyword == RID__MODULE) |
5087 | { |
5088 | mp_state |
5089 | = cp_parser_module_declaration (parser, mp_state, exporting); |
5090 | continue; |
5091 | } |
5092 | else if (next->keyword == RID__IMPORT) |
5093 | { |
5094 | if (mp_state == MP_FIRST) |
5095 | mp_state = MP_NOT_MODULE; |
5096 | cp_parser_import_declaration (parser, mp_state, exporting); |
5097 | continue; |
5098 | } |
5099 | else |
5100 | gcc_checking_assert (!exporting)((void)(!(!exporting) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5100, __FUNCTION__), 0 : 0)); |
5101 | |
5102 | if (mp_state == MP_GLOBAL && token->main_source_p) |
5103 | { |
5104 | static bool warned = false; |
5105 | if (!warned) |
5106 | { |
5107 | warned = true; |
5108 | error_at (token->location, |
5109 | "global module fragment contents must be" |
5110 | " from preprocessor inclusion"); |
5111 | } |
5112 | } |
5113 | } |
5114 | |
5115 | /* This relies on the ordering of module_parse values. */ |
5116 | if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS) |
5117 | /* We're no longer in the import portion of a named module. */ |
5118 | mp_state = module_parse (mp_state + 1); |
5119 | else if (mp_state == MP_FIRST) |
5120 | mp_state = MP_NOT_MODULE; |
5121 | |
5122 | if (token->type == CPP_CLOSE_BRACE) |
5123 | { |
5124 | cp_parser_error (parser, "expected declaration"); |
5125 | cp_lexer_consume_token (parser->lexer); |
5126 | /* If the next token is now a `;', consume it. */ |
5127 | if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) |
5128 | cp_lexer_consume_token (parser->lexer); |
5129 | } |
5130 | else |
5131 | cp_parser_toplevel_declaration (parser); |
5132 | } |
5133 | |
5134 | /* Get rid of the token array; we don't need it any more. */ |
5135 | cp_lexer_destroy (parser->lexer); |
5136 | parser->lexer = NULL__null; |
5137 | |
5138 | /* The EOF should have reset this. */ |
5139 | gcc_checking_assert (!implicit_extern_c)((void)(!(!implicit_extern_c) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5139, __FUNCTION__), 0 : 0)); |
5140 | |
5141 | /* Make sure the declarator obstack was fully cleaned up. */ |
5142 | gcc_assert (obstack_next_free (&declarator_obstack)((void)(!(((void *) (&declarator_obstack)->next_free) == declarator_obstack_base) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5143, __FUNCTION__), 0 : 0)) |
5143 | == declarator_obstack_base)((void)(!(((void *) (&declarator_obstack)->next_free) == declarator_obstack_base) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5143, __FUNCTION__), 0 : 0)); |
5144 | } |
5145 | |
5146 | /* Return the appropriate tsubst flags for parsing, possibly in N3276 |
5147 | decltype context. */ |
5148 | |
5149 | static inline tsubst_flags_t |
5150 | complain_flags (bool decltype_p) |
5151 | { |
5152 | tsubst_flags_t complain = tf_warning_or_error; |
5153 | if (decltype_p) |
5154 | complain |= tf_decltype; |
5155 | return complain; |
5156 | } |
5157 | |
5158 | /* We're about to parse a collection of statements. If we're currently |
5159 | parsing tentatively, set up a firewall so that any nested |
5160 | cp_parser_commit_to_tentative_parse won't affect the current context. */ |
5161 | |
5162 | static cp_token_position |
5163 | cp_parser_start_tentative_firewall (cp_parser *parser) |
5164 | { |
5165 | if (!cp_parser_uncommitted_to_tentative_parse_p (parser)) |
5166 | return 0; |
5167 | |
5168 | cp_parser_parse_tentatively (parser); |
5169 | cp_parser_commit_to_topmost_tentative_parse (parser); |
5170 | return cp_lexer_token_position (parser->lexer, false); |
5171 | } |
5172 | |
5173 | /* We've finished parsing the collection of statements. Wrap up the |
5174 | firewall and replace the relevant tokens with the parsed form. */ |
5175 | |
5176 | static void |
5177 | cp_parser_end_tentative_firewall (cp_parser *parser, cp_token_position start, |
5178 | tree expr) |
5179 | { |
5180 | if (!start) |
5181 | return; |
5182 | |
5183 | /* Finish the firewall level. */ |
5184 | cp_parser_parse_definitely (parser); |
5185 | /* And remember the result of the parse for when we try again. */ |
5186 | cp_token *token = cp_lexer_token_at (parser->lexer, start); |
5187 | token->type = CPP_PREPARSED_EXPR((enum cpp_ttype) (((enum cpp_ttype) (((enum cpp_ttype) (((enum cpp_ttype) (CPP_KEYWORD + 1)) + 1)) + 1)) + 1)); |
5188 | token->u.value = expr; |
5189 | token->keyword = RID_MAX; |
5190 | cp_lexer_purge_tokens_after (parser->lexer, start); |
5191 | } |
5192 | |
5193 | /* Like the above functions, but let the user modify the tokens. Used by |
5194 | CPP_DECLTYPE and CPP_TEMPLATE_ID, where we are saving the side-effects for |
5195 | later parses, so it makes sense to localize the effects of |
5196 | cp_parser_commit_to_tentative_parse. */ |
5197 | |
5198 | struct tentative_firewall |
5199 | { |
5200 | cp_parser *parser; |
5201 | bool set; |
5202 | |
5203 | tentative_firewall (cp_parser *p): parser(p) |
5204 | { |
5205 | /* If we're currently parsing tentatively, start a committed level as a |
5206 | firewall and then an inner tentative parse. */ |
5207 | if ((set = cp_parser_uncommitted_to_tentative_parse_p (parser))) |
5208 | { |
5209 | cp_parser_parse_tentatively (parser); |
5210 | cp_parser_commit_to_topmost_tentative_parse (parser); |
5211 | cp_parser_parse_tentatively (parser); |
5212 | } |
5213 | } |
5214 | |
5215 | ~tentative_firewall() |
5216 | { |
5217 | if (set) |
5218 | { |
5219 | /* Finish the inner tentative parse and the firewall, propagating any |
5220 | uncommitted error state to the outer tentative parse. */ |
5221 | bool err = cp_parser_error_occurred (parser); |
5222 | cp_parser_parse_definitely (parser); |
5223 | cp_parser_parse_definitely (parser); |
5224 | if (err) |
5225 | cp_parser_simulate_error (parser); |
5226 | } |
5227 | } |
5228 | }; |
5229 | |
5230 | /* Some tokens naturally come in pairs e.g.'(' and ')'. |
5231 | This class is for tracking such a matching pair of symbols. |
5232 | In particular, it tracks the location of the first token, |
5233 | so that if the second token is missing, we can highlight the |
5234 | location of the first token when notifying the user about the |
5235 | problem. */ |
5236 | |
5237 | template <typename traits_t> |
5238 | class token_pair |
5239 | { |
5240 | public: |
5241 | /* token_pair's ctor. */ |
5242 | token_pair () : m_open_loc (UNKNOWN_LOCATION((location_t) 0)) {} |
5243 | |
5244 | /* If the next token is the opening symbol for this pair, consume it and |
5245 | return true. |
5246 | Otherwise, issue an error and return false. |
5247 | In either case, record the location of the opening token. */ |
5248 | |
5249 | bool require_open (cp_parser *parser) |
5250 | { |
5251 | m_open_loc = cp_lexer_peek_token (parser->lexer)->location; |
5252 | return cp_parser_require (parser, traits_t::open_token_type, |
5253 | traits_t::required_token_open); |
5254 | } |
5255 | |
5256 | /* Consume the next token from PARSER, recording its location as |
5257 | that of the opening token within the pair. */ |
5258 | |
5259 | cp_token * consume_open (cp_parser *parser) |
5260 | { |
5261 | cp_token *tok = cp_lexer_consume_token (parser->lexer); |
5262 | gcc_assert (tok->type == traits_t::open_token_type)((void)(!(tok->type == traits_t::open_token_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5262, __FUNCTION__), 0 : 0)); |
5263 | m_open_loc = tok->location; |
5264 | return tok; |
5265 | } |
5266 | |
5267 | /* If the next token is the closing symbol for this pair, consume it |
5268 | and return it. |
5269 | Otherwise, issue an error, highlighting the location of the |
5270 | corresponding opening token, and return NULL. */ |
5271 | |
5272 | cp_token *require_close (cp_parser *parser) const |
5273 | { |
5274 | return cp_parser_require (parser, traits_t::close_token_type, |
5275 | traits_t::required_token_close, |
5276 | m_open_loc); |
5277 | } |
5278 | |
5279 | location_t open_location () const { return m_open_loc; } |
5280 | |
5281 | private: |
5282 | location_t m_open_loc; |
5283 | }; |
5284 | |
5285 | /* Traits for token_pair<T> for tracking matching pairs of parentheses. */ |
5286 | |
5287 | struct matching_paren_traits |
5288 | { |
5289 | static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN; |
5290 | static const enum required_token required_token_open = RT_OPEN_PAREN; |
5291 | static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN; |
5292 | static const enum required_token required_token_close = RT_CLOSE_PAREN; |
5293 | }; |
5294 | |
5295 | /* "matching_parens" is a token_pair<T> class for tracking matching |
5296 | pairs of parentheses. */ |
5297 | |
5298 | typedef token_pair<matching_paren_traits> matching_parens; |
5299 | |
5300 | /* Traits for token_pair<T> for tracking matching pairs of braces. */ |
5301 | |
5302 | struct matching_brace_traits |
5303 | { |
5304 | static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE; |
5305 | static const enum required_token required_token_open = RT_OPEN_BRACE; |
5306 | static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE; |
5307 | static const enum required_token required_token_close = RT_CLOSE_BRACE; |
5308 | }; |
5309 | |
5310 | /* "matching_braces" is a token_pair<T> class for tracking matching |
5311 | pairs of braces. */ |
5312 | |
5313 | typedef token_pair<matching_brace_traits> matching_braces; |
5314 | |
5315 | |
5316 | /* Parse a GNU statement-expression, i.e. ({ stmts }), except for the |
5317 | enclosing parentheses. */ |
5318 | |
5319 | static cp_expr |
5320 | cp_parser_statement_expr (cp_parser *parser) |
5321 | { |
5322 | cp_token_position start = cp_parser_start_tentative_firewall (parser); |
5323 | |
5324 | /* Consume the '('. */ |
5325 | location_t start_loc = cp_lexer_peek_token (parser->lexer)->location; |
5326 | matching_parens parens; |
5327 | parens.consume_open (parser); |
5328 | /* Start the statement-expression. */ |
5329 | tree expr = begin_stmt_expr (); |
5330 | /* Parse the compound-statement. */ |
5331 | cp_parser_compound_statement (parser, expr, BCS_STMT_EXPR, false); |
5332 | /* Finish up. */ |
5333 | expr = finish_stmt_expr (expr, false); |
5334 | /* Consume the ')'. */ |
5335 | location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location; |
5336 | if (!parens.require_close (parser)) |
5337 | cp_parser_skip_to_end_of_statement (parser); |
5338 | |
5339 | cp_parser_end_tentative_firewall (parser, start, expr); |
5340 | location_t combined_loc = make_location (start_loc, start_loc, finish_loc); |
5341 | return cp_expr (expr, combined_loc); |
5342 | } |
5343 | |
5344 | /* Expressions [gram.expr] */ |
5345 | |
5346 | /* Parse a fold-operator. |
5347 | |
5348 | fold-operator: |
5349 | - * / % ^ & | = < > << >> |
5350 | = -= *= /= %= ^= &= |= <<= >>= |
5351 | == != <= >= && || , .* ->* |
5352 | |
5353 | This returns the tree code corresponding to the matched operator |
5354 | as an int. When the current token matches a compound assignment |
5355 | operator, the resulting tree code is the negative value of the |
5356 | non-assignment operator. */ |
5357 | |
5358 | static int |
5359 | cp_parser_fold_operator (cp_token *token) |
5360 | { |
5361 | switch (token->type) |
5362 | { |
5363 | case CPP_PLUS: return PLUS_EXPR; |
5364 | case CPP_MINUS: return MINUS_EXPR; |
5365 | case CPP_MULT: return MULT_EXPR; |
5366 | case CPP_DIV: return TRUNC_DIV_EXPR; |
5367 | case CPP_MOD: return TRUNC_MOD_EXPR; |
5368 | case CPP_XOR: return BIT_XOR_EXPR; |
5369 | case CPP_AND: return BIT_AND_EXPR; |
5370 | case CPP_OR: return BIT_IOR_EXPR; |
5371 | case CPP_LSHIFT: return LSHIFT_EXPR; |
5372 | case CPP_RSHIFT: return RSHIFT_EXPR; |
5373 | |
5374 | case CPP_EQ: return -NOP_EXPR; |
5375 | case CPP_PLUS_EQ: return -PLUS_EXPR; |
5376 | case CPP_MINUS_EQ: return -MINUS_EXPR; |
5377 | case CPP_MULT_EQ: return -MULT_EXPR; |
5378 | case CPP_DIV_EQ: return -TRUNC_DIV_EXPR; |
5379 | case CPP_MOD_EQ: return -TRUNC_MOD_EXPR; |
5380 | case CPP_XOR_EQ: return -BIT_XOR_EXPR; |
5381 | case CPP_AND_EQ: return -BIT_AND_EXPR; |
5382 | case CPP_OR_EQ: return -BIT_IOR_EXPR; |
5383 | case CPP_LSHIFT_EQ: return -LSHIFT_EXPR; |
5384 | case CPP_RSHIFT_EQ: return -RSHIFT_EXPR; |
5385 | |
5386 | case CPP_EQ_EQ: return EQ_EXPR; |
5387 | case CPP_NOT_EQ: return NE_EXPR; |
5388 | case CPP_LESS: return LT_EXPR; |
5389 | case CPP_GREATER: return GT_EXPR; |
5390 | case CPP_LESS_EQ: return LE_EXPR; |
5391 | case CPP_GREATER_EQ: return GE_EXPR; |
5392 | |
5393 | case CPP_AND_AND: return TRUTH_ANDIF_EXPR; |
5394 | case CPP_OR_OR: return TRUTH_ORIF_EXPR; |
5395 | |
5396 | case CPP_COMMA: return COMPOUND_EXPR; |
5397 | |
5398 | case CPP_DOT_STAR: return DOTSTAR_EXPR; |
5399 | case CPP_DEREF_STAR: return MEMBER_REF; |
5400 | |
5401 | default: return ERROR_MARK; |
5402 | } |
5403 | } |
5404 | |
5405 | /* Returns true if CODE indicates a binary expression, which is not allowed in |
5406 | the LHS of a fold-expression. More codes will need to be added to use this |
5407 | function in other contexts. */ |
5408 | |
5409 | static bool |
5410 | is_binary_op (tree_code code) |
5411 | { |
5412 | switch (code) |
5413 | { |
5414 | case PLUS_EXPR: |
5415 | case POINTER_PLUS_EXPR: |
5416 | case MINUS_EXPR: |
5417 | case MULT_EXPR: |
5418 | case TRUNC_DIV_EXPR: |
5419 | case TRUNC_MOD_EXPR: |
5420 | case BIT_XOR_EXPR: |
5421 | case BIT_AND_EXPR: |
5422 | case BIT_IOR_EXPR: |
5423 | case LSHIFT_EXPR: |
5424 | case RSHIFT_EXPR: |
5425 | |
5426 | case MODOP_EXPR: |
5427 | |
5428 | case EQ_EXPR: |
5429 | case NE_EXPR: |
5430 | case LE_EXPR: |
5431 | case GE_EXPR: |
5432 | case LT_EXPR: |
5433 | case GT_EXPR: |
5434 | |
5435 | case TRUTH_ANDIF_EXPR: |
5436 | case TRUTH_ORIF_EXPR: |
5437 | |
5438 | case COMPOUND_EXPR: |
5439 | |
5440 | case DOTSTAR_EXPR: |
5441 | case MEMBER_REF: |
5442 | return true; |
5443 | |
5444 | default: |
5445 | return false; |
5446 | } |
5447 | } |
5448 | |
5449 | /* If the next token is a suitable fold operator, consume it and return as |
5450 | the function above. */ |
5451 | |
5452 | static int |
5453 | cp_parser_fold_operator (cp_parser *parser) |
5454 | { |
5455 | cp_token* token = cp_lexer_peek_token (parser->lexer); |
5456 | int code = cp_parser_fold_operator (token); |
5457 | if (code != ERROR_MARK) |
5458 | cp_lexer_consume_token (parser->lexer); |
5459 | return code; |
5460 | } |
5461 | |
5462 | /* Parse a fold-expression. |
5463 | |
5464 | fold-expression: |
5465 | ( ... folding-operator cast-expression) |
5466 | ( cast-expression folding-operator ... ) |
5467 | ( cast-expression folding operator ... folding-operator cast-expression) |
5468 | |
5469 | Note that the '(' and ')' are matched in primary expression. */ |
5470 | |
5471 | static cp_expr |
5472 | cp_parser_fold_expression (cp_parser *parser, tree expr1) |
5473 | { |
5474 | cp_id_kind pidk; |
5475 | |
5476 | // Left fold. |
5477 | if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) |
5478 | { |
5479 | if (expr1) |
5480 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5481 | cp_lexer_consume_token (parser->lexer); |
5482 | int op = cp_parser_fold_operator (parser); |
5483 | if (op == ERROR_MARK) |
5484 | { |
5485 | cp_parser_error (parser, "expected binary operator"); |
5486 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5487 | } |
5488 | |
5489 | tree expr = cp_parser_cast_expression (parser, false, false, |
5490 | false, &pidk); |
5491 | if (expr == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
5492 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5493 | return finish_left_unary_fold_expr (expr, op); |
5494 | } |
5495 | |
5496 | const cp_token* token = cp_lexer_peek_token (parser->lexer); |
5497 | int op = cp_parser_fold_operator (parser); |
5498 | if (op == ERROR_MARK) |
5499 | { |
5500 | cp_parser_error (parser, "expected binary operator"); |
5501 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5502 | } |
5503 | |
5504 | if (cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)) |
5505 | { |
5506 | cp_parser_error (parser, "expected ..."); |
5507 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5508 | } |
5509 | cp_lexer_consume_token (parser->lexer); |
5510 | |
5511 | /* The operands of a fold-expression are cast-expressions, so binary or |
5512 | conditional expressions are not allowed. We check this here to avoid |
5513 | tentative parsing. */ |
5514 | if (EXPR_P (expr1)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (expr1)->base.code))]) >= tcc_reference && (tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code) (expr1)->base.code))]) <= tcc_expression) && warning_suppressed_p (expr1, OPT_Wparentheses)) |
5515 | /* OK, the expression was parenthesized. */; |
5516 | else if (is_binary_op (TREE_CODE (expr1)((enum tree_code) (expr1)->base.code))) |
5517 | error_at (location_of (expr1), |
5518 | "binary expression in operand of fold-expression"); |
5519 | else if (TREE_CODE (expr1)((enum tree_code) (expr1)->base.code) == COND_EXPR |
5520 | || (REFERENCE_REF_P (expr1)((((enum tree_code) (expr1)->base.code) == INDIRECT_REF) && ((contains_struct_check (((*((const_cast<tree*> (tree_operand_check ((expr1), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5520, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5520, __FUNCTION__))->typed.type) && (((enum tree_code ) (((contains_struct_check (((*((const_cast<tree*> (tree_operand_check (((expr1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5520, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5520, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
5521 | && TREE_CODE (TREE_OPERAND (expr1, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((expr1), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5521, __FUNCTION__))))))->base.code) == COND_EXPR)) |
5522 | error_at (location_of (expr1), |
5523 | "conditional expression in operand of fold-expression"); |
5524 | |
5525 | // Right fold. |
5526 | if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) |
5527 | return finish_right_unary_fold_expr (expr1, op); |
5528 | |
5529 | if (cp_lexer_next_token_is_not (parser->lexer, token->type)) |
5530 | { |
5531 | cp_parser_error (parser, "mismatched operator in fold-expression"); |
5532 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5533 | } |
5534 | cp_lexer_consume_token (parser->lexer); |
5535 | |
5536 | // Binary left or right fold. |
5537 | tree expr2 = cp_parser_cast_expression (parser, false, false, false, &pidk); |
5538 | if (expr2 == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
5539 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5540 | return finish_binary_fold_expr (expr1, expr2, op); |
5541 | } |
5542 | |
5543 | /* Parse a primary-expression. |
5544 | |
5545 | primary-expression: |
5546 | literal |
5547 | this |
5548 | ( expression ) |
5549 | id-expression |
5550 | lambda-expression (C++11) |
5551 | |
5552 | GNU Extensions: |
5553 | |
5554 | primary-expression: |
5555 | ( compound-statement ) |
5556 | __builtin_va_arg ( assignment-expression , type-id ) |
5557 | __builtin_offsetof ( type-id , offsetof-expression ) |
5558 | |
5559 | C++ Extensions: |
5560 | __has_nothrow_assign ( type-id ) |
5561 | __has_nothrow_constructor ( type-id ) |
5562 | __has_nothrow_copy ( type-id ) |
5563 | __has_trivial_assign ( type-id ) |
5564 | __has_trivial_constructor ( type-id ) |
5565 | __has_trivial_copy ( type-id ) |
5566 | __has_trivial_destructor ( type-id ) |
5567 | __has_virtual_destructor ( type-id ) |
5568 | __is_abstract ( type-id ) |
5569 | __is_base_of ( type-id , type-id ) |
5570 | __is_class ( type-id ) |
5571 | __is_empty ( type-id ) |
5572 | __is_enum ( type-id ) |
5573 | __is_final ( type-id ) |
5574 | __is_literal_type ( type-id ) |
5575 | __is_pod ( type-id ) |
5576 | __is_polymorphic ( type-id ) |
5577 | __is_std_layout ( type-id ) |
5578 | __is_trivial ( type-id ) |
5579 | __is_union ( type-id ) |
5580 | |
5581 | Objective-C++ Extension: |
5582 | |
5583 | primary-expression: |
5584 | objc-expression |
5585 | |
5586 | literal: |
5587 | __null |
5588 | |
5589 | ADDRESS_P is true iff this expression was immediately preceded by |
5590 | "&" and therefore might denote a pointer-to-member. CAST_P is true |
5591 | iff this expression is the target of a cast. TEMPLATE_ARG_P is |
5592 | true iff this expression is a template argument. |
5593 | |
5594 | Returns a representation of the expression. Upon return, *IDK |
5595 | indicates what kind of id-expression (if any) was present. */ |
5596 | |
5597 | static cp_expr |
5598 | cp_parser_primary_expression (cp_parser *parser, |
5599 | bool address_p, |
5600 | bool cast_p, |
5601 | bool template_arg_p, |
5602 | bool decltype_p, |
5603 | cp_id_kind *idk) |
5604 | { |
5605 | cp_token *token = NULL__null; |
5606 | |
5607 | /* Assume the primary expression is not an id-expression. */ |
5608 | *idk = CP_ID_KIND_NONE; |
5609 | |
5610 | /* Peek at the next token. */ |
5611 | token = cp_lexer_peek_token (parser->lexer); |
5612 | switch ((int) token->type) |
5613 | { |
5614 | /* literal: |
5615 | integer-literal |
5616 | character-literal |
5617 | floating-literal |
5618 | string-literal |
5619 | boolean-literal |
5620 | pointer-literal |
5621 | user-defined-literal */ |
5622 | case CPP_CHAR: |
5623 | case CPP_CHAR16: |
5624 | case CPP_CHAR32: |
5625 | case CPP_WCHAR: |
5626 | case CPP_UTF8CHAR: |
5627 | case CPP_NUMBER: |
5628 | case CPP_PREPARSED_EXPR((enum cpp_ttype) (((enum cpp_ttype) (((enum cpp_ttype) (((enum cpp_ttype) (CPP_KEYWORD + 1)) + 1)) + 1)) + 1)): |
5629 | if (TREE_CODE (token->u.value)((enum tree_code) (token->u.value)->base.code) == USERDEF_LITERAL) |
5630 | return cp_parser_userdef_numeric_literal (parser); |
5631 | token = cp_lexer_consume_token (parser->lexer); |
5632 | if (TREE_CODE (token->u.value)((enum tree_code) (token->u.value)->base.code) == FIXED_CST) |
5633 | { |
5634 | error_at (token->location, |
5635 | "fixed-point types not supported in C++"); |
5636 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5637 | } |
5638 | /* Floating-point literals are only allowed in an integral |
5639 | constant expression if they are cast to an integral or |
5640 | enumeration type. */ |
5641 | if ((TREE_CODE (token->u.value)((enum tree_code) (token->u.value)->base.code) == REAL_CST |
5642 | || (TREE_CODE (token->u.value)((enum tree_code) (token->u.value)->base.code) == EXCESS_PRECISION_EXPR |
5643 | && TREE_CODE (TREE_OPERAND (token->u.value, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check ((token->u.value), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5643, __FUNCTION__))))))->base.code) == REAL_CST)) |
5644 | && parser->integral_constant_expression_p |
5645 | && pedanticglobal_options.x_pedantic) |
5646 | { |
5647 | /* CAST_P will be set even in invalid code like "int(2.7 + |
5648 | ...)". Therefore, we have to check that the next token |
5649 | is sure to end the cast. */ |
5650 | if (cast_p) |
5651 | { |
5652 | cp_token *next_token; |
5653 | |
5654 | next_token = cp_lexer_peek_token (parser->lexer); |
5655 | if (/* The comma at the end of an |
5656 | enumerator-definition. */ |
5657 | next_token->type != CPP_COMMA |
5658 | /* The curly brace at the end of an enum-specifier. */ |
5659 | && next_token->type != CPP_CLOSE_BRACE |
5660 | /* The end of a statement. */ |
5661 | && next_token->type != CPP_SEMICOLON |
5662 | /* The end of the cast-expression. */ |
5663 | && next_token->type != CPP_CLOSE_PAREN |
5664 | /* The end of an array bound. */ |
5665 | && next_token->type != CPP_CLOSE_SQUARE |
5666 | /* The closing ">" in a template-argument-list. */ |
5667 | && (next_token->type != CPP_GREATER |
5668 | || parser->greater_than_is_operator_p) |
5669 | /* C++0x only: A ">>" treated like two ">" tokens, |
5670 | in a template-argument-list. */ |
5671 | && (next_token->type != CPP_RSHIFT |
5672 | || (cxx_dialect == cxx98) |
5673 | || parser->greater_than_is_operator_p)) |
5674 | cast_p = false; |
5675 | } |
5676 | |
5677 | /* If we are within a cast, then the constraint that the |
5678 | cast is to an integral or enumeration type will be |
5679 | checked at that point. If we are not within a cast, then |
5680 | this code is invalid. */ |
5681 | if (!cast_p) |
5682 | cp_parser_non_integral_constant_expression (parser, NIC_FLOAT); |
5683 | } |
5684 | return (cp_expr (token->u.value, token->location, token->flags & DECIMAL_INT(1 << 6)) |
5685 | .maybe_add_location_wrapper ()); |
5686 | |
5687 | case CPP_CHAR_USERDEF: |
5688 | case CPP_CHAR16_USERDEF: |
5689 | case CPP_CHAR32_USERDEF: |
5690 | case CPP_WCHAR_USERDEF: |
5691 | case CPP_UTF8CHAR_USERDEF: |
5692 | return cp_parser_userdef_char_literal (parser); |
5693 | |
5694 | case CPP_STRING: |
5695 | case CPP_STRING16: |
5696 | case CPP_STRING32: |
5697 | case CPP_WSTRING: |
5698 | case CPP_UTF8STRING: |
5699 | case CPP_STRING_USERDEF: |
5700 | case CPP_STRING16_USERDEF: |
5701 | case CPP_STRING32_USERDEF: |
5702 | case CPP_WSTRING_USERDEF: |
5703 | case CPP_UTF8STRING_USERDEF: |
5704 | /* ??? Should wide strings be allowed when parser->translate_strings_p |
5705 | is false (i.e. in attributes)? If not, we can kill the third |
5706 | argument to cp_parser_string_literal. */ |
5707 | if (parser->translate_strings_p) |
5708 | return (cp_parser_userdef_string_literal (parser, |
5709 | /*lookup_udlit=*/true) |
5710 | .maybe_add_location_wrapper ()); |
5711 | else |
5712 | return (cp_parser_string_literal (parser, |
5713 | /*translate=*/false, |
5714 | /*wide_ok=*/true) |
5715 | .maybe_add_location_wrapper ()); |
5716 | |
5717 | case CPP_OPEN_PAREN: |
5718 | /* If we see `( { ' then we are looking at the beginning of |
5719 | a GNU statement-expression. */ |
5720 | if (cp_parser_allow_gnu_extensions_p (parser) |
5721 | && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_BRACE)) |
5722 | { |
5723 | /* Statement-expressions are not allowed by the standard. */ |
5724 | pedwarn (token->location, OPT_Wpedantic, |
5725 | "ISO C++ forbids braced-groups within expressions"); |
5726 | |
5727 | /* And they're not allowed outside of a function-body; you |
5728 | cannot, for example, write: |
5729 | |
5730 | int i = ({ int j = 3; j + 1; }); |
5731 | |
5732 | at class or namespace scope. */ |
5733 | if (!parser->in_function_body |
5734 | || parser->in_template_argument_list_p) |
5735 | { |
5736 | error_at (token->location, |
5737 | "statement-expressions are not allowed outside " |
5738 | "functions nor in template-argument lists"); |
5739 | cp_parser_skip_to_end_of_block_or_statement (parser); |
5740 | if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)) |
5741 | cp_lexer_consume_token (parser->lexer); |
5742 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5743 | } |
5744 | else |
5745 | return cp_parser_statement_expr (parser); |
5746 | } |
5747 | /* Otherwise it's a normal parenthesized expression. */ |
5748 | { |
5749 | cp_expr expr; |
5750 | bool saved_greater_than_is_operator_p; |
5751 | |
5752 | location_t open_paren_loc = token->location; |
5753 | |
5754 | /* Consume the `('. */ |
5755 | matching_parens parens; |
5756 | parens.consume_open (parser); |
5757 | /* Within a parenthesized expression, a `>' token is always |
5758 | the greater-than operator. */ |
5759 | saved_greater_than_is_operator_p |
5760 | = parser->greater_than_is_operator_p; |
5761 | parser->greater_than_is_operator_p = true; |
5762 | |
5763 | if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) |
5764 | /* Left fold expression. */ |
5765 | expr = NULL_TREE(tree) __null; |
5766 | else |
5767 | /* Parse the parenthesized expression. */ |
5768 | expr = cp_parser_expression (parser, idk, cast_p, decltype_p); |
5769 | |
5770 | token = cp_lexer_peek_token (parser->lexer); |
5771 | if (token->type == CPP_ELLIPSIS || cp_parser_fold_operator (token)) |
5772 | { |
5773 | expr = cp_parser_fold_expression (parser, expr); |
5774 | if (expr != error_mark_nodeglobal_trees[TI_ERROR_MARK] |
5775 | && cxx_dialect < cxx17) |
5776 | pedwarn (input_location, OPT_Wc__17_extensions, |
5777 | "fold-expressions only available with %<-std=c++17%> " |
5778 | "or %<-std=gnu++17%>"); |
5779 | } |
5780 | else |
5781 | /* Let the front end know that this expression was |
5782 | enclosed in parentheses. This matters in case, for |
5783 | example, the expression is of the form `A::B', since |
5784 | `&A::B' might be a pointer-to-member, but `&(A::B)' is |
5785 | not. */ |
5786 | expr = finish_parenthesized_expr (expr); |
5787 | |
5788 | /* DR 705: Wrapping an unqualified name in parentheses |
5789 | suppresses arg-dependent lookup. We want to pass back |
5790 | CP_ID_KIND_QUALIFIED for suppressing vtable lookup |
5791 | (c++/37862), but none of the others. */ |
5792 | if (*idk != CP_ID_KIND_QUALIFIED) |
5793 | *idk = CP_ID_KIND_NONE; |
5794 | |
5795 | /* The `>' token might be the end of a template-id or |
5796 | template-parameter-list now. */ |
5797 | parser->greater_than_is_operator_p |
5798 | = saved_greater_than_is_operator_p; |
5799 | |
5800 | /* Consume the `)'. */ |
5801 | token = cp_lexer_peek_token (parser->lexer); |
5802 | location_t close_paren_loc = token->location; |
5803 | bool no_wparens = warning_suppressed_p (expr, OPT_Wparentheses); |
5804 | expr.set_range (open_paren_loc, close_paren_loc); |
5805 | if (no_wparens) |
5806 | suppress_warning (expr, OPT_Wparentheses); |
5807 | if (!parens.require_close (parser) |
5808 | && !cp_parser_uncommitted_to_tentative_parse_p (parser)) |
5809 | cp_parser_skip_to_end_of_statement (parser); |
5810 | |
5811 | return expr; |
5812 | } |
5813 | |
5814 | case CPP_OPEN_SQUARE: |
5815 | { |
5816 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
5817 | { |
5818 | /* We might have an Objective-C++ message. */ |
5819 | cp_parser_parse_tentatively (parser); |
5820 | tree msg = cp_parser_objc_message_expression (parser); |
5821 | /* If that works out, we're done ... */ |
5822 | if (cp_parser_parse_definitely (parser)) |
5823 | return msg; |
5824 | /* ... else, fall though to see if it's a lambda. */ |
5825 | } |
5826 | cp_expr lam = cp_parser_lambda_expression (parser); |
5827 | /* Don't warn about a failed tentative parse. */ |
5828 | if (cp_parser_error_occurred (parser)) |
5829 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5830 | maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR); |
5831 | return lam; |
5832 | } |
5833 | |
5834 | case CPP_OBJC_STRING: |
5835 | if (c_dialect_objc ()((c_language & clk_objc) != 0)) |
5836 | /* We have an Objective-C++ string literal. */ |
5837 | return cp_parser_objc_expression (parser); |
5838 | cp_parser_error (parser, "expected primary-expression"); |
5839 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5840 | |
5841 | case CPP_KEYWORD: |
5842 | switch (token->keyword) |
5843 | { |
5844 | /* These two are the boolean literals. */ |
5845 | case RID_TRUE: |
5846 | cp_lexer_consume_token (parser->lexer); |
5847 | return cp_expr (boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE], token->location); |
5848 | case RID_FALSE: |
5849 | cp_lexer_consume_token (parser->lexer); |
5850 | return cp_expr (boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE], token->location); |
5851 | |
5852 | /* The `__null' literal. */ |
5853 | case RID_NULL: |
5854 | cp_lexer_consume_token (parser->lexer); |
5855 | return cp_expr (null_nodec_global_trees[CTI_NULL], token->location); |
5856 | |
5857 | /* The `nullptr' literal. */ |
5858 | case RID_NULLPTR: |
5859 | cp_lexer_consume_token (parser->lexer); |
5860 | return cp_expr (nullptr_nodec_global_trees[CTI_NULLPTR], token->location); |
5861 | |
5862 | /* Recognize the `this' keyword. */ |
5863 | case RID_THIS: |
5864 | cp_lexer_consume_token (parser->lexer); |
5865 | if (parser->local_variables_forbidden_p & THIS_FORBIDDEN(1 << 1)) |
5866 | { |
5867 | error_at (token->location, |
5868 | "%<this%> may not be used in this context"); |
5869 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5870 | } |
5871 | /* Pointers cannot appear in constant-expressions. */ |
5872 | if (cp_parser_non_integral_constant_expression (parser, NIC_THIS)) |
5873 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5874 | return cp_expr (finish_this_expr (), token->location); |
5875 | |
5876 | /* The `operator' keyword can be the beginning of an |
5877 | id-expression. */ |
5878 | case RID_OPERATOR: |
5879 | goto id_expression; |
5880 | |
5881 | case RID_FUNCTION_NAME: |
5882 | case RID_PRETTY_FUNCTION_NAME: |
5883 | case RID_C99_FUNCTION_NAME: |
5884 | { |
5885 | non_integral_constant name; |
5886 | |
5887 | /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and |
5888 | __func__ are the names of variables -- but they are |
5889 | treated specially. Therefore, they are handled here, |
5890 | rather than relying on the generic id-expression logic |
5891 | below. Grammatically, these names are id-expressions. |
5892 | |
5893 | Consume the token. */ |
5894 | token = cp_lexer_consume_token (parser->lexer); |
5895 | |
5896 | switch (token->keyword) |
5897 | { |
5898 | case RID_FUNCTION_NAME: |
5899 | name = NIC_FUNC_NAME; |
5900 | break; |
5901 | case RID_PRETTY_FUNCTION_NAME: |
5902 | name = NIC_PRETTY_FUNC; |
5903 | break; |
5904 | case RID_C99_FUNCTION_NAME: |
5905 | name = NIC_C99_FUNC; |
5906 | break; |
5907 | default: |
5908 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5908, __FUNCTION__)); |
5909 | } |
5910 | |
5911 | if (cp_parser_non_integral_constant_expression (parser, name)) |
5912 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5913 | |
5914 | /* Look up the name. */ |
5915 | return finish_fname (token->u.value); |
5916 | } |
5917 | |
5918 | case RID_VA_ARG: |
5919 | { |
5920 | tree expression; |
5921 | tree type; |
5922 | location_t type_location; |
5923 | location_t start_loc |
5924 | = cp_lexer_peek_token (parser->lexer)->location; |
5925 | /* The `__builtin_va_arg' construct is used to handle |
5926 | `va_arg'. Consume the `__builtin_va_arg' token. */ |
5927 | cp_lexer_consume_token (parser->lexer); |
5928 | /* Look for the opening `('. */ |
5929 | matching_parens parens; |
5930 | parens.require_open (parser); |
5931 | /* Now, parse the assignment-expression. */ |
5932 | expression = cp_parser_assignment_expression (parser); |
5933 | /* Look for the `,'. */ |
5934 | cp_parser_require (parser, CPP_COMMA, RT_COMMA); |
5935 | type_location = cp_lexer_peek_token (parser->lexer)->location; |
5936 | /* Parse the type-id. */ |
5937 | { |
5938 | type_id_in_expr_sentinel s (parser); |
5939 | type = cp_parser_type_id (parser); |
5940 | } |
5941 | /* Look for the closing `)'. */ |
5942 | location_t finish_loc |
5943 | = cp_lexer_peek_token (parser->lexer)->location; |
5944 | parens.require_close (parser); |
5945 | /* Using `va_arg' in a constant-expression is not |
5946 | allowed. */ |
5947 | if (cp_parser_non_integral_constant_expression (parser, |
5948 | NIC_VA_ARG)) |
5949 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5950 | /* Construct a location of the form: |
5951 | __builtin_va_arg (v, int) |
5952 | ~~~~~~~~~~~~~~~~~~~~~^~~~ |
5953 | with the caret at the type, ranging from the start of the |
5954 | "__builtin_va_arg" token to the close paren. */ |
5955 | location_t combined_loc |
5956 | = make_location (type_location, start_loc, finish_loc); |
5957 | return build_x_va_arg (combined_loc, expression, type); |
5958 | } |
5959 | |
5960 | case RID_OFFSETOF: |
5961 | return cp_parser_builtin_offsetof (parser); |
5962 | |
5963 | #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \ |
5964 | case RID_##CODE: |
5965 | #include "cp-trait.def" |
5966 | #undef DEFTRAIT_EXPR |
5967 | return cp_parser_trait (parser, token->keyword); |
5968 | |
5969 | // C++ concepts |
5970 | case RID_REQUIRES: |
5971 | return cp_parser_requires_expression (parser); |
5972 | |
5973 | /* Objective-C++ expressions. */ |
5974 | case RID_AT_ENCODE: |
5975 | case RID_AT_PROTOCOL: |
5976 | case RID_AT_SELECTOR: |
5977 | return cp_parser_objc_expression (parser); |
5978 | |
5979 | case RID_OMP_ALL_MEMORY: |
5980 | gcc_assert (flag_openmp)((void)(!(global_options.x_flag_openmp) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/parser.cc" , 5980, __FUNCTION__), 0 : 0)); |
5981 | cp_lexer_consume_token (parser->lexer); |
5982 | error_at (token->location, |
5983 | "%<omp_all_memory%> may only be used in OpenMP " |
5984 | "%<depend%> clause"); |
5985 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5986 | |
5987 | case RID_TEMPLATE: |
5988 | if (parser->in_function_body |
5989 | && (cp_lexer_peek_nth_token (parser->lexer, 2)->type |
5990 | == CPP_LESS)) |
5991 | { |
5992 | error_at (token->location, |
5993 | "a template declaration cannot appear at block scope"); |
5994 | cp_parser_skip_to_end_of_block_or_statement (parser); |
5995 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
5996 | } |
5997 | /* FALLTHRU */ |
5998 | default: |
5999 | cp_parser_error (parser, "expected primary-expression"); |
6000 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
6001 | } |
6002 | |
6003 | /* An id-expression can start with either an identifier, a |
6004 | `::' as the beginning of a qualified-id, or the "operator" |
6005 | keyword. */ |
6006 | case CPP_NAME: |
6007 | case CPP_SCOPE: |
6008 | case CPP_TEMPLATE_ID((enum cpp_ttype) (CPP_KEYWORD + 1)): |
6009 | case CPP_NESTED_NAME_SPECIFIER((enum cpp_ttype) (((enum cpp_ttype) (CPP_KEYWORD + 1)) + 1)): |
6010 | { |
6011 | id_expression: |
6012 | cp_expr id_expression; |
6013 | cp_expr decl; |
6014 | const char *error_msg; |
6015 | bool template_p; |
6016 | bool done; |
6017 | cp_token *id_expr_token; |
6018 | |
6019 | /* Parse the id-expression. */ |
6020 | id_expression |
6021 | = cp_parser_id_expression (parser, |
6022 | /*template_keyword_p=*/false, |
6023 | /*check_dependency_p=*/true, |
6024 | &template_p, |
6025 | /*declarator_p=*/false, |
6026 | /*optional_p=*/false); |
6027 | if (id_expression == error_mark_nodeglobal_trees[TI_ERROR_MARK]) |
6028 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
6029 | id_expr_token = token; |
6030 | token = cp_lexer_peek_token (parser->lexer); |
6031 | done = (token->type != CPP_OPEN_SQUARE |
6032 | && token->type != CPP_OPEN_PAREN |
6033 | && token->type != CPP_DOT |
6034 | && token->type != CPP_DEREF |
6035 | && token->type != CPP_PLUS_PLUS |
6036 | && token->type != CPP_MINUS_MINUS); |
6037 | /* If we have a template-id, then no further lookup is |
6038 | required. If the template-id was for a template-class, we |
6039 | will sometimes have a TYPE_DECL at this point. */ |
6040 | if (TREE_CODE (id_expression)((enum tree_code) (id_expression)->base.code) == TEMPLATE_ID_EXPR |
6041 | || TREE_CODE (id_expression)((enum tree_code) (id_expression)->base.code) == TYPE_DECL) |
6042 | decl = id_expression; |
6043 | /* Look up the name. */ |
6044 | else |
6045 | { |
6046 | tree ambiguous_decls; |
6047 | |
6048 | /* If we already know that this lookup is ambiguous, then |
6049 | we've already issued an error message; there's no reason |
6050 |