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