1/* -*- C++ -*- Parser.
2 Copyright (C) 2000-2024 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
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#define INCLUDE_MEMORY
23#include "system.h"
24#include "coretypes.h"
25#include "cp-tree.h"
26#include "c-family/c-common.h"
27#include "timevar.h"
28#include "stringpool.h"
29#include "cgraph.h"
30#include "print-tree.h"
31#include "attribs.h"
32#include "trans-mem.h"
33#include "intl.h"
34#include "decl.h"
35#include "c-family/c-objc.h"
36#include "plugin.h"
37#include "tree-pretty-print.h"
38#include "parser.h"
39#include "gomp-constants.h"
40#include "omp-general.h"
41#include "omp-offload.h"
42#include "c-family/c-indentation.h"
43#include "context.h"
44#include "gcc-rich-location.h"
45#include "tree-iterator.h"
46#include "cp-name-hint.h"
47#include "memmodel.h"
48#include "c-family/known-headers.h"
49#include "contracts.h"
50#include "bitmap.h"
51#include "builtins.h"
52
53
54/* The lexer. */
55
56/* The cp_lexer_* routines mediate between the lexer proper (in libcpp
57 and c-lex.cc) and the C++ parser. */
58
59/* The various kinds of non integral constant we encounter. */
60enum non_integral_constant {
61 NIC_NONE,
62 /* floating-point literal */
63 NIC_FLOAT,
64 /* %<this%> */
65 NIC_THIS,
66 /* %<__FUNCTION__%> */
67 NIC_FUNC_NAME,
68 /* %<__PRETTY_FUNCTION__%> */
69 NIC_PRETTY_FUNC,
70 /* %<__func__%> */
71 NIC_C99_FUNC,
72 /* "%<va_arg%> */
73 NIC_VA_ARG,
74 /* a cast */
75 NIC_CAST,
76 /* %<typeid%> operator */
77 NIC_TYPEID,
78 /* non-constant compound literals */
79 NIC_NCC,
80 /* a function call */
81 NIC_FUNC_CALL,
82 /* an increment */
83 NIC_INC,
84 /* an decrement */
85 NIC_DEC,
86 /* an array reference */
87 NIC_ARRAY_REF,
88 /* %<->%> */
89 NIC_ARROW,
90 /* %<.%> */
91 NIC_POINT,
92 /* the address of a label */
93 NIC_ADDR_LABEL,
94 /* %<*%> */
95 NIC_STAR,
96 /* %<&%> */
97 NIC_ADDR,
98 /* %<++%> */
99 NIC_PREINCREMENT,
100 /* %<--%> */
101 NIC_PREDECREMENT,
102 /* %<new%> */
103 NIC_NEW,
104 /* %<delete%> */
105 NIC_DEL,
106 /* calls to overloaded operators */
107 NIC_OVERLOADED,
108 /* an assignment */
109 NIC_ASSIGNMENT,
110 /* a comma operator */
111 NIC_COMMA,
112 /* a call to a constructor */
113 NIC_CONSTRUCTOR,
114 /* a transaction expression */
115 NIC_TRANSACTION
116};
117
118/* The various kinds of errors about name-lookup failing. */
119enum name_lookup_error {
120 /* NULL */
121 NLE_NULL,
122 /* is not a type */
123 NLE_TYPE,
124 /* is not a class or namespace */
125 NLE_CXX98,
126 /* is not a class, namespace, or enumeration */
127 NLE_NOT_CXX98
128};
129
130/* The various kinds of required token */
131enum required_token {
132 RT_NONE,
133 RT_SEMICOLON, /* ';' */
134 RT_OPEN_PAREN, /* '(' */
135 RT_CLOSE_BRACE, /* '}' */
136 RT_OPEN_BRACE, /* '{' */
137 RT_CLOSE_SQUARE, /* ']' */
138 RT_OPEN_SQUARE, /* '[' */
139 RT_COMMA, /* ',' */
140 RT_SCOPE, /* '::' */
141 RT_LESS, /* '<' */
142 RT_GREATER, /* '>' */
143 RT_EQ, /* '=' */
144 RT_ELLIPSIS, /* '...' */
145 RT_MULT, /* '*' */
146 RT_COMPL, /* '~' */
147 RT_COLON, /* ':' */
148 RT_COLON_SCOPE, /* ':' or '::' */
149 RT_CLOSE_PAREN, /* ')' */
150 RT_COMMA_CLOSE_PAREN, /* ',' or ')' */
151 RT_PRAGMA_EOL, /* end of line */
152 RT_NAME, /* identifier */
153
154 /* The type is CPP_KEYWORD */
155 RT_NEW, /* new */
156 RT_DELETE, /* delete */
157 RT_RETURN, /* return */
158 RT_WHILE, /* while */
159 RT_EXTERN, /* extern */
160 RT_STATIC_ASSERT, /* static_assert */
161 RT_DECLTYPE, /* decltype */
162 RT_OPERATOR, /* operator */
163 RT_CLASS, /* class */
164 RT_TEMPLATE, /* template */
165 RT_NAMESPACE, /* namespace */
166 RT_USING, /* using */
167 RT_ASM, /* asm */
168 RT_TRY, /* try */
169 RT_CATCH, /* catch */
170 RT_THROW, /* throw */
171 RT_AUTO, /* auto */
172 RT_LABEL, /* __label__ */
173 RT_AT_TRY, /* @try */
174 RT_AT_SYNCHRONIZED, /* @synchronized */
175 RT_AT_THROW, /* @throw */
176
177 RT_SELECT, /* selection-statement */
178 RT_ITERATION, /* iteration-statement */
179 RT_JUMP, /* jump-statement */
180 RT_CLASS_KEY, /* class-key */
181 RT_CLASS_TYPENAME_TEMPLATE, /* class, typename, or template */
182 RT_TRANSACTION_ATOMIC, /* __transaction_atomic */
183 RT_TRANSACTION_RELAXED, /* __transaction_relaxed */
184 RT_TRANSACTION_CANCEL, /* __transaction_cancel */
185
186 RT_CO_YIELD /* co_yield */
187};
188
189/* RAII wrapper for parser->in_type_id_in_expr_p, setting it on creation and
190 reverting it on destruction. */
191
192class type_id_in_expr_sentinel
193{
194 cp_parser *parser;
195 bool saved;
196public:
197 type_id_in_expr_sentinel (cp_parser *parser, bool set = true)
198 : parser (parser),
199 saved (parser->in_type_id_in_expr_p)
200 { parser->in_type_id_in_expr_p = set; }
201 ~type_id_in_expr_sentinel ()
202 { parser->in_type_id_in_expr_p = saved; }
203};
204
205/* Prototypes. */
206
207static cp_lexer *cp_lexer_new_main
208 (void);
209static cp_lexer *cp_lexer_new_from_tokens
210 (cp_token_cache *tokens);
211static void cp_lexer_destroy
212 (cp_lexer *);
213static int cp_lexer_saving_tokens
214 (const cp_lexer *);
215static cp_token *cp_lexer_token_at
216 (cp_lexer *, cp_token_position);
217static void cp_lexer_get_preprocessor_token
218 (unsigned, cp_token *);
219static inline cp_token *cp_lexer_peek_token
220 (cp_lexer *);
221static cp_token *cp_lexer_peek_nth_token
222 (cp_lexer *, size_t);
223static inline bool cp_lexer_next_token_is
224 (cp_lexer *, enum cpp_ttype);
225static bool cp_lexer_next_token_is_not
226 (cp_lexer *, enum cpp_ttype);
227static bool cp_lexer_next_token_is_keyword
228 (cp_lexer *, enum rid);
229static cp_token *cp_lexer_consume_token
230 (cp_lexer *);
231static void cp_lexer_purge_token
232 (cp_lexer *);
233static void cp_lexer_purge_tokens_after
234 (cp_lexer *, cp_token_position);
235static void cp_lexer_save_tokens
236 (cp_lexer *);
237static void cp_lexer_commit_tokens
238 (cp_lexer *);
239static void cp_lexer_rollback_tokens
240 (cp_lexer *);
241static void cp_lexer_print_token
242 (FILE *, cp_token *);
243static inline bool cp_lexer_debugging_p
244 (cp_lexer *);
245static void cp_lexer_start_debugging
246 (cp_lexer *) ATTRIBUTE_UNUSED;
247static void cp_lexer_stop_debugging
248 (cp_lexer *) ATTRIBUTE_UNUSED;
249static const cp_trait *cp_lexer_peek_trait
250 (cp_lexer *);
251static const cp_trait *cp_lexer_peek_trait_expr
252 (cp_lexer *);
253static const cp_trait *cp_lexer_peek_trait_type
254 (cp_lexer *);
255
256static cp_token_cache *cp_token_cache_new
257 (cp_token *, cp_token *);
258static tree cp_parser_late_noexcept_specifier
259 (cp_parser *, tree);
260static void noexcept_override_late_checks
261 (tree);
262
263static void cp_parser_initial_pragma
264 (cp_token *);
265
266static bool cp_parser_omp_declare_reduction_exprs
267 (tree, cp_parser *);
268static void cp_finalize_oacc_routine
269 (cp_parser *, tree, bool);
270
271static void check_omp_intervening_code
272 (cp_parser *);
273
274
275/* Manifest constants. */
276#define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
277#define CP_SAVED_TOKEN_STACK 5
278
279/* Variables. */
280
281/* The stream to which debugging output should be written. */
282static FILE *cp_lexer_debug_stream;
283
284/* Nonzero if we are parsing an unevaluated operand: an operand to
285 sizeof, typeof, or alignof. */
286int cp_unevaluated_operand;
287
288/* Dump up to NUM tokens in BUFFER to FILE starting with token
289 START_TOKEN. If START_TOKEN is NULL, the dump starts with the
290 first token in BUFFER. If NUM is 0, dump all the tokens. If
291 CURR_TOKEN is set and it is one of the tokens in BUFFER, it will be
292 highlighted by surrounding it in [[ ]]. */
293
294static void
295cp_lexer_dump_tokens (FILE *file, vec<cp_token, va_gc> *buffer,
296 cp_token *start_token, unsigned num,
297 cp_token *curr_token)
298{
299 unsigned i, nprinted;
300 cp_token *token;
301 bool do_print;
302
303 fprintf (stream: file, format: "%u tokens\n", vec_safe_length (v: buffer));
304
305 if (buffer == NULL)
306 return;
307
308 if (num == 0)
309 num = buffer->length ();
310
311 if (start_token == NULL)
312 start_token = buffer->address ();
313
314 if (start_token > buffer->address ())
315 {
316 cp_lexer_print_token (file, &(*buffer)[0]);
317 fprintf (stream: file, format: " ... ");
318 }
319
320 do_print = false;
321 nprinted = 0;
322 for (i = 0; buffer->iterate (ix: i, ptr: &token) && nprinted < num; i++)
323 {
324 if (token == start_token)
325 do_print = true;
326
327 if (!do_print)
328 continue;
329
330 nprinted++;
331 if (token == curr_token)
332 fprintf (stream: file, format: "[[");
333
334 cp_lexer_print_token (file, token);
335
336 if (token == curr_token)
337 fprintf (stream: file, format: "]]");
338
339 switch (token->type)
340 {
341 case CPP_SEMICOLON:
342 case CPP_OPEN_BRACE:
343 case CPP_CLOSE_BRACE:
344 case CPP_EOF:
345 fputc (c: '\n', stream: file);
346 break;
347
348 default:
349 fputc (c: ' ', stream: file);
350 }
351 }
352
353 if (i == num && i < buffer->length ())
354 {
355 fprintf (stream: file, format: " ... ");
356 cp_lexer_print_token (file, &buffer->last ());
357 }
358
359 fprintf (stream: file, format: "\n");
360}
361
362
363/* Dump all tokens in BUFFER to stderr. */
364
365void
366cp_lexer_debug_tokens (vec<cp_token, va_gc> *buffer)
367{
368 cp_lexer_dump_tokens (stderr, buffer, NULL, num: 0, NULL);
369}
370
371DEBUG_FUNCTION void
372debug (vec<cp_token, va_gc> &ref)
373{
374 cp_lexer_dump_tokens (stderr, buffer: &ref, NULL, num: 0, NULL);
375}
376
377DEBUG_FUNCTION void
378debug (vec<cp_token, va_gc> *ptr)
379{
380 if (ptr)
381 debug (ref&: *ptr);
382 else
383 fprintf (stderr, format: "<nil>\n");
384}
385
386
387/* Dump the cp_parser tree field T to FILE if T is non-NULL. DESC is the
388 description for T. */
389
390static void
391cp_debug_print_tree_if_set (FILE *file, const char *desc, tree t)
392{
393 if (t)
394 {
395 fprintf (stream: file, format: "%s: ", desc);
396 print_node_brief (file, "", t, 0);
397 }
398}
399
400
401/* Dump parser context C to FILE. */
402
403static void
404cp_debug_print_context (FILE *file, cp_parser_context *c)
405{
406 const char *status_s[] = { "OK", "ERROR", "COMMITTED" };
407 fprintf (stream: file, format: "{ status = %s, scope = ", status_s[c->status]);
408 print_node_brief (file, "", c->object_type, 0);
409 fprintf (stream: file, format: "}\n");
410}
411
412
413/* Print the stack of parsing contexts to FILE starting with FIRST. */
414
415static void
416cp_debug_print_context_stack (FILE *file, cp_parser_context *first)
417{
418 unsigned i;
419 cp_parser_context *c;
420
421 fprintf (stream: file, format: "Parsing context stack:\n");
422 for (i = 0, c = first; c; c = c->next, i++)
423 {
424 fprintf (stream: file, format: "\t#%u: ", i);
425 cp_debug_print_context (file, c);
426 }
427}
428
429
430/* Print the value of FLAG to FILE. DESC is a string describing the flag. */
431
432static void
433cp_debug_print_flag (FILE *file, const char *desc, bool flag)
434{
435 if (flag)
436 fprintf (stream: file, format: "%s: true\n", desc);
437}
438
439
440/* Print an unparsed function entry UF to FILE. */
441
442static void
443cp_debug_print_unparsed_function (FILE *file, cp_unparsed_functions_entry *uf)
444{
445 unsigned i;
446 cp_default_arg_entry *default_arg_fn;
447 tree fn;
448
449 fprintf (stream: file, format: "\tFunctions with default args:\n");
450 for (i = 0;
451 vec_safe_iterate (v: uf->funs_with_default_args, ix: i, ptr: &default_arg_fn);
452 i++)
453 {
454 fprintf (stream: file, format: "\t\tClass type: ");
455 print_node_brief (file, "", default_arg_fn->class_type, 0);
456 fprintf (stream: file, format: "\t\tDeclaration: ");
457 print_node_brief (file, "", default_arg_fn->decl, 0);
458 fprintf (stream: file, format: "\n");
459 }
460
461 fprintf (stream: file, format: "\n\tFunctions with definitions that require "
462 "post-processing\n\t\t");
463 for (i = 0; vec_safe_iterate (v: uf->funs_with_definitions, ix: i, ptr: &fn); i++)
464 {
465 print_node_brief (file, "", fn, 0);
466 fprintf (stream: file, format: " ");
467 }
468 fprintf (stream: file, format: "\n");
469
470 fprintf (stream: file, format: "\n\tNon-static data members with initializers that require "
471 "post-processing\n\t\t");
472 for (i = 0; vec_safe_iterate (v: uf->nsdmis, ix: i, ptr: &fn); i++)
473 {
474 print_node_brief (file, "", fn, 0);
475 fprintf (stream: file, format: " ");
476 }
477 fprintf (stream: file, format: "\n");
478}
479
480
481/* Print the stack of unparsed member functions S to FILE. */
482
483static void
484cp_debug_print_unparsed_queues (FILE *file,
485 vec<cp_unparsed_functions_entry, va_gc> *s)
486{
487 unsigned i;
488 cp_unparsed_functions_entry *uf;
489
490 fprintf (stream: file, format: "Unparsed functions\n");
491 for (i = 0; vec_safe_iterate (v: s, ix: i, ptr: &uf); i++)
492 {
493 fprintf (stream: file, format: "#%u:\n", i);
494 cp_debug_print_unparsed_function (file, uf);
495 }
496}
497
498
499/* Dump the tokens in a window of size WINDOW_SIZE around the next_token for
500 the given PARSER. If FILE is NULL, the output is printed on stderr. */
501
502static void
503cp_debug_parser_tokens (FILE *file, cp_parser *parser, int window_size)
504{
505 cp_token *next_token, *first_token, *start_token;
506
507 if (file == NULL)
508 file = stderr;
509
510 next_token = parser->lexer->next_token;
511 first_token = parser->lexer->buffer->address ();
512 start_token = (next_token > first_token + window_size / 2)
513 ? next_token - window_size / 2
514 : first_token;
515 cp_lexer_dump_tokens (file, buffer: parser->lexer->buffer, start_token, num: window_size,
516 curr_token: next_token);
517}
518
519
520/* Dump debugging information for the given PARSER. If FILE is NULL,
521 the output is printed on stderr. */
522
523void
524cp_debug_parser (FILE *file, cp_parser *parser)
525{
526 const size_t window_size = 20;
527 cp_token *token;
528 expanded_location eloc;
529
530 if (file == NULL)
531 file = stderr;
532
533 fprintf (stream: file, format: "Parser state\n\n");
534 fprintf (stream: file, format: "Number of tokens: %u\n",
535 vec_safe_length (v: parser->lexer->buffer));
536 cp_debug_print_tree_if_set (file, desc: "Lookup scope", t: parser->scope);
537 cp_debug_print_tree_if_set (file, desc: "Object scope",
538 t: parser->object_scope);
539 cp_debug_print_tree_if_set (file, desc: "Qualifying scope",
540 t: parser->qualifying_scope);
541 cp_debug_print_context_stack (file, first: parser->context);
542 cp_debug_print_flag (file, desc: "Allow GNU extensions",
543 flag: parser->allow_gnu_extensions_p);
544 cp_debug_print_flag (file, desc: "'>' token is greater-than",
545 flag: parser->greater_than_is_operator_p);
546 cp_debug_print_flag (file, desc: "Default args allowed in current "
547 "parameter list", flag: parser->default_arg_ok_p);
548 cp_debug_print_flag (file, desc: "Parsing integral constant-expression",
549 flag: parser->integral_constant_expression_p);
550 cp_debug_print_flag (file, desc: "Allow non-constant expression in current "
551 "constant-expression",
552 flag: parser->allow_non_integral_constant_expression_p);
553 cp_debug_print_flag (file, desc: "Seen non-constant expression",
554 flag: parser->non_integral_constant_expression_p);
555 cp_debug_print_flag (file, desc: "Local names forbidden in current context",
556 flag: (parser->local_variables_forbidden_p
557 & LOCAL_VARS_FORBIDDEN));
558 cp_debug_print_flag (file, desc: "'this' forbidden in current context",
559 flag: (parser->local_variables_forbidden_p
560 & THIS_FORBIDDEN));
561 cp_debug_print_flag (file, desc: "In unbraced linkage specification",
562 flag: parser->in_unbraced_linkage_specification_p);
563 cp_debug_print_flag (file, desc: "Parsing a declarator",
564 flag: parser->in_declarator_p);
565 cp_debug_print_flag (file, desc: "In template argument list",
566 flag: parser->in_template_argument_list_p);
567 cp_debug_print_flag (file, desc: "Parsing an iteration statement",
568 flag: parser->in_statement & IN_ITERATION_STMT);
569 cp_debug_print_flag (file, desc: "Parsing a switch statement",
570 flag: parser->in_statement & IN_SWITCH_STMT);
571 cp_debug_print_flag (file, desc: "Parsing a structured OpenMP block",
572 flag: parser->in_statement & IN_OMP_BLOCK);
573 cp_debug_print_flag (file, desc: "Parsing an OpenMP loop",
574 flag: parser->in_statement & IN_OMP_FOR);
575 cp_debug_print_flag (file, desc: "Parsing an if statement",
576 flag: parser->in_statement & IN_IF_STMT);
577 cp_debug_print_flag (file, desc: "Parsing a type-id in an expression "
578 "context", flag: parser->in_type_id_in_expr_p);
579 cp_debug_print_flag (file, desc: "String expressions should be translated "
580 "to execution character set",
581 flag: parser->translate_strings_p);
582 cp_debug_print_flag (file, desc: "Parsing function body outside of a "
583 "local class", flag: parser->in_function_body);
584 cp_debug_print_flag (file, desc: "Auto correct a colon to a scope operator",
585 flag: parser->colon_corrects_to_scope_p);
586 cp_debug_print_flag (file, desc: "Colon doesn't start a class definition",
587 flag: parser->colon_doesnt_start_class_def_p);
588 cp_debug_print_flag (file, desc: "Parsing an Objective-C++ message context",
589 flag: parser->objective_c_message_context_p);
590 if (parser->type_definition_forbidden_message)
591 fprintf (stream: file, format: "Error message for forbidden type definitions: %s %s\n",
592 parser->type_definition_forbidden_message,
593 parser->type_definition_forbidden_message_arg
594 ? parser->type_definition_forbidden_message_arg : "<none>");
595 cp_debug_print_unparsed_queues (file, s: parser->unparsed_queues);
596 fprintf (stream: file, format: "Number of class definitions in progress: %u\n",
597 parser->num_classes_being_defined);
598 fprintf (stream: file, format: "Number of template parameter lists for the current "
599 "declaration: %u\n", parser->num_template_parameter_lists);
600 cp_debug_parser_tokens (file, parser, window_size);
601 token = parser->lexer->next_token;
602 fprintf (stream: file, format: "Next token to parse:\n");
603 fprintf (stream: file, format: "\tToken: ");
604 cp_lexer_print_token (file, token);
605 eloc = expand_location (token->location);
606 fprintf (stream: file, format: "\n\tFile: %s\n", eloc.file);
607 fprintf (stream: file, format: "\tLine: %d\n", eloc.line);
608 fprintf (stream: file, format: "\tColumn: %d\n", eloc.column);
609}
610
611DEBUG_FUNCTION void
612debug (cp_parser &ref)
613{
614 cp_debug_parser (stderr, parser: &ref);
615}
616
617DEBUG_FUNCTION void
618debug (cp_parser *ptr)
619{
620 if (ptr)
621 debug (ref&: *ptr);
622 else
623 fprintf (stderr, format: "<nil>\n");
624}
625
626/* Allocate memory for a new lexer object and return it. */
627
628static cp_lexer *
629cp_lexer_alloc (void)
630{
631 /* Allocate the memory. */
632 cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> ();
633
634 /* Initially we are not debugging. */
635 lexer->debugging_p = false;
636
637 lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);
638
639 /* Create the buffer. */
640 vec_alloc (v&: lexer->buffer, CP_LEXER_BUFFER_SIZE);
641
642 return lexer;
643}
644
645/* Return TRUE if token is the start of a module declaration that will be
646 terminated by a CPP_PRAGMA_EOL token. */
647static inline bool
648cp_token_is_module_directive (cp_token *token)
649{
650 return token->keyword == RID__EXPORT
651 || token->keyword == RID__MODULE
652 || token->keyword == RID__IMPORT;
653}
654
655/* Return TOKEN's pragma_kind if it is CPP_PRAGMA, otherwise
656 PRAGMA_NONE. */
657
658static enum pragma_kind
659cp_parser_pragma_kind (cp_token *token)
660{
661 if (token->type != CPP_PRAGMA)
662 return PRAGMA_NONE;
663 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */
664 return (enum pragma_kind) TREE_INT_CST_LOW (token->u.value);
665}
666
667/* Handle early pragmas such as #pragma GCC diagnostic, which needs to be done
668 during preprocessing for the case of preprocessing-related diagnostics. This
669 is called immediately after pushing the CPP_PRAGMA_EOL token onto
670 lexer->buffer. */
671
672static void
673cp_lexer_handle_early_pragma (cp_lexer *lexer)
674{
675 const auto first_token = lexer->buffer->address ();
676 const auto last_token = first_token + lexer->buffer->length () - 1;
677
678 /* Back up to the start of the pragma so pragma_lex () can parse it when
679 c-pragma lib asks it to. */
680 auto begin = last_token;
681 gcc_assert (begin->type == CPP_PRAGMA_EOL);
682 while (begin->type != CPP_PRAGMA)
683 {
684 if (cp_token_is_module_directive (token: begin))
685 return;
686 gcc_assert (begin != first_token);
687 --begin;
688 }
689 gcc_assert (!lexer->next_token);
690 gcc_assert (!lexer->last_token);
691 lexer->next_token = begin;
692 lexer->last_token = last_token;
693
694 /* Dispatch it. */
695 const unsigned int id
696 = cp_parser_pragma_kind (token: cp_lexer_consume_token (lexer));
697 if (id >= PRAGMA_FIRST_EXTERNAL)
698 c_invoke_early_pragma_handler (id);
699
700 /* Reset to normal state. */
701 lexer->next_token = lexer->last_token = nullptr;
702}
703
704/* The parser. */
705static cp_parser *cp_parser_new (cp_lexer *);
706static GTY (()) cp_parser *the_parser;
707
708/* Create a new main C++ lexer, the lexer that gets tokens from the
709 preprocessor, and also create the main parser. */
710
711static cp_lexer *
712cp_lexer_new_main (void)
713{
714 cp_token token;
715
716 /* It's possible that parsing the first pragma will load a PCH file,
717 which is a GC collection point. So we have to do that before
718 allocating any memory. */
719 cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, &token);
720 cp_parser_initial_pragma (&token);
721 c_common_no_more_pch ();
722
723 cp_lexer *lexer = cp_lexer_alloc ();
724 /* Put the first token in the buffer. */
725 cp_token *tok = lexer->buffer->quick_push (obj: token);
726
727 uintptr_t filter = 0;
728 if (modules_p ())
729 filter = module_token_cdtor (parse_in, filter);
730
731 /* Create the parser now, so we can use it to handle early pragmas. */
732 gcc_assert (!the_parser);
733 the_parser = cp_parser_new (lexer);
734
735 /* Get the remaining tokens from the preprocessor. */
736 while (tok->type != CPP_EOF)
737 {
738 if (filter)
739 /* Process the previous token. */
740 module_token_lang (type: tok->type, keyword: tok->keyword, value: tok->u.value,
741 tok->location, filter);
742
743 /* Check for early pragmas that need to be handled now. */
744 if (tok->type == CPP_PRAGMA_EOL)
745 cp_lexer_handle_early_pragma (lexer);
746
747 tok = vec_safe_push (v&: lexer->buffer, obj: cp_token ());
748 cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok);
749 }
750
751 lexer->next_token = lexer->buffer->address ();
752 lexer->last_token = lexer->next_token
753 + lexer->buffer->length ()
754 - 1;
755
756 if (lexer->buffer->length () != 1)
757 {
758 /* Set the EOF token's location to be the just after the previous
759 token's range. That way 'at-eof' diagnostics point at something
760 meaninful. */
761 auto range = get_range_from_loc (set: line_table, loc: tok[-1].location);
762 tok[0].location
763 = linemap_position_for_loc_and_offset (set: line_table, loc: range.m_finish, offset: 1);
764 }
765
766 if (filter)
767 module_token_cdtor (parse_in, filter);
768
769 /* Subsequent preprocessor diagnostics should use compiler
770 diagnostic functions to get the compiler source location. */
771 override_libcpp_locations = true;
772
773 maybe_check_all_macros (parse_in);
774
775 /* If we processed any #pragma GCC target directives, we handled them early so
776 any macros they defined would be effective during preprocessing. Now, we
777 need to reset to the default state to begin compilation, and we will
778 process them again at the correct time as needed. */
779 c_reset_target_pragmas ();
780
781 gcc_assert (!lexer->next_token->purged_p);
782 return lexer;
783}
784
785/* Create a lexer and parser to be used during preprocess-only mode.
786 This will be filled with tokens to parse when needed by pragma_lex (). */
787void
788c_init_preprocess ()
789{
790 gcc_assert (!the_parser);
791 the_parser = cp_parser_new (cp_lexer_alloc ());
792}
793
794/* Create a new lexer whose token stream is primed with the tokens in
795 CACHE. When these tokens are exhausted, no new tokens will be read. */
796
797static cp_lexer *
798cp_lexer_new_from_tokens (cp_token_cache *cache)
799{
800 cp_token *first = cache->first;
801 cp_token *last = cache->last;
802 cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> ();
803
804 /* We do not own the buffer. */
805 lexer->buffer = NULL;
806
807 /* Insert an EOF token. */
808 lexer->saved_type = last->type;
809 lexer->saved_keyword = last->keyword;
810 last->type = CPP_EOF;
811 last->keyword = RID_MAX;
812
813 lexer->next_token = first;
814 lexer->last_token = last;
815
816 lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);
817
818 /* Initially we are not debugging. */
819 lexer->debugging_p = false;
820
821 gcc_assert (!lexer->next_token->purged_p
822 && !lexer->last_token->purged_p);
823 return lexer;
824}
825
826/* Frees all resources associated with LEXER. */
827
828static void
829cp_lexer_destroy (cp_lexer *lexer)
830{
831 if (lexer->buffer)
832 vec_free (v&: lexer->buffer);
833 else
834 {
835 /* Restore the token we overwrite with EOF. */
836 lexer->last_token->type = lexer->saved_type;
837 lexer->last_token->keyword = lexer->saved_keyword;
838 }
839 lexer->saved_tokens.release ();
840 ggc_free (lexer);
841}
842
843/* This needs to be set to TRUE before the lexer-debugging infrastructure can
844 be used. The point of this flag is to help the compiler to fold away calls
845 to cp_lexer_debugging_p within this source file at compile time, when the
846 lexer is not being debugged. */
847
848#define LEXER_DEBUGGING_ENABLED_P false
849
850/* Returns nonzero if debugging information should be output. */
851
852static inline bool
853cp_lexer_debugging_p (cp_lexer *lexer)
854{
855 if (!LEXER_DEBUGGING_ENABLED_P)
856 return false;
857
858 return lexer->debugging_p;
859}
860
861
862static inline cp_token_position
863cp_lexer_token_position (cp_lexer *lexer, bool previous_p)
864{
865 return lexer->next_token - previous_p;
866}
867
868static inline cp_token *
869cp_lexer_token_at (cp_lexer * /*lexer*/, cp_token_position pos)
870{
871 return pos;
872}
873
874static inline void
875cp_lexer_set_token_position (cp_lexer *lexer, cp_token_position pos)
876{
877 lexer->next_token = cp_lexer_token_at (lexer, pos);
878}
879
880static inline cp_token_position
881cp_lexer_previous_token_position (cp_lexer *lexer)
882{
883 return cp_lexer_token_position (lexer, previous_p: true);
884}
885
886static inline cp_token *
887cp_lexer_previous_token (cp_lexer *lexer)
888{
889 cp_token_position tp = cp_lexer_previous_token_position (lexer);
890
891 /* Skip past purged tokens. */
892 while (tp->purged_p)
893 {
894 gcc_assert (tp != vec_safe_address (lexer->buffer));
895 tp--;
896 }
897
898 return cp_lexer_token_at (lexer, pos: tp);
899}
900
901/* Same as above, but return NULL when the lexer doesn't own the token
902 buffer or if the next_token is at the start of the token
903 vector or if all previous tokens are purged. */
904
905static cp_token *
906cp_lexer_safe_previous_token (cp_lexer *lexer)
907{
908 if (lexer->buffer
909 && lexer->next_token != lexer->buffer->address ())
910 {
911 cp_token_position tp = cp_lexer_previous_token_position (lexer);
912
913 /* Skip past purged tokens. */
914 while (tp->purged_p)
915 {
916 if (tp == lexer->buffer->address ())
917 return NULL;
918 tp--;
919 }
920 return cp_lexer_token_at (lexer, pos: tp);
921 }
922
923 return NULL;
924}
925
926/* Overload for make_location, taking the lexer to mean the location of the
927 previous token. */
928
929static inline location_t
930make_location (location_t caret, location_t start, cp_lexer *lexer)
931{
932 cp_token *t = cp_lexer_previous_token (lexer);
933 return make_location (caret, start, finish: t->location);
934}
935
936/* Overload for make_location taking tokens instead of locations. */
937
938static inline location_t
939make_location (cp_token *caret, cp_token *start, cp_token *end)
940{
941 return make_location (caret: caret->location, start: start->location, finish: end->location);
942}
943
944/* nonzero if we are presently saving tokens. */
945
946static inline int
947cp_lexer_saving_tokens (const cp_lexer* lexer)
948{
949 return lexer->saved_tokens.length () != 0;
950}
951
952/* Store the next token from the preprocessor in *TOKEN. Return true
953 if we reach EOF. If LEXER is NULL, assume we are handling an
954 initial #pragma pch_preprocess, and thus want the lexer to return
955 processed strings.
956
957 Diagnostics issued from this function must have their controlling option (if
958 any) in c.opt annotated as a libcpp option via the CppReason property. */
959
960static void
961cp_lexer_get_preprocessor_token (unsigned flags, cp_token *token)
962{
963 static int is_extern_c = 0;
964
965 /* Get a new token from the preprocessor. */
966 token->type
967 = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
968 flags);
969 token->keyword = RID_MAX;
970 token->purged_p = false;
971 token->error_reported = false;
972 token->tree_check_p = false;
973 /* Usually never see a zero, but just in case ... */
974 token->main_source_p = line_table->depth <= 1;
975
976 /* On some systems, some header files are surrounded by an
977 implicit extern "C" block. Set a flag in the token if it
978 comes from such a header. */
979 is_extern_c += pending_lang_change;
980 pending_lang_change = 0;
981 token->implicit_extern_c = is_extern_c > 0;
982
983 /* Check to see if this token is a keyword. */
984 if (token->type == CPP_NAME)
985 {
986 if (IDENTIFIER_KEYWORD_P (token->u.value))
987 {
988 /* Mark this token as a keyword. */
989 token->type = CPP_KEYWORD;
990 /* Record which keyword. */
991 token->keyword = C_RID_CODE (token->u.value);
992 }
993 else
994 {
995 if (warn_cxx11_compat
996 && ((C_RID_CODE (token->u.value) >= RID_FIRST_CXX11
997 && C_RID_CODE (token->u.value) <= RID_LAST_CXX11)
998 /* These are outside the CXX11 range. */
999 || C_RID_CODE (token->u.value) == RID_ALIGNOF
1000 || C_RID_CODE (token->u.value) == RID_ALIGNAS
1001 || C_RID_CODE (token->u.value)== RID_THREAD))
1002 {
1003 /* Warn about the C++11 keyword (but still treat it as
1004 an identifier). */
1005 warning_at (token->location, OPT_Wc__11_compat,
1006 "identifier %qE is a keyword in C++11",
1007 token->u.value);
1008
1009 /* Clear out the C_RID_CODE so we don't warn about this
1010 particular identifier-turned-keyword again. */
1011 C_SET_RID_CODE (token->u.value, RID_MAX);
1012 }
1013 if (warn_cxx20_compat
1014 && C_RID_CODE (token->u.value) >= RID_FIRST_CXX20
1015 && C_RID_CODE (token->u.value) <= RID_LAST_CXX20)
1016 {
1017 /* Warn about the C++20 keyword (but still treat it as
1018 an identifier). */
1019 warning_at (token->location, OPT_Wc__20_compat,
1020 "identifier %qE is a keyword in C++20",
1021 token->u.value);
1022
1023 /* Clear out the C_RID_CODE so we don't warn about this
1024 particular identifier-turned-keyword again. */
1025 C_SET_RID_CODE (token->u.value, RID_MAX);
1026 }
1027
1028 token->keyword = RID_MAX;
1029 }
1030 }
1031 else if (token->type == CPP_AT_NAME)
1032 {
1033 /* This only happens in Objective-C++; it must be a keyword. */
1034 token->type = CPP_KEYWORD;
1035 switch (C_RID_CODE (token->u.value))
1036 {
1037 /* Replace 'class' with '@class', 'private' with '@private',
1038 etc. This prevents confusion with the C++ keyword
1039 'class', and makes the tokens consistent with other
1040 Objective-C 'AT' keywords. For example '@class' is
1041 reported as RID_AT_CLASS which is consistent with
1042 '@synchronized', which is reported as
1043 RID_AT_SYNCHRONIZED.
1044 */
1045 case RID_CLASS: token->keyword = RID_AT_CLASS; break;
1046 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break;
1047 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
1048 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break;
1049 case RID_THROW: token->keyword = RID_AT_THROW; break;
1050 case RID_TRY: token->keyword = RID_AT_TRY; break;
1051 case RID_CATCH: token->keyword = RID_AT_CATCH; break;
1052 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
1053 default: token->keyword = C_RID_CODE (token->u.value);
1054 }
1055 }
1056}
1057
1058/* Update the globals input_location and the input file stack from TOKEN. */
1059static inline void
1060cp_lexer_set_source_position_from_token (cp_token *token)
1061{
1062 input_location = token->location;
1063}
1064
1065/* Update the globals input_location and the input file stack from LEXER. */
1066static inline void
1067cp_lexer_set_source_position (cp_lexer *lexer)
1068{
1069 cp_token *token = cp_lexer_peek_token (lexer);
1070 cp_lexer_set_source_position_from_token (token);
1071}
1072
1073/* Return a pointer to the next token in the token stream, but do not
1074 consume it. */
1075
1076static inline cp_token *
1077cp_lexer_peek_token (cp_lexer *lexer)
1078{
1079 if (cp_lexer_debugging_p (lexer))
1080 {
1081 fputs (s: "cp_lexer: peeking at token: ", stream: cp_lexer_debug_stream);
1082 cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token);
1083 putc (c: '\n', stream: cp_lexer_debug_stream);
1084 }
1085 return lexer->next_token;
1086}
1087
1088/* Return true if the next token has the indicated TYPE. */
1089
1090static inline bool
1091cp_lexer_next_token_is (cp_lexer* lexer, enum cpp_ttype type)
1092{
1093 return cp_lexer_peek_token (lexer)->type == type;
1094}
1095
1096/* Return true if the next token does not have the indicated TYPE. */
1097
1098static inline bool
1099cp_lexer_next_token_is_not (cp_lexer* lexer, enum cpp_ttype type)
1100{
1101 return !cp_lexer_next_token_is (lexer, type);
1102}
1103
1104/* Return true if the next token is the indicated KEYWORD. */
1105
1106static inline bool
1107cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
1108{
1109 return cp_lexer_peek_token (lexer)->keyword == keyword;
1110}
1111
1112static inline bool
1113cp_lexer_nth_token_is (cp_lexer* lexer, size_t n, enum cpp_ttype type)
1114{
1115 return cp_lexer_peek_nth_token (lexer, n)->type == type;
1116}
1117
1118static inline bool
1119cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword)
1120{
1121 return cp_lexer_peek_nth_token (lexer, n)->keyword == keyword;
1122}
1123
1124/* Return true if KEYWORD can start a decl-specifier. */
1125
1126bool
1127cp_keyword_starts_decl_specifier_p (enum rid keyword)
1128{
1129 switch (keyword)
1130 {
1131 /* auto specifier: storage-class-specifier in C++,
1132 simple-type-specifier in C++0x. */
1133 case RID_AUTO:
1134 /* Storage classes. */
1135 case RID_REGISTER:
1136 case RID_STATIC:
1137 case RID_EXTERN:
1138 case RID_MUTABLE:
1139 case RID_THREAD:
1140 /* Elaborated type specifiers. */
1141 case RID_ENUM:
1142 case RID_CLASS:
1143 case RID_STRUCT:
1144 case RID_UNION:
1145 case RID_TYPENAME:
1146 /* Simple type specifiers. */
1147 case RID_CHAR:
1148 case RID_CHAR8:
1149 case RID_CHAR16:
1150 case RID_CHAR32:
1151 case RID_WCHAR:
1152 case RID_BOOL:
1153 case RID_SHORT:
1154 case RID_INT:
1155 case RID_LONG:
1156 case RID_SIGNED:
1157 case RID_UNSIGNED:
1158 case RID_FLOAT:
1159 case RID_DOUBLE:
1160 CASE_RID_FLOATN_NX:
1161 case RID_VOID:
1162 /* CV qualifiers. */
1163 case RID_CONST:
1164 case RID_VOLATILE:
1165 /* Function specifiers. */
1166 case RID_EXPLICIT:
1167 case RID_VIRTUAL:
1168 /* friend/typdef/inline specifiers. */
1169 case RID_FRIEND:
1170 case RID_TYPEDEF:
1171 case RID_INLINE:
1172 /* GNU extensions. */
1173 case RID_TYPEOF:
1174 /* C++11 extensions. */
1175 case RID_DECLTYPE:
1176 case RID_CONSTEXPR:
1177 /* C++20 extensions. */
1178 case RID_CONSTINIT:
1179 case RID_CONSTEVAL:
1180 return true;
1181
1182 default:
1183 if (keyword >= RID_FIRST_INT_N
1184 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
1185 && int_n_enabled_p[keyword - RID_FIRST_INT_N])
1186 return true;
1187 return false;
1188 }
1189}
1190
1191/* Peeks the corresponding built-in trait if the first token is
1192 a built-in trait and the second token is either `(' or `<' depending
1193 on the trait. Otherwise, returns nullptr. */
1194
1195static const cp_trait *
1196cp_lexer_peek_trait (cp_lexer *lexer)
1197{
1198 const cp_token *token1 = cp_lexer_peek_token (lexer);
1199 if (token1->type == CPP_NAME && IDENTIFIER_TRAIT_P (token1->u.value))
1200 {
1201 const cp_trait &trait = cp_traits[IDENTIFIER_CP_INDEX (token1->u.value)];
1202 const bool is_pack_element = (trait.kind == CPTK_TYPE_PACK_ELEMENT);
1203
1204 /* Check if the subsequent token is a `<' token to
1205 __type_pack_element or is a `(' token to everything else. */
1206 const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
1207 if (is_pack_element && token2->type != CPP_LESS)
1208 return nullptr;
1209 if (!is_pack_element && token2->type != CPP_OPEN_PAREN)
1210 return nullptr;
1211
1212 return &trait;
1213 }
1214 return nullptr;
1215}
1216
1217/* Similarly, but only if the token is an expression-yielding
1218 built-in trait. */
1219
1220static const cp_trait *
1221cp_lexer_peek_trait_expr (cp_lexer *lexer)
1222{
1223 const cp_trait *trait = cp_lexer_peek_trait (lexer);
1224 if (trait && !trait->type)
1225 return trait;
1226
1227 return nullptr;
1228}
1229
1230/* Similarly, but only if the token is a type-yielding
1231 built-in trait. */
1232
1233static const cp_trait *
1234cp_lexer_peek_trait_type (cp_lexer *lexer)
1235{
1236 const cp_trait *trait = cp_lexer_peek_trait (lexer);
1237 if (trait && trait->type)
1238 return trait;
1239
1240 return nullptr;
1241}
1242
1243/* Return true if the next token is a keyword for a decl-specifier. */
1244
1245static bool
1246cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
1247{
1248 cp_token *token;
1249
1250 if (cp_lexer_peek_trait_type (lexer))
1251 return true;
1252
1253 token = cp_lexer_peek_token (lexer);
1254 return cp_keyword_starts_decl_specifier_p (keyword: token->keyword);
1255}
1256
1257/* Returns TRUE iff the token T begins a decltype type. */
1258
1259static bool
1260token_is_decltype (cp_token *t)
1261{
1262 return (t->keyword == RID_DECLTYPE
1263 || t->type == CPP_DECLTYPE);
1264}
1265
1266/* Returns TRUE iff the next token begins a decltype type. */
1267
1268static bool
1269cp_lexer_next_token_is_decltype (cp_lexer *lexer)
1270{
1271 cp_token *t = cp_lexer_peek_token (lexer);
1272 return token_is_decltype (t);
1273}
1274
1275/* Called when processing a token with tree_check_value; perform or defer the
1276 associated checks and return the value. */
1277
1278static tree
1279saved_checks_value (struct tree_check *check_value)
1280{
1281 /* Perform any access checks that were deferred. */
1282 vec<deferred_access_check, va_gc> *checks;
1283 deferred_access_check *chk;
1284 checks = check_value->checks;
1285 if (checks)
1286 {
1287 int i;
1288 FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
1289 perform_or_defer_access_check (chk->binfo,
1290 chk->decl,
1291 chk->diag_decl, tf_warning_or_error);
1292 }
1293 /* Return the stored value. */
1294 return check_value->value;
1295}
1296
1297/* Return a pointer to the Nth token in the token stream. If N is 1,
1298 then this is precisely equivalent to cp_lexer_peek_token (except
1299 that it is not inline). One would like to disallow that case, but
1300 there is one case (cp_parser_nth_token_starts_template_id) where
1301 the caller passes a variable for N and it might be 1. */
1302
1303static cp_token *
1304cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
1305{
1306 cp_token *token;
1307
1308 /* N is 1-based, not zero-based. */
1309 gcc_assert (n > 0);
1310
1311 if (cp_lexer_debugging_p (lexer))
1312 fprintf (stream: cp_lexer_debug_stream,
1313 format: "cp_lexer: peeking ahead " HOST_SIZE_T_PRINT_DEC " at token: ",
1314 (fmt_size_t) n);
1315
1316 --n;
1317 token = lexer->next_token;
1318 while (n && token->type != CPP_EOF)
1319 {
1320 ++token;
1321 if (!token->purged_p)
1322 --n;
1323 }
1324
1325 if (cp_lexer_debugging_p (lexer))
1326 {
1327 cp_lexer_print_token (cp_lexer_debug_stream, token);
1328 putc (c: '\n', stream: cp_lexer_debug_stream);
1329 }
1330
1331 return token;
1332}
1333
1334/* Return the next token, and advance the lexer's next_token pointer
1335 to point to the next non-purged token. */
1336
1337static cp_token *
1338cp_lexer_consume_token (cp_lexer* lexer)
1339{
1340 cp_token *token = lexer->next_token;
1341
1342 do
1343 {
1344 gcc_assert (token->type != CPP_EOF);
1345 lexer->next_token++;
1346 }
1347 while (lexer->next_token->purged_p);
1348
1349 cp_lexer_set_source_position_from_token (token);
1350
1351 /* Provide debugging output. */
1352 if (cp_lexer_debugging_p (lexer))
1353 {
1354 fputs (s: "cp_lexer: consuming token: ", stream: cp_lexer_debug_stream);
1355 cp_lexer_print_token (cp_lexer_debug_stream, token);
1356 putc (c: '\n', stream: cp_lexer_debug_stream);
1357 }
1358
1359 return token;
1360}
1361
1362/* Permanently remove the next token from the token stream, and
1363 advance the next_token pointer to refer to the next non-purged
1364 token. */
1365
1366static void
1367cp_lexer_purge_token (cp_lexer *lexer)
1368{
1369 cp_token *tok = lexer->next_token;
1370
1371 gcc_assert (tok->type != CPP_EOF);
1372 tok->purged_p = true;
1373 tok->location = UNKNOWN_LOCATION;
1374 tok->u.value = NULL_TREE;
1375 tok->keyword = RID_MAX;
1376
1377 do
1378 tok++;
1379 while (tok->purged_p);
1380 lexer->next_token = tok;
1381}
1382
1383/* Permanently remove all tokens after TOK, up to, but not
1384 including, the token that will be returned next by
1385 cp_lexer_peek_token. */
1386
1387static void
1388cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
1389{
1390 cp_token *peek = lexer->next_token;
1391
1392 gcc_assert (tok < peek);
1393
1394 for (tok++; tok != peek; tok++)
1395 {
1396 tok->purged_p = true;
1397 tok->location = UNKNOWN_LOCATION;
1398 tok->u.value = NULL_TREE;
1399 tok->keyword = RID_MAX;
1400 }
1401}
1402
1403/* Begin saving tokens. All tokens consumed after this point will be
1404 preserved. */
1405
1406static void
1407cp_lexer_save_tokens (cp_lexer* lexer)
1408{
1409 /* Provide debugging output. */
1410 if (cp_lexer_debugging_p (lexer))
1411 fprintf (stream: cp_lexer_debug_stream, format: "cp_lexer: saving tokens\n");
1412
1413 lexer->saved_tokens.safe_push (obj: lexer->next_token);
1414}
1415
1416/* Commit to the portion of the token stream most recently saved. */
1417
1418static void
1419cp_lexer_commit_tokens (cp_lexer* lexer)
1420{
1421 /* Provide debugging output. */
1422 if (cp_lexer_debugging_p (lexer))
1423 fprintf (stream: cp_lexer_debug_stream, format: "cp_lexer: committing tokens\n");
1424
1425 lexer->saved_tokens.pop ();
1426}
1427
1428/* Return all tokens saved since the last call to cp_lexer_save_tokens
1429 to the token stream. Stop saving tokens. */
1430
1431static void
1432cp_lexer_rollback_tokens (cp_lexer* lexer)
1433{
1434 /* Provide debugging output. */
1435 if (cp_lexer_debugging_p (lexer))
1436 fprintf (stream: cp_lexer_debug_stream, format: "cp_lexer: restoring tokens\n");
1437
1438 lexer->next_token = lexer->saved_tokens.pop ();
1439}
1440
1441/* Determines what saved_token_sentinel does when going out of scope. */
1442
1443enum saved_token_sentinel_mode {
1444 STS_COMMIT,
1445 STS_ROLLBACK,
1446 STS_DONOTHING
1447};
1448
1449/* RAII wrapper around the above functions, with sanity checking (the token
1450 stream should be the same at the point of instantiation as it is at the
1451 point of destruction).
1452
1453 Creating a variable saves tokens. MODE determines what happens when the
1454 object is destroyed. STS_COMMIT commits tokens (default),
1455 STS_ROLLBACK rolls-back and STS_DONOTHING does nothing. Calling
1456 rollback() will immediately roll-back tokens and set MODE to
1457 STS_DONOTHING. */
1458
1459struct saved_token_sentinel
1460{
1461 cp_lexer *lexer;
1462 unsigned len;
1463 saved_token_sentinel_mode mode;
1464 saved_token_sentinel (cp_lexer *_lexer,
1465 saved_token_sentinel_mode _mode = STS_COMMIT)
1466 : lexer (_lexer), mode (_mode)
1467 {
1468 len = lexer->saved_tokens.length ();
1469 cp_lexer_save_tokens (lexer);
1470 }
1471 void rollback ()
1472 {
1473 cp_lexer_rollback_tokens (lexer);
1474 cp_lexer_set_source_position_from_token
1475 (token: cp_lexer_previous_token (lexer));
1476 mode = STS_DONOTHING;
1477 }
1478 ~saved_token_sentinel ()
1479 {
1480 if (mode == STS_COMMIT)
1481 cp_lexer_commit_tokens (lexer);
1482 else if (mode == STS_ROLLBACK)
1483 rollback ();
1484
1485 gcc_assert (lexer->saved_tokens.length () == len);
1486 }
1487};
1488
1489/* Print a representation of the TOKEN on the STREAM. */
1490
1491static void
1492cp_lexer_print_token (FILE * stream, cp_token *token)
1493{
1494 /* We don't use cpp_type2name here because the parser defines
1495 a few tokens of its own. */
1496 static const char *const token_names[] = {
1497 /* cpplib-defined token types */
1498#define OP(e, s) #e,
1499#define TK(e, s) #e,
1500 TTYPE_TABLE
1501#undef OP
1502#undef TK
1503 /* C++ parser token types - see "Manifest constants", above. */
1504 "KEYWORD",
1505 "TEMPLATE_ID",
1506 "NESTED_NAME_SPECIFIER",
1507 };
1508
1509 /* For some tokens, print the associated data. */
1510 switch (token->type)
1511 {
1512 case CPP_KEYWORD:
1513 /* Some keywords have a value that is not an IDENTIFIER_NODE.
1514 For example, `struct' is mapped to an INTEGER_CST. */
1515 if (!identifier_p (t: token->u.value))
1516 break;
1517 /* fall through */
1518 case CPP_NAME:
1519 fputs (IDENTIFIER_POINTER (token->u.value), stream: stream);
1520 break;
1521
1522 case CPP_STRING:
1523 case CPP_STRING16:
1524 case CPP_STRING32:
1525 case CPP_WSTRING:
1526 case CPP_UTF8STRING:
1527 fprintf (stream: stream, format: " \"%s\"", TREE_STRING_POINTER (token->u.value));
1528 break;
1529
1530 case CPP_NUMBER:
1531 print_generic_expr (stream, token->u.value);
1532 break;
1533
1534 default:
1535 /* If we have a name for the token, print it out. Otherwise, we
1536 simply give the numeric code. */
1537 if (token->type < ARRAY_SIZE(token_names))
1538 fputs (s: token_names[token->type], stream: stream);
1539 else
1540 fprintf (stream: stream, format: "[%d]", token->type);
1541 break;
1542 }
1543}
1544
1545DEBUG_FUNCTION void
1546debug (cp_token &ref)
1547{
1548 cp_lexer_print_token (stderr, token: &ref);
1549 fprintf (stderr, format: "\n");
1550}
1551
1552DEBUG_FUNCTION void
1553debug (cp_token *ptr)
1554{
1555 if (ptr)
1556 debug (ref&: *ptr);
1557 else
1558 fprintf (stderr, format: "<nil>\n");
1559}
1560
1561
1562/* Start emitting debugging information. */
1563
1564static void
1565cp_lexer_start_debugging (cp_lexer* lexer)
1566{
1567 if (!LEXER_DEBUGGING_ENABLED_P)
1568 fatal_error (input_location,
1569 "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true");
1570
1571 lexer->debugging_p = true;
1572 cp_lexer_debug_stream = stderr;
1573}
1574
1575/* Stop emitting debugging information. */
1576
1577static void
1578cp_lexer_stop_debugging (cp_lexer* lexer)
1579{
1580 if (!LEXER_DEBUGGING_ENABLED_P)
1581 fatal_error (input_location,
1582 "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true");
1583
1584 lexer->debugging_p = false;
1585 cp_lexer_debug_stream = NULL;
1586}
1587
1588/* Create a new cp_token_cache, representing a range of tokens. */
1589
1590static cp_token_cache *
1591cp_token_cache_new (cp_token *first, cp_token *last)
1592{
1593 cp_token_cache *cache = ggc_alloc<cp_token_cache> ();
1594 cache->first = first;
1595 cache->last = last;
1596 return cache;
1597}
1598
1599/* Diagnose if #pragma omp declare simd isn't followed immediately
1600 by function declaration or definition. */
1601
1602static inline void
1603cp_ensure_no_omp_declare_simd (cp_parser *parser)
1604{
1605 if (parser->omp_declare_simd && !parser->omp_declare_simd->error_seen)
1606 {
1607 error ("%<#pragma omp declare %s%> not immediately followed by "
1608 "function declaration or definition",
1609 parser->omp_declare_simd->variant_p ? "variant" : "simd");
1610 parser->omp_declare_simd = NULL;
1611 }
1612}
1613
1614/* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
1615 and put that into "omp declare simd" attribute. */
1616
1617static inline void
1618cp_finalize_omp_declare_simd (cp_parser *parser, tree fndecl)
1619{
1620 if (UNLIKELY (parser->omp_declare_simd != NULL))
1621 {
1622 if (fndecl == error_mark_node)
1623 {
1624 parser->omp_declare_simd = NULL;
1625 return;
1626 }
1627 if (TREE_CODE (fndecl) != FUNCTION_DECL)
1628 {
1629 cp_ensure_no_omp_declare_simd (parser);
1630 return;
1631 }
1632 }
1633}
1634
1635/* Similarly, but for use in declaration parsing functions
1636 which call cp_parser_handle_directive_omp_attributes. */
1637
1638static inline void
1639cp_finalize_omp_declare_simd (cp_parser *parser, cp_omp_declare_simd_data *data)
1640{
1641 if (parser->omp_declare_simd != data)
1642 return;
1643
1644 if (!parser->omp_declare_simd->error_seen
1645 && !parser->omp_declare_simd->fndecl_seen)
1646 error_at (parser->omp_declare_simd->loc,
1647 "%<declare %s%> directive not immediately followed by "
1648 "function declaration or definition",
1649 parser->omp_declare_simd->variant_p ? "variant" : "simd");
1650 parser->omp_declare_simd = NULL;
1651}
1652
1653/* Diagnose if #pragma acc routine isn't followed immediately by function
1654 declaration or definition. */
1655
1656static inline void
1657cp_ensure_no_oacc_routine (cp_parser *parser)
1658{
1659 if (parser->oacc_routine && !parser->oacc_routine->error_seen)
1660 {
1661 error_at (parser->oacc_routine->loc,
1662 "%<#pragma acc routine%> not immediately followed by "
1663 "function declaration or definition");
1664 parser->oacc_routine = NULL;
1665 }
1666}
1667
1668/* Decl-specifiers. */
1669
1670/* Set *DECL_SPECS to represent an empty decl-specifier-seq. */
1671
1672static void
1673clear_decl_specs (cp_decl_specifier_seq *decl_specs)
1674{
1675 memset (s: decl_specs, c: 0, n: sizeof (cp_decl_specifier_seq));
1676}
1677
1678/* Declarators. */
1679
1680/* Nothing other than the parser should be creating declarators;
1681 declarators are a semi-syntactic representation of C++ entities.
1682 Other parts of the front end that need to create entities (like
1683 VAR_DECLs or FUNCTION_DECLs) should do that directly. */
1684
1685static cp_declarator *make_call_declarator
1686 (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier,
1687 tree, tree, tree, tree, tree, location_t);
1688static cp_declarator *make_array_declarator
1689 (cp_declarator *, tree);
1690static cp_declarator *make_pointer_declarator
1691 (cp_cv_quals, cp_declarator *, tree);
1692static cp_declarator *make_reference_declarator
1693 (cp_cv_quals, cp_declarator *, bool, tree);
1694static cp_declarator *make_ptrmem_declarator
1695 (cp_cv_quals, tree, cp_declarator *, tree);
1696
1697/* An erroneous declarator. */
1698static cp_declarator *cp_error_declarator;
1699
1700/* The obstack on which declarators and related data structures are
1701 allocated. */
1702static struct obstack declarator_obstack;
1703
1704/* Alloc BYTES from the declarator memory pool. */
1705
1706static inline void *
1707alloc_declarator (size_t bytes)
1708{
1709 return obstack_alloc (&declarator_obstack, bytes);
1710}
1711
1712/* Allocate a declarator of the indicated KIND. Clear fields that are
1713 common to all declarators. */
1714
1715static cp_declarator *
1716make_declarator (cp_declarator_kind kind)
1717{
1718 cp_declarator *declarator;
1719
1720 declarator = (cp_declarator *) alloc_declarator (bytes: sizeof (cp_declarator));
1721 declarator->kind = kind;
1722 declarator->parenthesized = UNKNOWN_LOCATION;
1723 declarator->attributes = NULL_TREE;
1724 declarator->std_attributes = NULL_TREE;
1725 declarator->declarator = NULL;
1726 declarator->parameter_pack_p = false;
1727 declarator->id_loc = UNKNOWN_LOCATION;
1728 declarator->init_loc = UNKNOWN_LOCATION;
1729
1730 return declarator;
1731}
1732
1733/* Make a declarator for a generalized identifier. If
1734 QUALIFYING_SCOPE is non-NULL, the identifier is
1735 QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just
1736 UNQUALIFIED_NAME. SFK indicates the kind of special function this
1737 is, if any. */
1738
1739static cp_declarator *
1740make_id_declarator (tree qualifying_scope, tree unqualified_name,
1741 special_function_kind sfk, location_t id_location)
1742{
1743 cp_declarator *declarator;
1744
1745 /* It is valid to write:
1746
1747 class C { void f(); };
1748 typedef C D;
1749 void D::f();
1750
1751 The standard is not clear about whether `typedef const C D' is
1752 legal; as of 2002-09-15 the committee is considering that
1753 question. EDG 3.0 allows that syntax. Therefore, we do as
1754 well. */
1755 if (qualifying_scope && TYPE_P (qualifying_scope))
1756 qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
1757
1758 gcc_assert (identifier_p (unqualified_name)
1759 || TREE_CODE (unqualified_name) == BIT_NOT_EXPR
1760 || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR);
1761
1762 declarator = make_declarator (kind: cdk_id);
1763 declarator->u.id.qualifying_scope = qualifying_scope;
1764 declarator->u.id.unqualified_name = unqualified_name;
1765 declarator->u.id.sfk = sfk;
1766 declarator->id_loc = id_location;
1767
1768 return declarator;
1769}
1770
1771/* Make a declarator for a pointer to TARGET. CV_QUALIFIERS is a list
1772 of modifiers such as const or volatile to apply to the pointer
1773 type, represented as identifiers. ATTRIBUTES represent the attributes that
1774 appertain to the pointer or reference. */
1775
1776cp_declarator *
1777make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
1778 tree attributes)
1779{
1780 cp_declarator *declarator;
1781
1782 declarator = make_declarator (kind: cdk_pointer);
1783 declarator->declarator = target;
1784 declarator->u.pointer.qualifiers = cv_qualifiers;
1785 declarator->u.pointer.class_type = NULL_TREE;
1786 if (target)
1787 {
1788 declarator->id_loc = target->id_loc;
1789 declarator->parameter_pack_p = target->parameter_pack_p;
1790 target->parameter_pack_p = false;
1791 }
1792 else
1793 declarator->parameter_pack_p = false;
1794
1795 declarator->std_attributes = attributes;
1796
1797 return declarator;
1798}
1799
1800/* Like make_pointer_declarator -- but for references. ATTRIBUTES
1801 represent the attributes that appertain to the pointer or
1802 reference. */
1803
1804cp_declarator *
1805make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
1806 bool rvalue_ref, tree attributes)
1807{
1808 cp_declarator *declarator;
1809
1810 declarator = make_declarator (kind: cdk_reference);
1811 declarator->declarator = target;
1812 declarator->u.reference.qualifiers = cv_qualifiers;
1813 declarator->u.reference.rvalue_ref = rvalue_ref;
1814 if (target)
1815 {
1816 declarator->id_loc = target->id_loc;
1817 declarator->parameter_pack_p = target->parameter_pack_p;
1818 target->parameter_pack_p = false;
1819 }
1820 else
1821 declarator->parameter_pack_p = false;
1822
1823 declarator->std_attributes = attributes;
1824
1825 return declarator;
1826}
1827
1828/* Like make_pointer_declarator -- but for a pointer to a non-static
1829 member of CLASS_TYPE. ATTRIBUTES represent the attributes that
1830 appertain to the pointer or reference. */
1831
1832cp_declarator *
1833make_ptrmem_declarator (cp_cv_quals cv_qualifiers, tree class_type,
1834 cp_declarator *pointee,
1835 tree attributes)
1836{
1837 cp_declarator *declarator;
1838
1839 declarator = make_declarator (kind: cdk_ptrmem);
1840 declarator->declarator = pointee;
1841 declarator->u.pointer.qualifiers = cv_qualifiers;
1842 declarator->u.pointer.class_type = class_type;
1843
1844 if (pointee)
1845 {
1846 declarator->parameter_pack_p = pointee->parameter_pack_p;
1847 pointee->parameter_pack_p = false;
1848 }
1849 else
1850 declarator->parameter_pack_p = false;
1851
1852 declarator->std_attributes = attributes;
1853
1854 return declarator;
1855}
1856
1857/* Make a declarator for the function given by TARGET, with the
1858 indicated PARMS. The CV_QUALIFIERS apply to the function, as in
1859 "const"-qualified member function. The EXCEPTION_SPECIFICATION
1860 indicates what exceptions can be thrown. STD_ATTRS contains
1861 attributes that appertain to the function type. */
1862
1863cp_declarator *
1864make_call_declarator (cp_declarator *target,
1865 tree parms,
1866 cp_cv_quals cv_qualifiers,
1867 cp_virt_specifiers virt_specifiers,
1868 cp_ref_qualifier ref_qualifier,
1869 tree tx_qualifier,
1870 tree exception_specification,
1871 tree late_return_type,
1872 tree requires_clause,
1873 tree std_attrs,
1874 location_t parens_loc)
1875{
1876 cp_declarator *declarator;
1877
1878 declarator = make_declarator (kind: cdk_function);
1879 declarator->declarator = target;
1880 declarator->u.function.parameters = parms;
1881 declarator->u.function.qualifiers = cv_qualifiers;
1882 declarator->u.function.virt_specifiers = virt_specifiers;
1883 declarator->u.function.ref_qualifier = ref_qualifier;
1884 declarator->u.function.tx_qualifier = tx_qualifier;
1885 declarator->u.function.exception_specification = exception_specification;
1886 declarator->u.function.late_return_type = late_return_type;
1887 declarator->u.function.requires_clause = requires_clause;
1888 declarator->u.function.parens_loc = parens_loc;
1889 if (target)
1890 {
1891 declarator->id_loc = target->id_loc;
1892 declarator->parameter_pack_p = target->parameter_pack_p;
1893 target->parameter_pack_p = false;
1894 }
1895 else
1896 declarator->parameter_pack_p = false;
1897
1898 declarator->std_attributes = std_attrs;
1899
1900 return declarator;
1901}
1902
1903/* Make a declarator for an array of BOUNDS elements, each of which is
1904 defined by ELEMENT. */
1905
1906cp_declarator *
1907make_array_declarator (cp_declarator *element, tree bounds)
1908{
1909 cp_declarator *declarator;
1910
1911 declarator = make_declarator (kind: cdk_array);
1912 declarator->declarator = element;
1913 declarator->u.array.bounds = bounds;
1914 if (element)
1915 {
1916 declarator->id_loc = element->id_loc;
1917 declarator->parameter_pack_p = element->parameter_pack_p;
1918 element->parameter_pack_p = false;
1919 }
1920 else
1921 declarator->parameter_pack_p = false;
1922
1923 return declarator;
1924}
1925
1926/* Determine whether the declarator we've seen so far can be a
1927 parameter pack, when followed by an ellipsis. */
1928static bool
1929declarator_can_be_parameter_pack (cp_declarator *declarator)
1930{
1931 if (declarator && declarator->parameter_pack_p)
1932 /* We already saw an ellipsis. */
1933 return false;
1934
1935 /* Search for a declarator name, or any other declarator that goes
1936 after the point where the ellipsis could appear in a parameter
1937 pack. If we find any of these, then this declarator cannot be
1938 made into a parameter pack. */
1939 bool found = false;
1940 while (declarator && !found)
1941 {
1942 switch ((int)declarator->kind)
1943 {
1944 case cdk_id:
1945 case cdk_array:
1946 case cdk_decomp:
1947 found = true;
1948 break;
1949
1950 case cdk_error:
1951 return true;
1952
1953 default:
1954 declarator = declarator->declarator;
1955 break;
1956 }
1957 }
1958
1959 return !found;
1960}
1961
1962cp_parameter_declarator *no_parameters;
1963
1964/* Create a parameter declarator with the indicated DECL_SPECIFIERS,
1965 DECLARATOR and DEFAULT_ARGUMENT. */
1966
1967cp_parameter_declarator *
1968make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers,
1969 cp_declarator *declarator,
1970 tree default_argument,
1971 location_t loc,
1972 bool template_parameter_pack_p = false)
1973{
1974 cp_parameter_declarator *parameter;
1975
1976 parameter = ((cp_parameter_declarator *)
1977 alloc_declarator (bytes: sizeof (cp_parameter_declarator)));
1978 parameter->next = NULL;
1979 if (decl_specifiers)
1980 parameter->decl_specifiers = *decl_specifiers;
1981 else
1982 clear_decl_specs (decl_specs: &parameter->decl_specifiers);
1983 parameter->declarator = declarator;
1984 parameter->default_argument = default_argument;
1985 parameter->template_parameter_pack_p = template_parameter_pack_p;
1986 parameter->loc = loc;
1987
1988 return parameter;
1989}
1990
1991/* Returns true iff DECLARATOR is a declaration for a function. */
1992
1993static bool
1994function_declarator_p (const cp_declarator *declarator)
1995{
1996 while (declarator)
1997 {
1998 if (declarator->kind == cdk_function
1999 && declarator->declarator->kind == cdk_id)
2000 return true;
2001 if (declarator->kind == cdk_id
2002 || declarator->kind == cdk_decomp
2003 || declarator->kind == cdk_error)
2004 return false;
2005 declarator = declarator->declarator;
2006 }
2007 return false;
2008}
2009
2010/* The parser. */
2011
2012/* Overview
2013 --------
2014
2015 A cp_parser parses the token stream as specified by the C++
2016 grammar. Its job is purely parsing, not semantic analysis. For
2017 example, the parser breaks the token stream into declarators,
2018 expressions, statements, and other similar syntactic constructs.
2019 It does not check that the types of the expressions on either side
2020 of an assignment-statement are compatible, or that a function is
2021 not declared with a parameter of type `void'.
2022
2023 The parser invokes routines elsewhere in the compiler to perform
2024 semantic analysis and to build up the abstract syntax tree for the
2025 code processed.
2026
2027 The parser (and the template instantiation code, which is, in a
2028 way, a close relative of parsing) are the only parts of the
2029 compiler that should be calling push_scope and pop_scope, or
2030 related functions. The parser (and template instantiation code)
2031 keeps track of what scope is presently active; everything else
2032 should simply honor that. (The code that generates static
2033 initializers may also need to set the scope, in order to check
2034 access control correctly when emitting the initializers.)
2035
2036 Methodology
2037 -----------
2038
2039 The parser is of the standard recursive-descent variety. Upcoming
2040 tokens in the token stream are examined in order to determine which
2041 production to use when parsing a non-terminal. Some C++ constructs
2042 require arbitrary look ahead to disambiguate. For example, it is
2043 impossible, in the general case, to tell whether a statement is an
2044 expression or declaration without scanning the entire statement.
2045 Therefore, the parser is capable of "parsing tentatively." When the
2046 parser is not sure what construct comes next, it enters this mode.
2047 Then, while we attempt to parse the construct, the parser queues up
2048 error messages, rather than issuing them immediately, and saves the
2049 tokens it consumes. If the construct is parsed successfully, the
2050 parser "commits", i.e., it issues any queued error messages and
2051 the tokens that were being preserved are permanently discarded.
2052 If, however, the construct is not parsed successfully, the parser
2053 rolls back its state completely so that it can resume parsing using
2054 a different alternative.
2055
2056 Future Improvements
2057 -------------------
2058
2059 The performance of the parser could probably be improved substantially.
2060 We could often eliminate the need to parse tentatively by looking ahead
2061 a little bit. In some places, this approach might not entirely eliminate
2062 the need to parse tentatively, but it might still speed up the average
2063 case. */
2064
2065/* Flags that are passed to some parsing functions. These values can
2066 be bitwise-ored together. */
2067
2068enum
2069{
2070 /* No flags. */
2071 CP_PARSER_FLAGS_NONE = 0x0,
2072 /* The construct is optional. If it is not present, then no error
2073 should be issued. */
2074 CP_PARSER_FLAGS_OPTIONAL = 0x1,
2075 /* When parsing a type-specifier, treat user-defined type-names
2076 as non-type identifiers. */
2077 CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2,
2078 /* When parsing a type-specifier, do not try to parse a class-specifier
2079 or enum-specifier. */
2080 CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4,
2081 /* When parsing a decl-specifier-seq, only allow type-specifier or
2082 constexpr. */
2083 CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR = 0x8,
2084 /* When parsing a decl-specifier-seq, only allow mutable, constexpr or
2085 for C++20 consteval or for C++23 static. */
2086 CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10,
2087 /* When parsing a decl-specifier-seq, allow missing typename. */
2088 CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20,
2089 /* When parsing of the noexcept-specifier should be delayed. */
2090 CP_PARSER_FLAGS_DELAY_NOEXCEPT = 0x40,
2091 /* When parsing a consteval declarator. */
2092 CP_PARSER_FLAGS_CONSTEVAL = 0x80,
2093 /* When parsing a parameter declaration. */
2094 CP_PARSER_FLAGS_PARAMETER = 0x100
2095};
2096
2097/* This type is used for parameters and variables which hold
2098 combinations of the above flags. */
2099typedef int cp_parser_flags;
2100
2101/* The different kinds of declarators we want to parse. */
2102
2103enum cp_parser_declarator_kind
2104{
2105 /* We want an abstract declarator. */
2106 CP_PARSER_DECLARATOR_ABSTRACT,
2107 /* We want a named declarator. */
2108 CP_PARSER_DECLARATOR_NAMED,
2109 /* We don't mind, but the name must be an unqualified-id. */
2110 CP_PARSER_DECLARATOR_EITHER
2111};
2112
2113/* The precedence values used to parse binary expressions. The minimum value
2114 of PREC must be 1, because zero is reserved to quickly discriminate
2115 binary operators from other tokens. */
2116
2117enum cp_parser_prec
2118{
2119 PREC_NOT_OPERATOR,
2120 PREC_LOGICAL_OR_EXPRESSION,
2121 PREC_LOGICAL_AND_EXPRESSION,
2122 PREC_INCLUSIVE_OR_EXPRESSION,
2123 PREC_EXCLUSIVE_OR_EXPRESSION,
2124 PREC_AND_EXPRESSION,
2125 PREC_EQUALITY_EXPRESSION,
2126 PREC_RELATIONAL_EXPRESSION,
2127 PREC_SPACESHIP_EXPRESSION,
2128 PREC_SHIFT_EXPRESSION,
2129 PREC_ADDITIVE_EXPRESSION,
2130 PREC_MULTIPLICATIVE_EXPRESSION,
2131 PREC_PM_EXPRESSION,
2132 NUM_PREC_VALUES = PREC_PM_EXPRESSION
2133};
2134
2135/* A mapping from a token type to a corresponding tree node type, with a
2136 precedence value. */
2137
2138struct cp_parser_binary_operations_map_node
2139{
2140 /* The token type. */
2141 enum cpp_ttype token_type;
2142 /* The corresponding tree code. */
2143 enum tree_code tree_type;
2144 /* The precedence of this operator. */
2145 enum cp_parser_prec prec;
2146};
2147
2148struct cp_parser_expression_stack_entry
2149{
2150 /* Left hand side of the binary operation we are currently
2151 parsing. */
2152 cp_expr lhs;
2153 /* Original tree code for left hand side, if it was a binary
2154 expression itself (used for -Wparentheses). */
2155 enum tree_code lhs_type;
2156 /* Tree code for the binary operation we are parsing. */
2157 enum tree_code tree_type;
2158 /* Precedence of the binary operation we are parsing. */
2159 enum cp_parser_prec prec;
2160 /* Location of the binary operation we are parsing. */
2161 location_t loc;
2162 /* Flags from the operator token. */
2163 unsigned char flags;
2164};
2165
2166/* The stack for storing partial expressions. We only need NUM_PREC_VALUES
2167 entries because precedence levels on the stack are monotonically
2168 increasing. */
2169typedef struct cp_parser_expression_stack_entry
2170 cp_parser_expression_stack[NUM_PREC_VALUES];
2171
2172/* Used for parsing OMP for loops.
2173
2174 Some notes on flags used for context:
2175 parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
2176 construct, except for the final-loop-body.
2177 The want_nested_loop flag is true if inside a {} sequence where
2178 a loop-nest (or another {} sequence containing a loop-nest) is expected,
2179 but has not yet been seen. It's false when parsing intervening code
2180 statements or their substatements that cannot contain a loop-nest.
2181 The in_intervening_code flag is true when parsing any intervening code,
2182 including substatements, and whether or not want_nested_loop is true.
2183
2184 And, about error handling:
2185 The saw_intervening_code flag is set if the loop is not perfectly
2186 nested, even in the usual case where this is not an error.
2187 perfect_nesting_fail is set if an error has been diagnosed because an
2188 imperfectly-nested loop was found where a perfectly-nested one is
2189 required (we diagnose this only once).
2190 fail is set if any kind of structural error in the loop nest
2191 has been found and diagnosed.
2192 */
2193struct omp_for_parse_data {
2194 enum tree_code code;
2195 tree declv, condv, incrv, initv;
2196 tree pre_body;
2197 tree orig_declv;
2198 auto_vec<tree, 4> orig_inits;
2199 int count; /* Expected nesting depth. */
2200 int depth; /* Current nesting depth. */
2201 location_t for_loc;
2202 releasing_vec init_blockv;
2203 releasing_vec body_blockv;
2204 releasing_vec init_placeholderv;
2205 releasing_vec body_placeholderv;
2206 bool ordered : 1;
2207 bool inscan : 1;
2208 bool want_nested_loop : 1;
2209 bool in_intervening_code : 1;
2210 bool saw_intervening_code : 1;
2211 bool perfect_nesting_fail : 1;
2212 bool fail : 1;
2213 tree clauses;
2214 tree *cclauses;
2215 tree ordered_cl;
2216};
2217
2218/* Prototypes. */
2219
2220/* Constructors and destructors. */
2221
2222static cp_parser_context *cp_parser_context_new
2223 (cp_parser_context *);
2224
2225/* Class variables. */
2226
2227static GTY((deletable)) cp_parser_context* cp_parser_context_free_list;
2228
2229/* The operator-precedence table used by cp_parser_binary_expression.
2230 Transformed into an associative array (binops_by_token) by
2231 cp_parser_new. */
2232
2233static const cp_parser_binary_operations_map_node binops[] = {
2234 { .token_type: CPP_DEREF_STAR, .tree_type: MEMBER_REF, .prec: PREC_PM_EXPRESSION },
2235 { .token_type: CPP_DOT_STAR, .tree_type: DOTSTAR_EXPR, .prec: PREC_PM_EXPRESSION },
2236
2237 { .token_type: CPP_MULT, .tree_type: MULT_EXPR, .prec: PREC_MULTIPLICATIVE_EXPRESSION },
2238 { .token_type: CPP_DIV, .tree_type: TRUNC_DIV_EXPR, .prec: PREC_MULTIPLICATIVE_EXPRESSION },
2239 { .token_type: CPP_MOD, .tree_type: TRUNC_MOD_EXPR, .prec: PREC_MULTIPLICATIVE_EXPRESSION },
2240
2241 { .token_type: CPP_PLUS, .tree_type: PLUS_EXPR, .prec: PREC_ADDITIVE_EXPRESSION },
2242 { .token_type: CPP_MINUS, .tree_type: MINUS_EXPR, .prec: PREC_ADDITIVE_EXPRESSION },
2243
2244 { .token_type: CPP_LSHIFT, .tree_type: LSHIFT_EXPR, .prec: PREC_SHIFT_EXPRESSION },
2245 { .token_type: CPP_RSHIFT, .tree_type: RSHIFT_EXPR, .prec: PREC_SHIFT_EXPRESSION },
2246
2247 { .token_type: CPP_SPACESHIP, .tree_type: SPACESHIP_EXPR, .prec: PREC_SPACESHIP_EXPRESSION },
2248
2249 { .token_type: CPP_LESS, .tree_type: LT_EXPR, .prec: PREC_RELATIONAL_EXPRESSION },
2250 { .token_type: CPP_GREATER, .tree_type: GT_EXPR, .prec: PREC_RELATIONAL_EXPRESSION },
2251 { .token_type: CPP_LESS_EQ, .tree_type: LE_EXPR, .prec: PREC_RELATIONAL_EXPRESSION },
2252 { .token_type: CPP_GREATER_EQ, .tree_type: GE_EXPR, .prec: PREC_RELATIONAL_EXPRESSION },
2253
2254 { .token_type: CPP_EQ_EQ, .tree_type: EQ_EXPR, .prec: PREC_EQUALITY_EXPRESSION },
2255 { .token_type: CPP_NOT_EQ, .tree_type: NE_EXPR, .prec: PREC_EQUALITY_EXPRESSION },
2256
2257 { .token_type: CPP_AND, .tree_type: BIT_AND_EXPR, .prec: PREC_AND_EXPRESSION },
2258
2259 { .token_type: CPP_XOR, .tree_type: BIT_XOR_EXPR, .prec: PREC_EXCLUSIVE_OR_EXPRESSION },
2260
2261 { .token_type: CPP_OR, .tree_type: BIT_IOR_EXPR, .prec: PREC_INCLUSIVE_OR_EXPRESSION },
2262
2263 { .token_type: CPP_AND_AND, .tree_type: TRUTH_ANDIF_EXPR, .prec: PREC_LOGICAL_AND_EXPRESSION },
2264
2265 { .token_type: CPP_OR_OR, .tree_type: TRUTH_ORIF_EXPR, .prec: PREC_LOGICAL_OR_EXPRESSION }
2266};
2267
2268/* The same as binops, but initialized by cp_parser_new so that
2269 binops_by_token[N].token_type == N. Used in cp_parser_binary_expression
2270 for speed. */
2271static cp_parser_binary_operations_map_node binops_by_token[N_CP_TTYPES];
2272
2273/* Constructors and destructors. */
2274
2275/* Construct a new context. The context below this one on the stack
2276 is given by NEXT. */
2277
2278static cp_parser_context *
2279cp_parser_context_new (cp_parser_context* next)
2280{
2281 cp_parser_context *context;
2282
2283 /* Allocate the storage. */
2284 if (cp_parser_context_free_list != NULL)
2285 {
2286 /* Pull the first entry from the free list. */
2287 context = cp_parser_context_free_list;
2288 cp_parser_context_free_list = context->next;
2289 memset (s: context, c: 0, n: sizeof (*context));
2290 }
2291 else
2292 context = ggc_cleared_alloc<cp_parser_context> ();
2293
2294 /* No errors have occurred yet in this context. */
2295 context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
2296 /* If this is not the bottommost context, copy information that we
2297 need from the previous context. */
2298 if (next)
2299 {
2300 /* If, in the NEXT context, we are parsing an `x->' or `x.'
2301 expression, then we are parsing one in this context, too. */
2302 context->object_type = next->object_type;
2303 /* Thread the stack. */
2304 context->next = next;
2305 }
2306
2307 return context;
2308}
2309
2310/* Managing the unparsed function queues. */
2311
2312#define unparsed_funs_with_default_args \
2313 parser->unparsed_queues->last ().funs_with_default_args
2314#define unparsed_funs_with_definitions \
2315 parser->unparsed_queues->last ().funs_with_definitions
2316#define unparsed_nsdmis \
2317 parser->unparsed_queues->last ().nsdmis
2318#define unparsed_noexcepts \
2319 parser->unparsed_queues->last ().noexcepts
2320#define unparsed_contracts \
2321 parser->unparsed_queues->last ().contracts
2322
2323static void
2324push_unparsed_function_queues (cp_parser *parser)
2325{
2326 cp_unparsed_functions_entry e
2327 = { NULL, .funs_with_definitions: make_tree_vector (), NULL, NULL, NULL };
2328 vec_safe_push (v&: parser->unparsed_queues, obj: e);
2329}
2330
2331static void
2332pop_unparsed_function_queues (cp_parser *parser)
2333{
2334 release_tree_vector (unparsed_funs_with_definitions);
2335 parser->unparsed_queues->pop ();
2336}
2337
2338/* Prototypes. */
2339
2340/* Routines to parse various constructs.
2341
2342 Those that return `tree' will return the error_mark_node (rather
2343 than NULL_TREE) if a parse error occurs, unless otherwise noted.
2344 Sometimes, they will return an ordinary node if error-recovery was
2345 attempted, even though a parse error occurred. So, to check
2346 whether or not a parse error occurred, you should always use
2347 cp_parser_error_occurred. If the construct is optional (indicated
2348 either by an `_opt' in the name of the function that does the
2349 parsing or via a FLAGS parameter), then NULL_TREE is returned if
2350 the construct is not present. */
2351
2352/* Lexical conventions [gram.lex] */
2353
2354static tree finish_userdef_string_literal
2355 (tree);
2356
2357/* Basic concepts [gram.basic] */
2358
2359static void cp_parser_translation_unit (cp_parser *);
2360
2361/* Expressions [gram.expr] */
2362
2363static cp_expr cp_parser_primary_expression
2364 (cp_parser *, bool, bool, bool, cp_id_kind *);
2365static cp_expr cp_parser_id_expression
2366 (cp_parser *, bool, bool, bool *, bool, bool);
2367static cp_expr cp_parser_unqualified_id
2368 (cp_parser *, bool, bool, bool, bool);
2369static tree cp_parser_nested_name_specifier_opt
2370 (cp_parser *, bool, bool, bool, bool, bool = false);
2371static tree cp_parser_nested_name_specifier
2372 (cp_parser *, bool, bool, bool, bool);
2373static tree cp_parser_qualifying_entity
2374 (cp_parser *, bool, bool, bool, bool, bool);
2375static cp_expr cp_parser_postfix_expression
2376 (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
2377static tree cp_parser_postfix_open_square_expression
2378 (cp_parser *, tree, bool, bool);
2379static tree cp_parser_postfix_dot_deref_expression
2380 (cp_parser *, enum cpp_ttype, cp_expr, bool, cp_id_kind *, location_t);
2381static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
2382 (cp_parser *, int, bool, bool, bool *, location_t * = NULL,
2383 bool = false);
2384/* Values for the second parameter of cp_parser_parenthesized_expression_list. */
2385enum { non_attr = 0, normal_attr = 1, id_attr = 2, assume_attr = 3,
2386 uneval_string_attr = 4 };
2387static void cp_parser_pseudo_destructor_name
2388 (cp_parser *, tree, tree *, tree *);
2389static cp_expr cp_parser_unary_expression
2390 (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
2391static enum tree_code cp_parser_unary_operator
2392 (cp_token *);
2393static tree cp_parser_has_attribute_expression
2394 (cp_parser *);
2395static tree cp_parser_new_expression
2396 (cp_parser *);
2397static vec<tree, va_gc> *cp_parser_new_placement
2398 (cp_parser *);
2399static tree cp_parser_new_type_id
2400 (cp_parser *, tree *);
2401static cp_declarator *cp_parser_new_declarator_opt
2402 (cp_parser *);
2403static cp_declarator *cp_parser_direct_new_declarator
2404 (cp_parser *);
2405static vec<tree, va_gc> *cp_parser_new_initializer
2406 (cp_parser *);
2407static tree cp_parser_delete_expression
2408 (cp_parser *);
2409static cp_expr cp_parser_cast_expression
2410 (cp_parser *, bool, bool, bool, cp_id_kind *);
2411static cp_expr cp_parser_binary_expression
2412 (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
2413static tree cp_parser_question_colon_clause
2414 (cp_parser *, cp_expr);
2415static cp_expr cp_parser_conditional_expression (cp_parser *);
2416static cp_expr cp_parser_assignment_expression
2417 (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
2418static enum tree_code cp_parser_assignment_operator_opt
2419 (cp_parser *);
2420static cp_expr cp_parser_expression
2421 (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
2422static cp_expr cp_parser_constant_expression
2423 (cp_parser *, int = 0, bool * = NULL, bool = false);
2424static cp_expr cp_parser_builtin_offsetof
2425 (cp_parser *);
2426static cp_expr cp_parser_lambda_expression
2427 (cp_parser *);
2428static void cp_parser_lambda_introducer
2429 (cp_parser *, tree);
2430static bool cp_parser_lambda_declarator_opt
2431 (cp_parser *, tree);
2432static void cp_parser_lambda_body
2433 (cp_parser *, tree);
2434
2435/* Statements [gram.stmt.stmt] */
2436
2437static void cp_parser_statement
2438 (cp_parser *, tree, bool, bool *, vec<tree> * = NULL, location_t * = NULL);
2439static void cp_parser_label_for_labeled_statement
2440(cp_parser *, tree);
2441static tree cp_parser_expression_statement
2442 (cp_parser *, tree);
2443static tree cp_parser_compound_statement
2444 (cp_parser *, tree, int, bool);
2445static void cp_parser_statement_seq_opt
2446 (cp_parser *, tree);
2447static tree cp_parser_selection_statement
2448 (cp_parser *, bool *, vec<tree> *);
2449static tree cp_parser_condition
2450 (cp_parser *);
2451static tree cp_parser_iteration_statement
2452 (cp_parser *, bool *, bool, tree, bool);
2453static bool cp_parser_init_statement
2454 (cp_parser *, tree *decl);
2455static tree cp_parser_for
2456 (cp_parser *, bool, tree, bool);
2457static tree cp_parser_c_for
2458 (cp_parser *, tree, tree, bool, tree, bool);
2459static tree cp_parser_range_for
2460 (cp_parser *, tree, tree, tree, bool, tree, bool, bool);
2461static void do_range_for_auto_deduction
2462 (tree, tree, cp_decomp *);
2463static tree cp_parser_perform_range_for_lookup
2464 (tree, tree *, tree *);
2465static tree cp_parser_range_for_member_function
2466 (tree, tree);
2467static tree cp_parser_jump_statement
2468 (cp_parser *);
2469static void cp_parser_declaration_statement
2470 (cp_parser *);
2471
2472static tree cp_parser_implicitly_scoped_statement
2473 (cp_parser *, bool *, const token_indent_info &, vec<tree> * = NULL);
2474static void cp_parser_already_scoped_statement
2475 (cp_parser *, bool *, const token_indent_info &);
2476
2477/* State of module-declaration parsing. */
2478enum module_parse
2479{
2480 MP_NOT_MODULE, /* Not a module. */
2481
2482 _MP_UNUSED,
2483
2484 MP_FIRST, /* First declaration of TU. */
2485 MP_GLOBAL, /* Global Module Fragment. */
2486
2487 MP_PURVIEW_IMPORTS, /* Imports of a module. */
2488 MP_PURVIEW, /* Purview of a named module. */
2489
2490 MP_PRIVATE_IMPORTS, /* Imports of a Private Module Fragment. */
2491 MP_PRIVATE, /* Private Module Fragment. */
2492};
2493
2494static module_parse cp_parser_module_declaration
2495 (cp_parser *parser, module_parse, bool exporting);
2496static void cp_parser_import_declaration
2497 (cp_parser *parser, module_parse, bool exporting);
2498
2499/* Declarations [gram.dcl.dcl] */
2500
2501static void cp_parser_declaration_seq_opt
2502 (cp_parser *);
2503static void cp_parser_declaration
2504 (cp_parser *, tree);
2505static void cp_parser_toplevel_declaration
2506 (cp_parser *);
2507static void cp_parser_block_declaration
2508 (cp_parser *, bool);
2509static void cp_parser_simple_declaration
2510 (cp_parser *, bool, tree *);
2511static void cp_parser_decl_specifier_seq
2512 (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, int *);
2513static tree cp_parser_storage_class_specifier_opt
2514 (cp_parser *);
2515static tree cp_parser_function_specifier_opt
2516 (cp_parser *, cp_decl_specifier_seq *);
2517static tree cp_parser_type_specifier
2518 (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, bool,
2519 int *, bool *);
2520static tree cp_parser_simple_type_specifier
2521 (cp_parser *, cp_decl_specifier_seq *, cp_parser_flags);
2522static tree cp_parser_placeholder_type_specifier
2523 (cp_parser *, location_t, tree, bool);
2524static tree cp_parser_type_name
2525 (cp_parser *, bool);
2526static tree cp_parser_nonclass_name
2527 (cp_parser* parser);
2528static tree cp_parser_elaborated_type_specifier
2529 (cp_parser *, bool, bool);
2530static tree cp_parser_enum_specifier
2531 (cp_parser *);
2532static void cp_parser_enumerator_list
2533 (cp_parser *, tree);
2534static void cp_parser_enumerator_definition
2535 (cp_parser *, tree);
2536static tree cp_parser_namespace_name
2537 (cp_parser *);
2538static void cp_parser_namespace_definition
2539 (cp_parser *);
2540static void cp_parser_namespace_body
2541 (cp_parser *);
2542static tree cp_parser_qualified_namespace_specifier
2543 (cp_parser *);
2544static void cp_parser_namespace_alias_definition
2545 (cp_parser *);
2546static bool cp_parser_using_declaration
2547 (cp_parser *, bool);
2548static void cp_parser_using_directive
2549 (cp_parser *);
2550static void cp_parser_using_enum
2551 (cp_parser *);
2552static tree cp_parser_alias_declaration
2553 (cp_parser *);
2554static void cp_parser_asm_definition
2555 (cp_parser *);
2556static void cp_parser_linkage_specification
2557 (cp_parser *, tree);
2558static void cp_parser_static_assert
2559 (cp_parser *, bool);
2560static tree cp_parser_decltype
2561 (cp_parser *);
2562static tree cp_parser_decomposition_declaration
2563 (cp_parser *, cp_decl_specifier_seq *, tree *, location_t *);
2564
2565/* Declarators [gram.dcl.decl] */
2566
2567static tree cp_parser_init_declarator
2568 (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *,
2569 vec<deferred_access_check, va_gc> *, bool, bool, int, bool *, tree *,
2570 location_t *, tree *);
2571static cp_declarator *cp_parser_declarator
2572 (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *,
2573 bool, bool, bool);
2574static cp_declarator *cp_parser_direct_declarator
2575 (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool,
2576 bool);
2577static enum tree_code cp_parser_ptr_operator
2578 (cp_parser *, tree *, cp_cv_quals *, tree *);
2579static cp_cv_quals cp_parser_cv_qualifier_seq_opt
2580 (cp_parser *);
2581static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
2582 (cp_parser *);
2583static cp_ref_qualifier cp_parser_ref_qualifier_opt
2584 (cp_parser *);
2585static tree cp_parser_tx_qualifier_opt
2586 (cp_parser *);
2587static tree cp_parser_late_return_type_opt
2588 (cp_parser *, cp_declarator *, tree &);
2589static tree cp_parser_declarator_id
2590 (cp_parser *, bool);
2591static tree cp_parser_type_id
2592 (cp_parser *, cp_parser_flags = CP_PARSER_FLAGS_NONE, location_t * = NULL);
2593static tree cp_parser_template_type_arg
2594 (cp_parser *);
2595static tree cp_parser_trailing_type_id (cp_parser *);
2596static tree cp_parser_type_id_1
2597 (cp_parser *, cp_parser_flags, bool, bool, location_t *);
2598static void cp_parser_type_specifier_seq
2599 (cp_parser *, cp_parser_flags, bool, bool, cp_decl_specifier_seq *);
2600static tree cp_parser_parameter_declaration_clause
2601 (cp_parser *, cp_parser_flags);
2602static tree cp_parser_parameter_declaration_list
2603 (cp_parser *, cp_parser_flags, auto_vec<tree> *);
2604static cp_parameter_declarator *cp_parser_parameter_declaration
2605 (cp_parser *, cp_parser_flags, bool, bool *);
2606static tree cp_parser_default_argument
2607 (cp_parser *, bool);
2608static void cp_parser_function_body
2609 (cp_parser *, bool);
2610static tree cp_parser_initializer
2611 (cp_parser *, bool * = nullptr, bool * = nullptr, bool = false);
2612static cp_expr cp_parser_initializer_clause
2613 (cp_parser *, bool * = nullptr);
2614static cp_expr cp_parser_braced_list
2615 (cp_parser*, bool * = nullptr);
2616static vec<constructor_elt, va_gc> *cp_parser_initializer_list
2617 (cp_parser *, bool *, bool *);
2618
2619static void cp_parser_ctor_initializer_opt_and_function_body
2620 (cp_parser *, bool);
2621
2622static tree cp_parser_late_parsing_omp_declare_simd
2623 (cp_parser *, tree);
2624
2625static tree cp_parser_late_parsing_oacc_routine
2626 (cp_parser *, tree);
2627
2628static tree synthesize_implicit_template_parm
2629 (cp_parser *, tree);
2630static tree finish_fully_implicit_template
2631 (cp_parser *, tree);
2632static void abort_fully_implicit_template
2633 (cp_parser *);
2634
2635/* Classes [gram.class] */
2636
2637static tree cp_parser_class_name
2638 (cp_parser *, bool, bool, enum tag_types, bool, bool, bool, bool = false);
2639static tree cp_parser_class_specifier
2640 (cp_parser *);
2641static tree cp_parser_class_head
2642 (cp_parser *, bool *);
2643static enum tag_types cp_parser_class_key
2644 (cp_parser *);
2645static void cp_parser_type_parameter_key
2646 (cp_parser* parser);
2647static void cp_parser_member_specification_opt
2648 (cp_parser *);
2649static void cp_parser_member_declaration
2650 (cp_parser *);
2651static tree cp_parser_pure_specifier
2652 (cp_parser *);
2653static tree cp_parser_constant_initializer
2654 (cp_parser *);
2655
2656/* Derived classes [gram.class.derived] */
2657
2658static tree cp_parser_base_clause
2659 (cp_parser *);
2660static tree cp_parser_base_specifier
2661 (cp_parser *);
2662
2663/* Special member functions [gram.special] */
2664
2665static tree cp_parser_conversion_function_id
2666 (cp_parser *);
2667static tree cp_parser_conversion_type_id
2668 (cp_parser *);
2669static cp_declarator *cp_parser_conversion_declarator_opt
2670 (cp_parser *);
2671static void cp_parser_ctor_initializer_opt
2672 (cp_parser *);
2673static void cp_parser_mem_initializer_list
2674 (cp_parser *);
2675static tree cp_parser_mem_initializer
2676 (cp_parser *);
2677static tree cp_parser_mem_initializer_id
2678 (cp_parser *);
2679
2680/* Overloading [gram.over] */
2681
2682static cp_expr cp_parser_operator_function_id
2683 (cp_parser *);
2684static cp_expr cp_parser_operator
2685 (cp_parser *, location_t);
2686
2687/* Templates [gram.temp] */
2688
2689static void cp_parser_template_declaration
2690 (cp_parser *, bool);
2691static tree cp_parser_template_parameter_list
2692 (cp_parser *);
2693static tree cp_parser_template_parameter
2694 (cp_parser *, bool *, bool *);
2695static tree cp_parser_type_parameter
2696 (cp_parser *, bool *);
2697static tree cp_parser_template_id
2698 (cp_parser *, bool, bool, enum tag_types, bool);
2699static tree cp_parser_template_id_expr
2700 (cp_parser *, bool, bool, bool);
2701static tree cp_parser_template_name
2702 (cp_parser *, bool, bool, bool, enum tag_types, bool *);
2703static tree cp_parser_template_argument_list
2704 (cp_parser *);
2705static tree cp_parser_template_argument
2706 (cp_parser *);
2707static void cp_parser_explicit_instantiation
2708 (cp_parser *);
2709static void cp_parser_explicit_specialization
2710 (cp_parser *);
2711
2712/* Exception handling [gram.except] */
2713
2714static tree cp_parser_try_block
2715 (cp_parser *);
2716static void cp_parser_function_try_block
2717 (cp_parser *);
2718static void cp_parser_handler_seq
2719 (cp_parser *);
2720static void cp_parser_handler
2721 (cp_parser *);
2722static tree cp_parser_exception_declaration
2723 (cp_parser *);
2724static tree cp_parser_throw_expression
2725 (cp_parser *);
2726static tree cp_parser_exception_specification_opt
2727 (cp_parser *, cp_parser_flags);
2728static tree cp_parser_type_id_list
2729 (cp_parser *);
2730static tree cp_parser_noexcept_specification_opt
2731 (cp_parser *, cp_parser_flags, bool, bool *, bool);
2732
2733/* GNU Extensions */
2734
2735static tree cp_parser_asm_specification_opt
2736 (cp_parser *);
2737static tree cp_parser_asm_operand_list
2738 (cp_parser *);
2739static tree cp_parser_asm_clobber_list
2740 (cp_parser *);
2741static tree cp_parser_asm_label_list
2742 (cp_parser *);
2743static bool cp_next_tokens_can_be_attribute_p
2744 (cp_parser *);
2745static bool cp_next_tokens_can_be_gnu_attribute_p
2746 (cp_parser *);
2747static bool cp_next_tokens_can_be_std_attribute_p
2748 (cp_parser *);
2749static bool cp_nth_tokens_can_be_std_attribute_p
2750 (cp_parser *, size_t);
2751static bool cp_nth_tokens_can_be_gnu_attribute_p
2752 (cp_parser *, size_t);
2753static bool cp_nth_tokens_can_be_attribute_p
2754 (cp_parser *, size_t);
2755static tree cp_parser_attributes_opt
2756 (cp_parser *);
2757static tree cp_parser_gnu_attributes_opt
2758 (cp_parser *);
2759static tree cp_parser_gnu_attribute_list
2760 (cp_parser *, bool = false);
2761static tree cp_parser_std_attribute
2762 (cp_parser *, tree);
2763static tree cp_parser_std_attribute_spec
2764 (cp_parser *);
2765static tree cp_parser_std_attribute_spec_seq
2766 (cp_parser *);
2767static size_t cp_parser_skip_std_attribute_spec_seq
2768 (cp_parser *, size_t);
2769static size_t cp_parser_skip_attributes_opt
2770 (cp_parser *, size_t);
2771static bool cp_parser_extension_opt
2772 (cp_parser *, int *);
2773static void cp_parser_label_declaration
2774 (cp_parser *);
2775
2776/* Concept Extensions */
2777
2778static tree cp_parser_concept_definition
2779 (cp_parser *);
2780static tree cp_parser_constraint_expression
2781 (cp_parser *);
2782static tree cp_parser_requires_clause_opt
2783 (cp_parser *, bool);
2784static tree cp_parser_requires_expression
2785 (cp_parser *);
2786static tree cp_parser_requirement_parameter_list
2787 (cp_parser *);
2788static tree cp_parser_requirement_body
2789 (cp_parser *);
2790static tree cp_parser_requirement_seq
2791 (cp_parser *);
2792static tree cp_parser_requirement
2793 (cp_parser *);
2794static tree cp_parser_simple_requirement
2795 (cp_parser *);
2796static tree cp_parser_compound_requirement
2797 (cp_parser *);
2798static tree cp_parser_type_requirement
2799 (cp_parser *);
2800static tree cp_parser_nested_requirement
2801 (cp_parser *);
2802
2803/* Transactional Memory Extensions */
2804
2805static tree cp_parser_transaction
2806 (cp_parser *, cp_token *);
2807static tree cp_parser_transaction_expression
2808 (cp_parser *, enum rid);
2809static void cp_parser_function_transaction
2810 (cp_parser *, enum rid);
2811static tree cp_parser_transaction_cancel
2812 (cp_parser *);
2813
2814/* Coroutine extensions. */
2815
2816static tree cp_parser_yield_expression
2817 (cp_parser *);
2818
2819/* Contracts */
2820
2821static void cp_parser_late_contract_condition
2822 (cp_parser *, tree, tree);
2823
2824enum pragma_context {
2825 pragma_external,
2826 pragma_member,
2827 pragma_objc_icode,
2828 pragma_stmt,
2829 pragma_compound
2830};
2831static bool cp_parser_pragma
2832 (cp_parser *, enum pragma_context, bool *);
2833
2834/* Objective-C++ Productions */
2835
2836static tree cp_parser_objc_message_receiver
2837 (cp_parser *);
2838static tree cp_parser_objc_message_args
2839 (cp_parser *);
2840static tree cp_parser_objc_message_expression
2841 (cp_parser *);
2842static cp_expr cp_parser_objc_encode_expression
2843 (cp_parser *);
2844static tree cp_parser_objc_defs_expression
2845 (cp_parser *);
2846static tree cp_parser_objc_protocol_expression
2847 (cp_parser *);
2848static tree cp_parser_objc_selector_expression
2849 (cp_parser *);
2850static cp_expr cp_parser_objc_expression
2851 (cp_parser *);
2852static bool cp_parser_objc_selector_p
2853 (enum cpp_ttype);
2854static tree cp_parser_objc_selector
2855 (cp_parser *);
2856static tree cp_parser_objc_protocol_refs_opt
2857 (cp_parser *);
2858static void cp_parser_objc_declaration
2859 (cp_parser *, tree);
2860static tree cp_parser_objc_statement
2861 (cp_parser *);
2862static bool cp_parser_objc_valid_prefix_attributes
2863 (cp_parser *, tree *);
2864static void cp_parser_objc_at_property_declaration
2865 (cp_parser *) ;
2866static void cp_parser_objc_at_synthesize_declaration
2867 (cp_parser *) ;
2868static void cp_parser_objc_at_dynamic_declaration
2869 (cp_parser *) ;
2870static tree cp_parser_objc_struct_declaration
2871 (cp_parser *) ;
2872
2873/* Utility Routines */
2874
2875static cp_expr cp_parser_lookup_name
2876 (cp_parser *, tree, enum tag_types, int, bool, bool, tree *, location_t);
2877static tree cp_parser_lookup_name_simple
2878 (cp_parser *, tree, location_t);
2879static tree cp_parser_maybe_treat_template_as_class
2880 (tree, bool);
2881static bool cp_parser_check_declarator_template_parameters
2882 (cp_parser *, cp_declarator *, location_t);
2883static bool cp_parser_check_template_parameters
2884 (cp_parser *, unsigned, bool, location_t, cp_declarator *);
2885static cp_expr cp_parser_simple_cast_expression
2886 (cp_parser *);
2887static tree cp_parser_global_scope_opt
2888 (cp_parser *, bool);
2889static bool cp_parser_constructor_declarator_p
2890 (cp_parser *, cp_parser_flags, bool);
2891static tree cp_parser_function_definition_from_specifiers_and_declarator
2892 (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *);
2893static tree cp_parser_function_definition_after_declarator
2894 (cp_parser *, bool);
2895static bool cp_parser_template_declaration_after_export
2896 (cp_parser *, bool);
2897static void cp_parser_perform_template_parameter_access_checks
2898 (vec<deferred_access_check, va_gc> *);
2899static tree cp_parser_single_declaration
2900 (cp_parser *, vec<deferred_access_check, va_gc> *, bool, bool, bool *);
2901static cp_expr cp_parser_functional_cast
2902 (cp_parser *, tree);
2903static tree cp_parser_save_member_function_body
2904 (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree);
2905static tree cp_parser_save_nsdmi
2906 (cp_parser *);
2907static tree cp_parser_enclosed_template_argument_list
2908 (cp_parser *);
2909static void cp_parser_save_default_args
2910 (cp_parser *, tree);
2911static void cp_parser_late_parsing_for_member
2912 (cp_parser *, tree);
2913static tree cp_parser_late_parse_one_default_arg
2914 (cp_parser *, tree, tree, tree);
2915static void cp_parser_late_parsing_nsdmi
2916 (cp_parser *, tree);
2917static void cp_parser_late_parsing_default_args
2918 (cp_parser *, tree);
2919static tree cp_parser_sizeof_operand
2920 (cp_parser *, enum rid);
2921static cp_expr cp_parser_trait
2922 (cp_parser *, const cp_trait *);
2923static bool cp_parser_declares_only_class_p
2924 (cp_parser *);
2925static void cp_parser_set_storage_class
2926 (cp_parser *, cp_decl_specifier_seq *, enum rid, cp_token *);
2927static void cp_parser_set_decl_spec_type
2928 (cp_decl_specifier_seq *, tree, cp_token *, bool);
2929static void set_and_check_decl_spec_loc
2930 (cp_decl_specifier_seq *decl_specs,
2931 cp_decl_spec ds, cp_token *);
2932static bool cp_parser_friend_p
2933 (const cp_decl_specifier_seq *);
2934static void cp_parser_required_error
2935 (cp_parser *, required_token, bool, location_t);
2936static cp_token *cp_parser_require
2937 (cp_parser *, enum cpp_ttype, required_token, location_t = UNKNOWN_LOCATION);
2938static cp_token *cp_parser_require_keyword
2939 (cp_parser *, enum rid, required_token);
2940static bool cp_parser_token_starts_function_definition_p
2941 (cp_token *);
2942static bool cp_parser_next_token_starts_class_definition_p
2943 (cp_parser *);
2944static bool cp_parser_next_token_ends_template_argument_p
2945 (cp_parser *);
2946static bool cp_parser_nth_token_starts_template_argument_list_p
2947 (cp_parser *, size_t);
2948static enum tag_types cp_parser_token_is_class_key
2949 (cp_token *);
2950static enum tag_types cp_parser_token_is_type_parameter_key
2951 (cp_token *);
2952static void cp_parser_maybe_warn_enum_key (cp_parser *, location_t, tree, rid);
2953static void cp_parser_check_class_key
2954(cp_parser *, location_t, enum tag_types, tree type, bool, bool);
2955static void cp_parser_check_access_in_redeclaration
2956 (tree type, location_t location);
2957static bool cp_parser_optional_template_keyword
2958 (cp_parser *);
2959static void cp_parser_pre_parsed_nested_name_specifier
2960 (cp_parser *);
2961static bool cp_parser_cache_group
2962 (cp_parser *, enum cpp_ttype, unsigned);
2963static tree cp_parser_cache_defarg
2964 (cp_parser *parser, bool nsdmi);
2965static void cp_parser_parse_tentatively
2966 (cp_parser *);
2967static void cp_parser_commit_to_tentative_parse
2968 (cp_parser *);
2969static void cp_parser_commit_to_topmost_tentative_parse
2970 (cp_parser *);
2971static void cp_parser_abort_tentative_parse
2972 (cp_parser *);
2973static bool cp_parser_parse_definitely
2974 (cp_parser *);
2975static inline bool cp_parser_parsing_tentatively
2976 (cp_parser *);
2977static bool cp_parser_uncommitted_to_tentative_parse_p
2978 (cp_parser *);
2979static void cp_parser_error
2980 (cp_parser *, const char *);
2981static void cp_parser_name_lookup_error
2982 (cp_parser *, tree, tree, name_lookup_error, location_t);
2983static bool cp_parser_simulate_error
2984 (cp_parser *);
2985static bool cp_parser_check_type_definition
2986 (cp_parser *);
2987static void cp_parser_check_for_definition_in_return_type
2988 (cp_declarator *, tree, location_t type_location);
2989static void cp_parser_check_for_invalid_template_id
2990 (cp_parser *, tree, enum tag_types, location_t location);
2991static bool cp_parser_non_integral_constant_expression
2992 (cp_parser *, non_integral_constant);
2993static void cp_parser_diagnose_invalid_type_name
2994 (cp_parser *, tree, location_t);
2995static bool cp_parser_parse_and_diagnose_invalid_type_name
2996 (cp_parser *);
2997static int cp_parser_skip_to_closing_parenthesis
2998 (cp_parser *, bool, bool, bool);
2999static void cp_parser_skip_to_end_of_statement
3000 (cp_parser *);
3001static void cp_parser_consume_semicolon_at_end_of_statement
3002 (cp_parser *);
3003static void cp_parser_skip_to_end_of_block_or_statement
3004 (cp_parser *);
3005static bool cp_parser_skip_to_closing_brace
3006 (cp_parser *);
3007static bool cp_parser_skip_entire_template_parameter_list
3008 (cp_parser *);
3009static void cp_parser_require_end_of_template_parameter_list
3010 (cp_parser *);
3011static bool cp_parser_skip_to_end_of_template_parameter_list
3012 (cp_parser *);
3013static void cp_parser_skip_to_pragma_eol
3014 (cp_parser*, cp_token *);
3015static bool cp_parser_error_occurred
3016 (cp_parser *);
3017static bool cp_parser_allow_gnu_extensions_p
3018 (cp_parser *);
3019static bool cp_parser_is_pure_string_literal
3020 (cp_token *);
3021static bool cp_parser_is_string_literal
3022 (cp_token *);
3023static bool cp_parser_is_keyword
3024 (cp_token *, enum rid);
3025static tree cp_parser_make_typename_type
3026 (cp_parser *, tree, location_t location);
3027static cp_declarator * cp_parser_make_indirect_declarator
3028 (enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
3029static bool cp_parser_compound_literal_p
3030 (cp_parser *);
3031static bool cp_parser_array_designator_p
3032 (cp_parser *);
3033static bool cp_parser_init_statement_p
3034 (cp_parser *);
3035static bool cp_parser_skip_up_to_closing_square_bracket
3036 (cp_parser *);
3037static bool cp_parser_skip_to_closing_square_bracket
3038 (cp_parser *);
3039static size_t cp_parser_skip_balanced_tokens (cp_parser *, size_t);
3040static tree cp_parser_omp_loop_nest (cp_parser *, bool *);
3041
3042// -------------------------------------------------------------------------- //
3043// Unevaluated Operand Guard
3044//
3045// Implementation of an RAII helper for unevaluated operand parsing.
3046cp_unevaluated::cp_unevaluated ()
3047{
3048 ++cp_unevaluated_operand;
3049 ++c_inhibit_evaluation_warnings;
3050}
3051
3052cp_unevaluated::~cp_unevaluated ()
3053{
3054 --c_inhibit_evaluation_warnings;
3055 --cp_unevaluated_operand;
3056}
3057
3058// -------------------------------------------------------------------------- //
3059// Tentative Parsing
3060
3061/* Returns nonzero if we are parsing tentatively. */
3062
3063static inline bool
3064cp_parser_parsing_tentatively (cp_parser* parser)
3065{
3066 return parser->context->next != NULL;
3067}
3068
3069/* Returns nonzero if TOKEN is a string literal. */
3070
3071static bool
3072cp_parser_is_pure_string_literal (cp_token* token)
3073{
3074 return (token->type == CPP_STRING ||
3075 token->type == CPP_STRING16 ||
3076 token->type == CPP_STRING32 ||
3077 token->type == CPP_WSTRING ||
3078 token->type == CPP_UTF8STRING);
3079}
3080
3081/* Returns nonzero if TOKEN is a string literal
3082 of a user-defined string literal. */
3083
3084static bool
3085cp_parser_is_string_literal (cp_token* token)
3086{
3087 return (cp_parser_is_pure_string_literal (token) ||
3088 token->type == CPP_STRING_USERDEF ||
3089 token->type == CPP_STRING16_USERDEF ||
3090 token->type == CPP_STRING32_USERDEF ||
3091 token->type == CPP_WSTRING_USERDEF ||
3092 token->type == CPP_UTF8STRING_USERDEF);
3093}
3094
3095/* Returns nonzero if TOKEN is the indicated KEYWORD. */
3096
3097static bool
3098cp_parser_is_keyword (cp_token* token, enum rid keyword)
3099{
3100 return token->keyword == keyword;
3101}
3102
3103/* Helper function for cp_parser_error.
3104 Having peeked a token of kind TOK1_KIND that might signify
3105 a conflict marker, peek successor tokens to determine
3106 if we actually do have a conflict marker.
3107 Specifically, we consider a run of 7 '<', '=' or '>' characters
3108 at the start of a line as a conflict marker.
3109 These come through the lexer as three pairs and a single,
3110 e.g. three CPP_LSHIFT tokens ("<<") and a CPP_LESS token ('<').
3111 If it returns true, *OUT_LOC is written to with the location/range
3112 of the marker. */
3113
3114static bool
3115cp_lexer_peek_conflict_marker (cp_lexer *lexer, enum cpp_ttype tok1_kind,
3116 location_t *out_loc)
3117{
3118 cp_token *token2 = cp_lexer_peek_nth_token (lexer, n: 2);
3119 if (token2->type != tok1_kind)
3120 return false;
3121 cp_token *token3 = cp_lexer_peek_nth_token (lexer, n: 3);
3122 if (token3->type != tok1_kind)
3123 return false;
3124 cp_token *token4 = cp_lexer_peek_nth_token (lexer, n: 4);
3125 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
3126 return false;
3127
3128 /* It must be at the start of the line. */
3129 location_t start_loc = cp_lexer_peek_token (lexer)->location;
3130 if (LOCATION_COLUMN (start_loc) != 1)
3131 return false;
3132
3133 /* We have a conflict marker. Construct a location of the form:
3134 <<<<<<<
3135 ^~~~~~~
3136 with start == caret, finishing at the end of the marker. */
3137 location_t finish_loc = get_finish (loc: token4->location);
3138 *out_loc = make_location (caret: start_loc, start: start_loc, finish: finish_loc);
3139
3140 return true;
3141}
3142
3143/* Get a description of the matching symbol to TOKEN_DESC e.g. "(" for
3144 RT_CLOSE_PAREN. */
3145
3146static const char *
3147get_matching_symbol (required_token token_desc)
3148{
3149 switch (token_desc)
3150 {
3151 default:
3152 gcc_unreachable ();
3153 return "";
3154 case RT_CLOSE_BRACE:
3155 return "{";
3156 case RT_CLOSE_PAREN:
3157 return "(";
3158 }
3159}
3160
3161/* Attempt to convert TOKEN_DESC from a required_token to an
3162 enum cpp_ttype, returning CPP_EOF if there is no good conversion. */
3163
3164static enum cpp_ttype
3165get_required_cpp_ttype (required_token token_desc)
3166{
3167 switch (token_desc)
3168 {
3169 case RT_SEMICOLON:
3170 return CPP_SEMICOLON;
3171 case RT_OPEN_PAREN:
3172 return CPP_OPEN_PAREN;
3173 case RT_CLOSE_BRACE:
3174 return CPP_CLOSE_BRACE;
3175 case RT_OPEN_BRACE:
3176 return CPP_OPEN_BRACE;
3177 case RT_CLOSE_SQUARE:
3178 return CPP_CLOSE_SQUARE;
3179 case RT_OPEN_SQUARE:
3180 return CPP_OPEN_SQUARE;
3181 case RT_COMMA:
3182 return CPP_COMMA;
3183 case RT_COLON:
3184 return CPP_COLON;
3185 case RT_CLOSE_PAREN:
3186 return CPP_CLOSE_PAREN;
3187
3188 default:
3189 /* Use CPP_EOF as a "no completions possible" code. */
3190 return CPP_EOF;
3191 }
3192}
3193
3194
3195/* Subroutine of cp_parser_error and cp_parser_required_error.
3196
3197 Issue a diagnostic of the form
3198 FILE:LINE: MESSAGE before TOKEN
3199 where TOKEN is the next token in the input stream. MESSAGE
3200 (specified by the caller) is usually of the form "expected
3201 OTHER-TOKEN".
3202
3203 This bypasses the check for tentative passing, and potentially
3204 adds material needed by cp_parser_required_error.
3205
3206 If MISSING_TOKEN_DESC is not RT_NONE, then potentially add fix-it hints
3207 suggesting insertion of the missing token.
3208
3209 Additionally, if MATCHING_LOCATION is not UNKNOWN_LOCATION, then we
3210 have an unmatched symbol at MATCHING_LOCATION; highlight this secondary
3211 location. */
3212
3213static void
3214cp_parser_error_1 (cp_parser* parser, const char* gmsgid,
3215 required_token missing_token_desc,
3216 location_t matching_location)
3217{
3218 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
3219 /* This diagnostic makes more sense if it is tagged to the line
3220 of the token we just peeked at. */
3221 cp_lexer_set_source_position_from_token (token);
3222
3223 if (token->type == CPP_PRAGMA)
3224 {
3225 error_at (token->location,
3226 "%<#pragma%> is not allowed here");
3227 cp_parser_skip_to_pragma_eol (parser, token);
3228 return;
3229 }
3230
3231 /* If this is actually a conflict marker, report it as such. */
3232 if (token->type == CPP_LSHIFT
3233 || token->type == CPP_RSHIFT
3234 || token->type == CPP_EQ_EQ)
3235 {
3236 location_t loc;
3237 if (cp_lexer_peek_conflict_marker (lexer: parser->lexer, tok1_kind: token->type, out_loc: &loc))
3238 {
3239 error_at (loc, "version control conflict marker in file");
3240 expanded_location token_exploc = expand_location (token->location);
3241 /* Consume tokens until the end of the source line. */
3242 for (;;)
3243 {
3244 cp_lexer_consume_token (lexer: parser->lexer);
3245 cp_token *next = cp_lexer_peek_token (lexer: parser->lexer);
3246 if (next->type == CPP_EOF)
3247 break;
3248 if (next->location == UNKNOWN_LOCATION
3249 || loc == UNKNOWN_LOCATION)
3250 break;
3251
3252 expanded_location next_exploc = expand_location (next->location);
3253 if (next_exploc.file != token_exploc.file)
3254 break;
3255 if (next_exploc.line != token_exploc.line)
3256 break;
3257 }
3258 return;
3259 }
3260 }
3261
3262 auto_diagnostic_group d;
3263 gcc_rich_location richloc (input_location);
3264
3265 bool added_matching_location = false;
3266
3267 if (missing_token_desc != RT_NONE)
3268 if (cp_token *prev_token = cp_lexer_safe_previous_token (lexer: parser->lexer))
3269 {
3270 /* Potentially supply a fix-it hint, suggesting to add the
3271 missing token immediately after the *previous* token.
3272 This may move the primary location within richloc. */
3273 enum cpp_ttype ttype = get_required_cpp_ttype (token_desc: missing_token_desc);
3274 location_t prev_token_loc = prev_token->location;
3275 maybe_suggest_missing_token_insertion (richloc: &richloc, token_type: ttype,
3276 prev_token_loc);
3277
3278 /* If matching_location != UNKNOWN_LOCATION, highlight it.
3279 Attempt to consolidate diagnostics by printing it as a
3280 secondary range within the main diagnostic. */
3281 if (matching_location != UNKNOWN_LOCATION)
3282 added_matching_location
3283 = richloc.add_location_if_nearby (loc: matching_location);
3284 }
3285
3286 /* If we were parsing a string-literal and there is an unknown name
3287 token right after, then check to see if that could also have been
3288 a literal string by checking the name against a list of known
3289 standard string literal constants defined in header files. If
3290 there is one, then add that as an hint to the error message. */
3291 name_hint h;
3292 if (token->type == CPP_NAME)
3293 if (cp_token *prev_token = cp_lexer_safe_previous_token (lexer: parser->lexer))
3294 if (cp_parser_is_string_literal (token: prev_token))
3295 {
3296 tree name = token->u.value;
3297 const char *token_name = IDENTIFIER_POINTER (name);
3298 const char *header_hint
3299 = get_cp_stdlib_header_for_string_macro_name (n: token_name);
3300 if (header_hint != NULL)
3301 h = name_hint (NULL, new suggest_missing_header (token->location,
3302 token_name,
3303 header_hint));
3304 }
3305
3306 /* Actually emit the error. */
3307 c_parse_error (gmsgid,
3308 /* Because c_parser_error does not understand
3309 CPP_KEYWORD, keywords are treated like
3310 identifiers. */
3311 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
3312 token->u.value, token->flags, richloc: &richloc);
3313
3314 if (missing_token_desc != RT_NONE)
3315 {
3316 /* If we weren't able to consolidate matching_location, then
3317 print it as a secondary diagnostic. */
3318 if (matching_location != UNKNOWN_LOCATION
3319 && !added_matching_location)
3320 inform (matching_location, "to match this %qs",
3321 get_matching_symbol (token_desc: missing_token_desc));
3322 }
3323}
3324
3325/* If not parsing tentatively, issue a diagnostic of the form
3326 FILE:LINE: MESSAGE before TOKEN
3327 where TOKEN is the next token in the input stream. MESSAGE
3328 (specified by the caller) is usually of the form "expected
3329 OTHER-TOKEN". */
3330
3331static void
3332cp_parser_error (cp_parser* parser, const char* gmsgid)
3333{
3334 if (!cp_parser_simulate_error (parser))
3335 cp_parser_error_1 (parser, gmsgid, missing_token_desc: RT_NONE, UNKNOWN_LOCATION);
3336}
3337
3338/* Issue an error about name-lookup failing. NAME is the
3339 IDENTIFIER_NODE DECL is the result of
3340 the lookup (as returned from cp_parser_lookup_name). DESIRED is
3341 the thing that we hoped to find. */
3342
3343static void
3344cp_parser_name_lookup_error (cp_parser* parser,
3345 tree name,
3346 tree decl,
3347 name_lookup_error desired,
3348 location_t location)
3349{
3350 /* If name lookup completely failed, tell the user that NAME was not
3351 declared. */
3352 if (decl == error_mark_node)
3353 {
3354 if (parser->scope && parser->scope != global_namespace)
3355 error_at (location, "%<%E::%E%> has not been declared",
3356 parser->scope, name);
3357 else if (parser->scope == global_namespace)
3358 error_at (location, "%<::%E%> has not been declared", name);
3359 else if (parser->object_scope
3360 && !CLASS_TYPE_P (parser->object_scope))
3361 error_at (location, "request for member %qE in non-class type %qT",
3362 name, parser->object_scope);
3363 else if (parser->object_scope)
3364 error_at (location, "%<%T::%E%> has not been declared",
3365 parser->object_scope, name);
3366 else
3367 error_at (location, "%qE has not been declared", name);
3368 }
3369 else if (parser->scope && parser->scope != global_namespace)
3370 {
3371 switch (desired)
3372 {
3373 case NLE_TYPE:
3374 error_at (location, "%<%E::%E%> is not a type",
3375 parser->scope, name);
3376 break;
3377 case NLE_CXX98:
3378 error_at (location, "%<%E::%E%> is not a class or namespace",
3379 parser->scope, name);
3380 break;
3381 case NLE_NOT_CXX98:
3382 error_at (location,
3383 "%<%E::%E%> is not a class, namespace, or enumeration",
3384 parser->scope, name);
3385 break;
3386 default:
3387 gcc_unreachable ();
3388
3389 }
3390 }
3391 else if (parser->scope == global_namespace)
3392 {
3393 switch (desired)
3394 {
3395 case NLE_TYPE:
3396 error_at (location, "%<::%E%> is not a type", name);
3397 break;
3398 case NLE_CXX98:
3399 error_at (location, "%<::%E%> is not a class or namespace", name);
3400 break;
3401 case NLE_NOT_CXX98:
3402 error_at (location,
3403 "%<::%E%> is not a class, namespace, or enumeration",
3404 name);
3405 break;
3406 default:
3407 gcc_unreachable ();
3408 }
3409 }
3410 else
3411 {
3412 switch (desired)
3413 {
3414 case NLE_TYPE:
3415 error_at (location, "%qE is not a type", name);
3416 break;
3417 case NLE_CXX98:
3418 error_at (location, "%qE is not a class or namespace", name);
3419 break;
3420 case NLE_NOT_CXX98:
3421 error_at (location,
3422 "%qE is not a class, namespace, or enumeration", name);
3423 break;
3424 default:
3425 gcc_unreachable ();
3426 }
3427 }
3428}
3429
3430/* If we are parsing tentatively, remember that an error has occurred
3431 during this tentative parse. Returns true if the error was
3432 simulated; false if a message should be issued by the caller. */
3433
3434static bool
3435cp_parser_simulate_error (cp_parser* parser)
3436{
3437 if (cp_parser_uncommitted_to_tentative_parse_p (parser))
3438 {
3439 parser->context->status = CP_PARSER_STATUS_KIND_ERROR;
3440 return true;
3441 }
3442 return false;
3443}
3444
3445/* This function is called when a type is defined. If type
3446 definitions are forbidden at this point, an error message is
3447 issued. */
3448
3449static bool
3450cp_parser_check_type_definition (cp_parser* parser)
3451{
3452 /* If types are forbidden here, issue a message. */
3453 if (parser->type_definition_forbidden_message)
3454 {
3455 /* Don't use `%s' to print the string, because quotations (`%<', `%>')
3456 or %qs in the message need to be interpreted. */
3457 error (parser->type_definition_forbidden_message,
3458 parser->type_definition_forbidden_message_arg);
3459 return false;
3460 }
3461 return true;
3462}
3463
3464/* This function is called when the DECLARATOR is processed. The TYPE
3465 was a type defined in the decl-specifiers. If it is invalid to
3466 define a type in the decl-specifiers for DECLARATOR, an error is
3467 issued. TYPE_LOCATION is the location of TYPE and is used
3468 for error reporting. */
3469
3470static void
3471cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
3472 tree type, location_t type_location)
3473{
3474 /* [dcl.fct] forbids type definitions in return types.
3475 Unfortunately, it's not easy to know whether or not we are
3476 processing a return type until after the fact. */
3477 while (declarator
3478 && (declarator->kind == cdk_pointer
3479 || declarator->kind == cdk_reference
3480 || declarator->kind == cdk_ptrmem))
3481 declarator = declarator->declarator;
3482 if (declarator
3483 && declarator->kind == cdk_function)
3484 {
3485 error_at (type_location,
3486 "new types may not be defined in a return type");
3487 inform (type_location,
3488 "(perhaps a semicolon is missing after the definition of %qT)",
3489 type);
3490 }
3491}
3492
3493/* A type-specifier (TYPE) has been parsed which cannot be followed by
3494 "<" in any valid C++ program. If the next token is indeed "<",
3495 issue a message warning the user about what appears to be an
3496 invalid attempt to form a template-id. LOCATION is the location
3497 of the type-specifier (TYPE) */
3498
3499static void
3500cp_parser_check_for_invalid_template_id (cp_parser* parser,
3501 tree type,
3502 enum tag_types tag_type,
3503 location_t location)
3504{
3505 cp_token_position start = 0;
3506
3507 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_LESS))
3508 {
3509 if (TREE_CODE (type) == TYPE_DECL)
3510 type = TREE_TYPE (type);
3511 if (TYPE_P (type) && !template_placeholder_p (type))
3512 error_at (location, "%qT is not a template", type);
3513 else if (identifier_p (t: type))
3514 {
3515 if (tag_type != none_type)
3516 error_at (location, "%qE is not a class template", type);
3517 else
3518 error_at (location, "%qE is not a template", type);
3519 }
3520 else
3521 error_at (location, "invalid template-id");
3522 /* Remember the location of the invalid "<". */
3523 if (cp_parser_uncommitted_to_tentative_parse_p (parser))
3524 start = cp_lexer_token_position (lexer: parser->lexer, previous_p: true);
3525 /* Consume the "<". */
3526 cp_lexer_consume_token (lexer: parser->lexer);
3527 /* Parse the template arguments. */
3528 cp_parser_enclosed_template_argument_list (parser);
3529 /* Permanently remove the invalid template arguments so that
3530 this error message is not issued again. */
3531 if (start)
3532 cp_lexer_purge_tokens_after (lexer: parser->lexer, tok: start);
3533 }
3534}
3535
3536/* If parsing an integral constant-expression, issue an error message
3537 about the fact that THING appeared and return true. Otherwise,
3538 return false. In either case, set
3539 PARSER->NON_INTEGRAL_CONSTANT_EXPRESSION_P. */
3540
3541static bool
3542cp_parser_non_integral_constant_expression (cp_parser *parser,
3543 non_integral_constant thing)
3544{
3545 parser->non_integral_constant_expression_p = true;
3546 if (parser->integral_constant_expression_p)
3547 {
3548 if (!parser->allow_non_integral_constant_expression_p)
3549 {
3550 const char *msg = NULL;
3551 switch (thing)
3552 {
3553 case NIC_FLOAT:
3554 pedwarn (input_location, OPT_Wpedantic,
3555 "ISO C++ forbids using a floating-point literal "
3556 "in a constant-expression");
3557 return true;
3558 case NIC_CAST:
3559 error ("a cast to a type other than an integral or "
3560 "enumeration type cannot appear in a "
3561 "constant-expression");
3562 return true;
3563 case NIC_TYPEID:
3564 error ("%<typeid%> operator "
3565 "cannot appear in a constant-expression");
3566 return true;
3567 case NIC_NCC:
3568 error ("non-constant compound literals "
3569 "cannot appear in a constant-expression");
3570 return true;
3571 case NIC_FUNC_CALL:
3572 error ("a function call "
3573 "cannot appear in a constant-expression");
3574 return true;
3575 case NIC_INC:
3576 error ("an increment "
3577 "cannot appear in a constant-expression");
3578 return true;
3579 case NIC_DEC:
3580 error ("an decrement "
3581 "cannot appear in a constant-expression");
3582 return true;
3583 case NIC_ARRAY_REF:
3584 error ("an array reference "
3585 "cannot appear in a constant-expression");
3586 return true;
3587 case NIC_ADDR_LABEL:
3588 error ("the address of a label "
3589 "cannot appear in a constant-expression");
3590 return true;
3591 case NIC_OVERLOADED:
3592 error ("calls to overloaded operators "
3593 "cannot appear in a constant-expression");
3594 return true;
3595 case NIC_ASSIGNMENT:
3596 error ("an assignment cannot appear in a constant-expression");
3597 return true;
3598 case NIC_COMMA:
3599 error ("a comma operator "
3600 "cannot appear in a constant-expression");
3601 return true;
3602 case NIC_CONSTRUCTOR:
3603 error ("a call to a constructor "
3604 "cannot appear in a constant-expression");
3605 return true;
3606 case NIC_TRANSACTION:
3607 error ("a transaction expression "
3608 "cannot appear in a constant-expression");
3609 return true;
3610 case NIC_THIS:
3611 msg = "this";
3612 break;
3613 case NIC_FUNC_NAME:
3614 msg = "__FUNCTION__";
3615 break;
3616 case NIC_PRETTY_FUNC:
3617 msg = "__PRETTY_FUNCTION__";
3618 break;
3619 case NIC_C99_FUNC:
3620 msg = "__func__";
3621 break;
3622 case NIC_VA_ARG:
3623 msg = "va_arg";
3624 break;
3625 case NIC_ARROW:
3626 msg = "->";
3627 break;
3628 case NIC_POINT:
3629 msg = ".";
3630 break;
3631 case NIC_STAR:
3632 msg = "*";
3633 break;
3634 case NIC_ADDR:
3635 msg = "&";
3636 break;
3637 case NIC_PREINCREMENT:
3638 msg = "++";
3639 break;
3640 case NIC_PREDECREMENT:
3641 msg = "--";
3642 break;
3643 case NIC_NEW:
3644 msg = "new";
3645 break;
3646 case NIC_DEL:
3647 msg = "delete";
3648 break;
3649 default:
3650 gcc_unreachable ();
3651 }
3652 if (msg)
3653 error ("%qs cannot appear in a constant-expression", msg);
3654 return true;
3655 }
3656 }
3657 return false;
3658}
3659
3660/* Emit a diagnostic for an invalid type name. This function commits
3661 to the current active tentative parse, if any. (Otherwise, the
3662 problematic construct might be encountered again later, resulting
3663 in duplicate error messages.) LOCATION is the location of ID. */
3664
3665static void
3666cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
3667 location_t location)
3668{
3669 tree decl, ambiguous_decls;
3670 cp_parser_commit_to_tentative_parse (parser);
3671 /* Try to lookup the identifier. */
3672 decl = cp_parser_lookup_name (parser, id, none_type,
3673 /*is_template=*/false,
3674 /*is_namespace=*/false,
3675 /*check_dependency=*/true,
3676 &ambiguous_decls, location);
3677 if (ambiguous_decls)
3678 /* If the lookup was ambiguous, an error will already have
3679 been issued. */
3680 return;
3681 /* If the lookup found a template-name, it means that the user forgot
3682 to specify an argument list. Emit a useful error message. */
3683 if (DECL_TYPE_TEMPLATE_P (decl))
3684 {
3685 auto_diagnostic_group d;
3686 error_at (location,
3687 "invalid use of template-name %qE without an argument list",
3688 decl);
3689 if (DECL_CLASS_TEMPLATE_P (decl) && cxx_dialect < cxx17)
3690 inform (location, "class template argument deduction is only available "
3691 "with %<-std=c++17%> or %<-std=gnu++17%>");
3692 inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
3693 }
3694 else if (TREE_CODE (id) == BIT_NOT_EXPR)
3695 error_at (location, "invalid use of destructor %qD as a type", id);
3696 else if (TREE_CODE (decl) == TYPE_DECL)
3697 /* Something like 'unsigned A a;' */
3698 error_at (location, "invalid combination of multiple type-specifiers");
3699 else if (!parser->scope)
3700 {
3701 /* Issue an error message. */
3702 auto_diagnostic_group d;
3703 name_hint hint;
3704 if (TREE_CODE (id) == IDENTIFIER_NODE)
3705 hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_TYPENAME, location);
3706 if (const char *suggestion = hint.suggestion ())
3707 {
3708 gcc_rich_location richloc (location);
3709 richloc.add_fixit_replace (new_content: suggestion);
3710 error_at (&richloc,
3711 "%qE does not name a type; did you mean %qs?",
3712 id, suggestion);
3713 }
3714 else
3715 error_at (location, "%qE does not name a type", id);
3716 /* If we're in a template class, it's possible that the user was
3717 referring to a type from a base class. For example:
3718
3719 template <typename T> struct A { typedef T X; };
3720 template <typename T> struct B : public A<T> { X x; };
3721
3722 The user should have said "typename A<T>::X". */
3723 if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_CONSTEXPR])
3724 inform (location, "C++11 %<constexpr%> only available with "
3725 "%<-std=c++11%> or %<-std=gnu++11%>");
3726 else if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_NOEXCEPT])
3727 inform (location, "C++11 %<noexcept%> only available with "
3728 "%<-std=c++11%> or %<-std=gnu++11%>");
3729 else if (TREE_CODE (id) == IDENTIFIER_NODE
3730 && (id_equal (id, str: "module") || id_equal (id, str: "import")))
3731 {
3732 if (modules_p ())
3733 inform (location, "%qE is not recognized as a module control-line",
3734 id);
3735 else if (cxx_dialect < cxx20)
3736 inform (location, "C++20 %qE only available with %<-fmodules-ts%>",
3737 id);
3738 else
3739 inform (location, "C++20 %qE only available with %<-fmodules-ts%>"
3740 ", which is not yet enabled with %<-std=c++20%>", id);
3741 }
3742 else if (cxx_dialect < cxx11
3743 && TREE_CODE (id) == IDENTIFIER_NODE
3744 && id_equal (id, str: "thread_local"))
3745 inform (location, "C++11 %<thread_local%> only available with "
3746 "%<-std=c++11%> or %<-std=gnu++11%>");
3747 else if (cxx_dialect < cxx20 && id == ridpointers[(int)RID_CONSTINIT])
3748 inform (location, "C++20 %<constinit%> only available with "
3749 "%<-std=c++20%> or %<-std=gnu++20%>");
3750 else if (!flag_concepts && id == ridpointers[(int)RID_CONCEPT])
3751 inform (location, "%<concept%> only available with %<-std=c++20%> or "
3752 "%<-fconcepts%>");
3753 else if (!flag_concepts && id == ridpointers[(int)RID_REQUIRES])
3754 inform (location, "%<requires%> only available with %<-std=c++20%> or "
3755 "%<-fconcepts%>");
3756 else if (processing_template_decl && current_class_type
3757 && TYPE_BINFO (current_class_type))
3758 {
3759 for (tree b = TREE_CHAIN (TYPE_BINFO (current_class_type));
3760 b; b = TREE_CHAIN (b))
3761 {
3762 tree base_type = BINFO_TYPE (b);
3763 if (CLASS_TYPE_P (base_type)
3764 && dependent_type_p (base_type))
3765 {
3766 /* Go from a particular instantiation of the
3767 template (which will have an empty TYPE_FIELDs),
3768 to the main version. */
3769 base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
3770 for (tree field = TYPE_FIELDS (base_type);
3771 field; field = DECL_CHAIN (field))
3772 if (TREE_CODE (field) == TYPE_DECL
3773 && DECL_NAME (field) == id)
3774 {
3775 inform (location,
3776 "(perhaps %<typename %T::%E%> was intended)",
3777 BINFO_TYPE (b), id);
3778 goto found;
3779 }
3780 }
3781 }
3782 found:;
3783 }
3784 }
3785 /* Here we diagnose qualified-ids where the scope is actually correct,
3786 but the identifier does not resolve to a valid type name. */
3787 else if (parser->scope != error_mark_node)
3788 {
3789 if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
3790 {
3791 auto_diagnostic_group d;
3792 name_hint hint;
3793 if (decl == error_mark_node)
3794 hint = suggest_alternative_in_explicit_scope (location, id,
3795 parser->scope);
3796 const char *suggestion = hint.suggestion ();
3797 gcc_rich_location richloc (location_of (id));
3798 if (suggestion)
3799 richloc.add_fixit_replace (new_content: suggestion);
3800 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_LESS))
3801 {
3802 if (suggestion)
3803 error_at (&richloc,
3804 "%qE in namespace %qE does not name a template"
3805 " type; did you mean %qs?",
3806 id, parser->scope, suggestion);
3807 else
3808 error_at (&richloc,
3809 "%qE in namespace %qE does not name a template type",
3810 id, parser->scope);
3811 }
3812 else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
3813 {
3814 if (suggestion)
3815 error_at (&richloc,
3816 "%qE in namespace %qE does not name a template"
3817 " type; did you mean %qs?",
3818 TREE_OPERAND (id, 0), parser->scope, suggestion);
3819 else
3820 error_at (&richloc,
3821 "%qE in namespace %qE does not name a template"
3822 " type",
3823 TREE_OPERAND (id, 0), parser->scope);
3824 }
3825 else
3826 {
3827 if (suggestion)
3828 error_at (&richloc,
3829 "%qE in namespace %qE does not name a type"
3830 "; did you mean %qs?",
3831 id, parser->scope, suggestion);
3832 else
3833 error_at (&richloc,
3834 "%qE in namespace %qE does not name a type",
3835 id, parser->scope);
3836 }
3837 if (DECL_P (decl))
3838 inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
3839 }
3840 else if (CLASS_TYPE_P (parser->scope)
3841 && constructor_name_p (id, parser->scope))
3842 {
3843 /* A<T>::A<T>() */
3844 auto_diagnostic_group d;
3845 error_at (location, "%<%T::%E%> names the constructor, not"
3846 " the type", parser->scope, id);
3847 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_LESS))
3848 error_at (location, "and %qT has no template constructors",
3849 parser->scope);
3850 }
3851 else if (TYPE_P (parser->scope)
3852 && dependent_scope_p (parser->scope))
3853 {
3854 gcc_rich_location richloc (location);
3855 richloc.add_fixit_insert_before (new_content: "typename ");
3856 if (TREE_CODE (parser->scope) == TYPENAME_TYPE)
3857 error_at (&richloc,
3858 "need %<typename%> before %<%T::%D::%E%> because "
3859 "%<%T::%D%> is a dependent scope",
3860 TYPE_CONTEXT (parser->scope),
3861 TYPENAME_TYPE_FULLNAME (parser->scope),
3862 id,
3863 TYPE_CONTEXT (parser->scope),
3864 TYPENAME_TYPE_FULLNAME (parser->scope));
3865 else
3866 error_at (&richloc, "need %<typename%> before %<%T::%E%> because "
3867 "%qT is a dependent scope",
3868 parser->scope, id, parser->scope);
3869 }
3870 else if (TYPE_P (parser->scope))
3871 {
3872 auto_diagnostic_group d;
3873 if (!COMPLETE_TYPE_P (parser->scope))
3874 cxx_incomplete_type_error (location_of (id), NULL_TREE,
3875 parser->scope);
3876 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_LESS))
3877 error_at (location_of (id),
3878 "%qE in %q#T does not name a template type",
3879 id, parser->scope);
3880 else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
3881 error_at (location_of (id),
3882 "%qE in %q#T does not name a template type",
3883 TREE_OPERAND (id, 0), parser->scope);
3884 else
3885 error_at (location_of (id),
3886 "%qE in %q#T does not name a type",
3887 id, parser->scope);
3888 if (DECL_P (decl))
3889 inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
3890 }
3891 else
3892 gcc_unreachable ();
3893 }
3894}
3895
3896/* Check for a common situation where a type-name should be present,
3897 but is not, and issue a sensible error message. Returns true if an
3898 invalid type-name was detected.
3899
3900 The situation handled by this function are variable declarations of the
3901 form `ID a', where `ID' is an id-expression and `a' is a plain identifier.
3902 Usually, `ID' should name a type, but if we got here it means that it
3903 does not. We try to emit the best possible error message depending on
3904 how exactly the id-expression looks like. */
3905
3906static bool
3907cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
3908{
3909 tree id;
3910 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
3911
3912 /* Avoid duplicate error about ambiguous lookup. */
3913 if (token->type == CPP_NESTED_NAME_SPECIFIER)
3914 {
3915 cp_token *next = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
3916 if (next->type == CPP_NAME && next->error_reported)
3917 goto out;
3918 }
3919
3920 cp_parser_parse_tentatively (parser);
3921 id = cp_parser_id_expression (parser,
3922 /*template_keyword_p=*/false,
3923 /*check_dependency_p=*/true,
3924 /*template_p=*/NULL,
3925 /*declarator_p=*/true,
3926 /*optional_p=*/false);
3927 /* If the next token is a (, this is a function with no explicit return
3928 type, i.e. constructor, destructor or conversion op. */
3929 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN)
3930 || TREE_CODE (id) == TYPE_DECL)
3931 {
3932 cp_parser_abort_tentative_parse (parser);
3933 return false;
3934 }
3935 if (!cp_parser_parse_definitely (parser))
3936 return false;
3937
3938 /* Emit a diagnostic for the invalid type. */
3939 cp_parser_diagnose_invalid_type_name (parser, id, location: token->location);
3940 out:
3941 /* If we aren't in the middle of a declarator (i.e. in a
3942 parameter-declaration-clause), skip to the end of the declaration;
3943 there's no point in trying to process it. */
3944 if (!parser->in_declarator_p)
3945 cp_parser_skip_to_end_of_block_or_statement (parser);
3946 return true;
3947}
3948
3949/* Consume tokens up to, and including, the next non-nested closing `)'.
3950 Returns 1 iff we found a closing `)'. RECOVERING is true, if we
3951 are doing error recovery. Returns -1 if OR_TTYPE is not CPP_EOF and we
3952 found an unnested token of that type. */
3953
3954static int
3955cp_parser_skip_to_closing_parenthesis_1 (cp_parser *parser,
3956 bool recovering,
3957 cpp_ttype or_ttype,
3958 bool consume_paren)
3959{
3960 unsigned paren_depth = 0;
3961 unsigned brace_depth = 0;
3962 unsigned square_depth = 0;
3963 unsigned condop_depth = 0;
3964
3965 if (recovering && or_ttype == CPP_EOF
3966 && cp_parser_uncommitted_to_tentative_parse_p (parser))
3967 return 0;
3968
3969 while (true)
3970 {
3971 cp_token * token = cp_lexer_peek_token (lexer: parser->lexer);
3972
3973 /* Have we found what we're looking for before the closing paren? */
3974 if (token->type == or_ttype && or_ttype != CPP_EOF
3975 && !brace_depth && !paren_depth && !square_depth && !condop_depth)
3976 return -1;
3977
3978 switch (token->type)
3979 {
3980 case CPP_PRAGMA_EOL:
3981 if (!parser->lexer->in_pragma)
3982 break;
3983 /* FALLTHRU */
3984 case CPP_EOF:
3985 /* If we've run out of tokens, then there is no closing `)'. */
3986 return 0;
3987
3988 /* This is good for lambda expression capture-lists. */
3989 case CPP_OPEN_SQUARE:
3990 ++square_depth;
3991 break;
3992 case CPP_CLOSE_SQUARE:
3993 if (!square_depth--)
3994 return 0;
3995 break;
3996
3997 case CPP_SEMICOLON:
3998 /* This matches the processing in skip_to_end_of_statement. */
3999 if (!brace_depth)
4000 return 0;
4001 break;
4002
4003 case CPP_OPEN_BRACE:
4004 ++brace_depth;
4005 break;
4006 case CPP_CLOSE_BRACE:
4007 if (!brace_depth--)
4008 return 0;
4009 break;
4010
4011 case CPP_OPEN_PAREN:
4012 if (!brace_depth)
4013 ++paren_depth;
4014 break;
4015
4016 case CPP_CLOSE_PAREN:
4017 if (!brace_depth && !paren_depth--)
4018 {
4019 if (consume_paren)
4020 cp_lexer_consume_token (lexer: parser->lexer);
4021 return 1;
4022 }
4023 break;
4024
4025 case CPP_QUERY:
4026 if (!brace_depth && !paren_depth && !square_depth)
4027 ++condop_depth;
4028 break;
4029
4030 case CPP_COLON:
4031 if (!brace_depth && !paren_depth && !square_depth && condop_depth > 0)
4032 condop_depth--;
4033 break;
4034
4035 case CPP_KEYWORD:
4036 if (!cp_token_is_module_directive (token))
4037 break;
4038 /* FALLTHROUGH */
4039
4040 case CPP_PRAGMA:
4041 /* We fell into a pragma. Skip it, and continue. */
4042 cp_parser_skip_to_pragma_eol (parser, recovering ? token : nullptr);
4043 continue;
4044
4045 default:
4046 break;
4047 }
4048
4049 /* Consume the token. */
4050 cp_lexer_consume_token (lexer: parser->lexer);
4051 }
4052}
4053
4054/* Consume tokens up to, and including, the next non-nested closing `)'.
4055 Returns 1 iff we found a closing `)'. RECOVERING is true, if we
4056 are doing error recovery. Returns -1 if OR_COMMA is true and we
4057 found an unnested token of that type. */
4058
4059static int
4060cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
4061 bool recovering,
4062 bool or_comma,
4063 bool consume_paren)
4064{
4065 cpp_ttype ttype = or_comma ? CPP_COMMA : CPP_EOF;
4066 return cp_parser_skip_to_closing_parenthesis_1 (parser, recovering,
4067 or_ttype: ttype, consume_paren);
4068}
4069
4070/* Consume tokens until we reach the end of the current statement.
4071 Normally, that will be just before consuming a `;'. However, if a
4072 non-nested `}' comes first, then we stop before consuming that. */
4073
4074static void
4075cp_parser_skip_to_end_of_statement (cp_parser* parser)
4076{
4077 unsigned nesting_depth = 0;
4078
4079 /* Unwind generic function template scope if necessary. */
4080 if (parser->fully_implicit_function_template_p)
4081 abort_fully_implicit_template (parser);
4082
4083 while (true)
4084 {
4085 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
4086
4087 switch (token->type)
4088 {
4089 case CPP_PRAGMA_EOL:
4090 if (!parser->lexer->in_pragma)
4091 break;
4092 /* FALLTHRU */
4093 case CPP_EOF:
4094 /* If we've run out of tokens, stop. */
4095 return;
4096
4097 case CPP_SEMICOLON:
4098 /* If the next token is a `;', we have reached the end of the
4099 statement. */
4100 if (!nesting_depth)
4101 return;
4102 break;
4103
4104 case CPP_CLOSE_BRACE:
4105 /* If this is a non-nested '}', stop before consuming it.
4106 That way, when confronted with something like:
4107
4108 { 3 + }
4109
4110 we stop before consuming the closing '}', even though we
4111 have not yet reached a `;'. */
4112 if (nesting_depth == 0)
4113 return;
4114
4115 /* If it is the closing '}' for a block that we have
4116 scanned, stop -- but only after consuming the token.
4117 That way given:
4118
4119 void f g () { ... }
4120 typedef int I;
4121
4122 we will stop after the body of the erroneously declared
4123 function, but before consuming the following `typedef'
4124 declaration. */
4125 if (--nesting_depth == 0)
4126 {
4127 cp_lexer_consume_token (lexer: parser->lexer);
4128 return;
4129 }
4130 break;
4131
4132 case CPP_OPEN_BRACE:
4133 ++nesting_depth;
4134 break;
4135
4136 case CPP_KEYWORD:
4137 if (!cp_token_is_module_directive (token))
4138 break;
4139 /* FALLTHROUGH */
4140
4141 case CPP_PRAGMA:
4142 /* We fell into a pragma. Skip it, and continue or return. */
4143 cp_parser_skip_to_pragma_eol (parser, token);
4144 if (!nesting_depth)
4145 return;
4146 continue;
4147
4148 default:
4149 break;
4150 }
4151
4152 /* Consume the token. */
4153 cp_lexer_consume_token (lexer: parser->lexer);
4154 }
4155}
4156
4157/* This function is called at the end of a statement or declaration.
4158 If the next token is a semicolon, it is consumed; otherwise, error
4159 recovery is attempted. */
4160
4161static void
4162cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser)
4163{
4164 /* Look for the trailing `;'. */
4165 if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
4166 {
4167 /* If there is additional (erroneous) input, skip to the end of
4168 the statement. */
4169 cp_parser_skip_to_end_of_statement (parser);
4170 /* If the next token is now a `;', consume it. */
4171 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
4172 cp_lexer_consume_token (lexer: parser->lexer);
4173 }
4174}
4175
4176/* Skip tokens until we have consumed an entire block, or until we
4177 have consumed a non-nested `;'. */
4178
4179static void
4180cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
4181{
4182 int nesting_depth = 0;
4183
4184 /* Unwind generic function template scope if necessary. */
4185 if (parser->fully_implicit_function_template_p)
4186 abort_fully_implicit_template (parser);
4187
4188 while (nesting_depth >= 0)
4189 {
4190 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
4191
4192 switch (token->type)
4193 {
4194 case CPP_PRAGMA_EOL:
4195 if (!parser->lexer->in_pragma)
4196 break;
4197 /* FALLTHRU */
4198 case CPP_EOF:
4199 /* If we've run out of tokens, stop. */
4200 return;
4201
4202 case CPP_SEMICOLON:
4203 /* Stop if this is an unnested ';'. */
4204 if (!nesting_depth)
4205 nesting_depth = -1;
4206 break;
4207
4208 case CPP_CLOSE_BRACE:
4209 /* Stop if this is an unnested '}', or closes the outermost
4210 nesting level. */
4211 nesting_depth--;
4212 if (nesting_depth < 0)
4213 return;
4214 if (!nesting_depth)
4215 nesting_depth = -1;
4216 break;
4217
4218 case CPP_OPEN_BRACE:
4219 /* Nest. */
4220 nesting_depth++;
4221 break;
4222
4223 case CPP_KEYWORD:
4224 if (!cp_token_is_module_directive (token))
4225 break;
4226 /* FALLTHROUGH */
4227
4228 case CPP_PRAGMA:
4229 /* Skip it, and continue or return. */
4230 cp_parser_skip_to_pragma_eol (parser, token);
4231 if (!nesting_depth)
4232 return;
4233 continue;
4234
4235 default:
4236 break;
4237 }
4238
4239 /* Consume the token. */
4240 cp_lexer_consume_token (lexer: parser->lexer);
4241 }
4242}
4243
4244/* Skip tokens until a non-nested closing curly brace is the next
4245 token, or there are no more tokens. Return true in the first case,
4246 false otherwise. */
4247
4248static bool
4249cp_parser_skip_to_closing_brace (cp_parser *parser)
4250{
4251 unsigned nesting_depth = 0;
4252
4253 while (true)
4254 {
4255 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
4256
4257 switch (token->type)
4258 {
4259 case CPP_PRAGMA_EOL:
4260 if (!parser->lexer->in_pragma)
4261 break;
4262 /* FALLTHRU */
4263 case CPP_EOF:
4264 /* If we've run out of tokens, stop. */
4265 return false;
4266
4267 case CPP_CLOSE_BRACE:
4268 /* If the next token is a non-nested `}', then we have reached
4269 the end of the current block. */
4270 if (nesting_depth-- == 0)
4271 return true;
4272 break;
4273
4274 case CPP_OPEN_BRACE:
4275 /* If it the next token is a `{', then we are entering a new
4276 block. Consume the entire block. */
4277 ++nesting_depth;
4278 break;
4279
4280 default:
4281 break;
4282 }
4283
4284 /* Consume the token. */
4285 cp_lexer_consume_token (lexer: parser->lexer);
4286 }
4287}
4288
4289/* Consume tokens until we reach the end of the pragma. The PRAGMA_TOK
4290 parameter is the PRAGMA token, allowing us to purge the entire pragma
4291 sequence. PRAGMA_TOK can be NULL, if we're speculatively scanning
4292 forwards (not error recovery). */
4293
4294static void
4295cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok)
4296{
4297 cp_token *token;
4298
4299 do
4300 {
4301 /* The preprocessor makes sure that a PRAGMA_EOL token appears
4302 before an EOF token, even when the EOF is on the pragma line.
4303 We should never get here without being inside a deferred
4304 pragma. */
4305 gcc_checking_assert (cp_lexer_next_token_is_not (parser->lexer, CPP_EOF));
4306 token = cp_lexer_consume_token (lexer: parser->lexer);
4307 }
4308 while (token->type != CPP_PRAGMA_EOL);
4309
4310 if (pragma_tok)
4311 {
4312 parser->lexer->in_pragma = false;
4313 if (parser->lexer->in_omp_attribute_pragma
4314 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EOF))
4315 {
4316 parser->lexer = parser->lexer->next;
4317 /* Put the current source position back where it was before this
4318 lexer was pushed. */
4319 cp_lexer_set_source_position_from_token (token: parser->lexer->next_token);
4320 }
4321 }
4322}
4323
4324/* Require pragma end of line, resyncing with it as necessary. The
4325 arguments are as for cp_parser_skip_to_pragma_eol. */
4326
4327static void
4328cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
4329{
4330 parser->lexer->in_pragma = false;
4331 if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL))
4332 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
4333 else if (parser->lexer->in_omp_attribute_pragma
4334 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EOF))
4335 {
4336 parser->lexer = parser->lexer->next;
4337 /* Put the current source position back where it was before this
4338 lexer was pushed. */
4339 cp_lexer_set_source_position_from_token (token: parser->lexer->next_token);
4340 }
4341}
4342
4343/* This is a simple wrapper around make_typename_type. When the id is
4344 an unresolved identifier node, we can provide a superior diagnostic
4345 using cp_parser_diagnose_invalid_type_name. */
4346
4347static tree
4348cp_parser_make_typename_type (cp_parser *parser, tree id,
4349 location_t id_location)
4350{
4351 tree result;
4352 if (identifier_p (t: id))
4353 {
4354 result = make_typename_type (parser->scope, id, typename_type,
4355 /*complain=*/tf_none);
4356 if (result == error_mark_node)
4357 cp_parser_diagnose_invalid_type_name (parser, id, location: id_location);
4358 return result;
4359 }
4360 return make_typename_type (parser->scope, id, typename_type, tf_error);
4361}
4362
4363/* This is a wrapper around the
4364 make_{pointer,ptrmem,reference}_declarator functions that decides
4365 which one to call based on the CODE and CLASS_TYPE arguments. The
4366 CODE argument should be one of the values returned by
4367 cp_parser_ptr_operator. ATTRIBUTES represent the attributes that
4368 appertain to the pointer or reference. */
4369
4370static cp_declarator *
4371cp_parser_make_indirect_declarator (enum tree_code code, tree class_type,
4372 cp_cv_quals cv_qualifiers,
4373 cp_declarator *target,
4374 tree attributes)
4375{
4376 if (code == ERROR_MARK || target == cp_error_declarator)
4377 return cp_error_declarator;
4378
4379 if (code == INDIRECT_REF)
4380 if (class_type == NULL_TREE)
4381 return make_pointer_declarator (cv_qualifiers, target, attributes);
4382 else
4383 return make_ptrmem_declarator (cv_qualifiers, class_type,
4384 pointee: target, attributes);
4385 else if (code == ADDR_EXPR && class_type == NULL_TREE)
4386 return make_reference_declarator (cv_qualifiers, target,
4387 rvalue_ref: false, attributes);
4388 else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE)
4389 return make_reference_declarator (cv_qualifiers, target,
4390 rvalue_ref: true, attributes);
4391 gcc_unreachable ();
4392}
4393
4394/* Create a new C++ parser. */
4395
4396static cp_parser *
4397cp_parser_new (cp_lexer *lexer)
4398{
4399 /* Initialize the binops_by_token so that we can get the tree
4400 directly from the token. */
4401 for (unsigned i = 0; i < ARRAY_SIZE (binops); i++)
4402 binops_by_token[binops[i].token_type] = binops[i];
4403
4404 cp_parser *parser = ggc_cleared_alloc<cp_parser> ();
4405 parser->lexer = lexer;
4406 parser->context = cp_parser_context_new (NULL);
4407
4408 /* For now, we always accept GNU extensions. */
4409 parser->allow_gnu_extensions_p = 1;
4410
4411 /* The `>' token is a greater-than operator, not the end of a
4412 template-id. */
4413 parser->greater_than_is_operator_p = true;
4414
4415 parser->default_arg_ok_p = true;
4416
4417 /* We are not parsing a constant-expression. */
4418 parser->integral_constant_expression_p = false;
4419 parser->allow_non_integral_constant_expression_p = false;
4420 parser->non_integral_constant_expression_p = false;
4421
4422 /* Local variable names are not forbidden. */
4423 parser->local_variables_forbidden_p = 0;
4424
4425 /* We are not processing an `extern "C"' declaration. */
4426 parser->in_unbraced_linkage_specification_p = false;
4427
4428 /* We are not processing a declarator. */
4429 parser->in_declarator_p = false;
4430
4431 /* We are not processing a template-argument-list. */
4432 parser->in_template_argument_list_p = false;
4433
4434 /* We are not in an iteration statement. */
4435 parser->in_statement = 0;
4436
4437 /* We are not in a switch statement. */
4438 parser->in_switch_statement_p = false;
4439
4440 /* We are not parsing a type-id inside an expression. */
4441 parser->in_type_id_in_expr_p = false;
4442
4443 /* String literals should be translated to the execution character set. */
4444 parser->translate_strings_p = true;
4445
4446 /* We are not parsing a function body. */
4447 parser->in_function_body = false;
4448
4449 /* We can correct until told otherwise. */
4450 parser->colon_corrects_to_scope_p = true;
4451
4452 /* The unparsed function queue is empty. */
4453 push_unparsed_function_queues (parser);
4454
4455 /* There are no classes being defined. */
4456 parser->num_classes_being_defined = 0;
4457
4458 /* No template parameters apply. */
4459 parser->num_template_parameter_lists = 0;
4460
4461 /* Special parsing data structures. */
4462 parser->omp_declare_simd = NULL;
4463 parser->oacc_routine = NULL;
4464
4465 /* Disallow OpenMP array sections in expressions. */
4466 parser->omp_array_section_p = false;
4467
4468 /* Not declaring an implicit function template. */
4469 parser->auto_is_implicit_function_template_parm_p = false;
4470 parser->fully_implicit_function_template_p = false;
4471 parser->implicit_template_parms = 0;
4472 parser->implicit_template_scope = 0;
4473
4474 /* Allow constrained-type-specifiers. */
4475 parser->prevent_constrained_type_specifiers = 0;
4476
4477 /* We haven't yet seen an 'extern "C"'. */
4478 parser->innermost_linkage_specification_location = UNKNOWN_LOCATION;
4479
4480 return parser;
4481}
4482
4483/* Create a cp_lexer structure which will emit the tokens in CACHE
4484 and push it onto the parser's lexer stack. This is used for delayed
4485 parsing of in-class method bodies and default arguments, and should
4486 not be confused with tentative parsing. */
4487static void
4488cp_parser_push_lexer_for_tokens (cp_parser *parser, cp_token_cache *cache)
4489{
4490 cp_lexer *lexer = cp_lexer_new_from_tokens (cache);
4491 lexer->next = parser->lexer;
4492 parser->lexer = lexer;
4493
4494 /* Move the current source position to that of the first token in the
4495 new lexer. */
4496 cp_lexer_set_source_position_from_token (token: lexer->next_token);
4497}
4498
4499/* Pop the top lexer off the parser stack. This is never used for the
4500 "main" lexer, only for those pushed by cp_parser_push_lexer_for_tokens. */
4501static void
4502cp_parser_pop_lexer (cp_parser *parser)
4503{
4504 cp_lexer *lexer = parser->lexer;
4505 parser->lexer = lexer->next;
4506 cp_lexer_destroy (lexer);
4507
4508 /* Put the current source position back where it was before this
4509 lexer was pushed. */
4510 cp_lexer_set_source_position_from_token (token: parser->lexer->next_token);
4511}
4512
4513/* Lexical conventions [gram.lex] */
4514
4515/* Parse an identifier. Returns an IDENTIFIER_NODE representing the
4516 identifier. */
4517
4518static cp_expr
4519cp_parser_identifier (cp_parser* parser)
4520{
4521 cp_token *token;
4522
4523 /* Look for the identifier. */
4524 token = cp_parser_require (parser, CPP_NAME, RT_NAME);
4525 /* Return the value. */
4526 if (token)
4527 return cp_expr (token->u.value, token->location);
4528 else
4529 return error_mark_node;
4530}
4531
4532/* Worker for cp_parser_string_literal, cp_parser_userdef_string_literal
4533 and cp_parser_unevaluated_string_literal.
4534 Do not call this directly; use either of the above.
4535
4536 Parse a sequence of adjacent string constants. Return a
4537 TREE_STRING representing the combined, nul-terminated string
4538 constant. If TRANSLATE is true, translate the string to the
4539 execution character set. If WIDE_OK is true, a wide string is
4540 valid here. If UDL_OK is true, a string literal with user-defined
4541 suffix can be used in this context. If UNEVAL is true, diagnose
4542 numeric and conditional escape sequences in it if pedantic.
4543
4544 C++98 [lex.string] says that if a narrow string literal token is
4545 adjacent to a wide string literal token, the behavior is undefined.
4546 However, C99 6.4.5p4 says that this results in a wide string literal.
4547 We follow C99 here, for consistency with the C front end.
4548
4549 This code is largely lifted from lex_string() in c-lex.cc.
4550
4551 FUTURE: ObjC++ will need to handle @-strings here. */
4552
4553static cp_expr
4554cp_parser_string_literal_common (cp_parser *parser, bool translate,
4555 bool wide_ok, bool udl_ok,
4556 bool lookup_udlit, bool uneval)
4557{
4558 tree value;
4559 size_t count;
4560 struct obstack str_ob;
4561 struct obstack loc_ob;
4562 cpp_string str, istr, *strs;
4563 cp_token *tok;
4564 enum cpp_ttype type, curr_type;
4565 int have_suffix_p = 0;
4566 tree string_tree;
4567 tree suffix_id = NULL_TREE;
4568 bool curr_tok_is_userdef_p = false;
4569
4570 tok = cp_lexer_peek_token (lexer: parser->lexer);
4571 if (!cp_parser_is_string_literal (token: tok))
4572 {
4573 cp_parser_error (parser, gmsgid: "expected string-literal");
4574 return error_mark_node;
4575 }
4576
4577 location_t loc = tok->location;
4578
4579 if (cpp_userdef_string_p (type: tok->type))
4580 {
4581 if (!udl_ok)
4582 {
4583 error_at (loc, "string literal with user-defined suffix "
4584 "is invalid in this context");
4585 return error_mark_node;
4586 }
4587 string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
4588 curr_type = cpp_userdef_string_remove_type (type: tok->type);
4589 curr_tok_is_userdef_p = true;
4590 }
4591 else
4592 {
4593 string_tree = tok->u.value;
4594 curr_type = tok->type;
4595 }
4596 type = curr_type;
4597
4598 /* Try to avoid the overhead of creating and destroying an obstack
4599 for the common case of just one string. */
4600 if (!cp_parser_is_string_literal
4601 (token: cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)))
4602 {
4603 cp_lexer_consume_token (lexer: parser->lexer);
4604
4605 str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
4606 str.len = TREE_STRING_LENGTH (string_tree);
4607 count = 1;
4608
4609 if (curr_tok_is_userdef_p)
4610 {
4611 suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
4612 have_suffix_p = 1;
4613 curr_type = cpp_userdef_string_remove_type (type: tok->type);
4614 }
4615 else
4616 curr_type = tok->type;
4617
4618 strs = &str;
4619 }
4620 else
4621 {
4622 location_t last_tok_loc = tok->location;
4623 gcc_obstack_init (&str_ob);
4624 gcc_obstack_init (&loc_ob);
4625 count = 0;
4626
4627 do
4628 {
4629 cp_lexer_consume_token (lexer: parser->lexer);
4630 count++;
4631 str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
4632 str.len = TREE_STRING_LENGTH (string_tree);
4633
4634 if (curr_tok_is_userdef_p)
4635 {
4636 tree curr_suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
4637 if (have_suffix_p == 0)
4638 {
4639 suffix_id = curr_suffix_id;
4640 have_suffix_p = 1;
4641 }
4642 else if (have_suffix_p == 1
4643 && curr_suffix_id != suffix_id)
4644 {
4645 error ("inconsistent user-defined literal suffixes"
4646 " %qD and %qD in string literal",
4647 suffix_id, curr_suffix_id);
4648 have_suffix_p = -1;
4649 }
4650 curr_type = cpp_userdef_string_remove_type (type: tok->type);
4651 }
4652 else
4653 curr_type = tok->type;
4654
4655 if (type != curr_type)
4656 {
4657 if (type == CPP_STRING)
4658 type = curr_type;
4659 else if (curr_type != CPP_STRING)
4660 {
4661 rich_location rich_loc (line_table, tok->location);
4662 rich_loc.add_range (loc: last_tok_loc);
4663 error_at (&rich_loc,
4664 "concatenation of string literals with "
4665 "conflicting encoding prefixes");
4666 }
4667 }
4668
4669 obstack_grow (&str_ob, &str, sizeof (cpp_string));
4670 obstack_grow (&loc_ob, &tok->location, sizeof (location_t));
4671
4672 last_tok_loc = tok->location;
4673
4674 tok = cp_lexer_peek_token (lexer: parser->lexer);
4675 if (cpp_userdef_string_p (type: tok->type))
4676 {
4677 if (!udl_ok)
4678 {
4679 error_at (loc, "string literal with user-defined suffix "
4680 "is invalid in this context");
4681 return error_mark_node;
4682 }
4683 string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
4684 curr_type = cpp_userdef_string_remove_type (type: tok->type);
4685 curr_tok_is_userdef_p = true;
4686 }
4687 else
4688 {
4689 string_tree = tok->u.value;
4690 curr_type = tok->type;
4691 curr_tok_is_userdef_p = false;
4692 }
4693 }
4694 while (cp_parser_is_string_literal (token: tok));
4695
4696 /* A string literal built by concatenation has its caret=start at
4697 the start of the initial string, and its finish at the finish of
4698 the final string literal. */
4699 loc = make_location (caret: loc, start: loc, finish: get_finish (loc: last_tok_loc));
4700
4701 strs = (cpp_string *) obstack_finish (&str_ob);
4702 }
4703
4704 if (type != CPP_STRING && !wide_ok)
4705 {
4706 cp_parser_error (parser, gmsgid: "a wide string is invalid in this context");
4707 type = CPP_STRING;
4708 }
4709 if (uneval)
4710 type = CPP_UNEVAL_STRING;
4711
4712 if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate)
4713 (parse_in, strs, count, &istr, type))
4714 {
4715 value = build_string (istr.len, (const char *)istr.text);
4716 free (CONST_CAST (unsigned char *, istr.text));
4717 if (count > 1)
4718 {
4719 location_t *locs = (location_t *)obstack_finish (&loc_ob);
4720 gcc_assert (g_string_concat_db);
4721 g_string_concat_db->record_string_concatenation (num: count, locs);
4722 }
4723
4724 switch (type)
4725 {
4726 default:
4727 case CPP_STRING:
4728 TREE_TYPE (value) = char_array_type_node;
4729 break;
4730 case CPP_UTF8STRING:
4731 if (flag_char8_t)
4732 TREE_TYPE (value) = char8_array_type_node;
4733 else
4734 TREE_TYPE (value) = char_array_type_node;
4735 break;
4736 case CPP_STRING16:
4737 TREE_TYPE (value) = char16_array_type_node;
4738 break;
4739 case CPP_STRING32:
4740 TREE_TYPE (value) = char32_array_type_node;
4741 break;
4742 case CPP_WSTRING:
4743 TREE_TYPE (value) = wchar_array_type_node;
4744 break;
4745 }
4746
4747 value = fix_string_type (value);
4748
4749 if (have_suffix_p)
4750 {
4751 tree literal = build_userdef_literal (suffix_id, value,
4752 overflow: OT_NONE, NULL_TREE);
4753 if (lookup_udlit)
4754 value = finish_userdef_string_literal (literal);
4755 else
4756 value = literal;
4757 }
4758 }
4759 else
4760 /* cpp_interpret_string has issued an error. */
4761 value = error_mark_node;
4762
4763 if (count > 1)
4764 {
4765 obstack_free (&str_ob, 0);
4766 obstack_free (&loc_ob, 0);
4767 }
4768
4769 return cp_expr (value, loc);
4770}
4771
4772/* Parse a sequence of adjacent string constants. Return a TREE_STRING
4773 representing the combined, nul-terminated string constant. If
4774 TRANSLATE is true, translate the string to the execution character set.
4775 If WIDE_OK is true, a wide string is valid here.
4776
4777 This function issues an error if a user defined string literal is
4778 encountered; use cp_parser_userdef_string_literal if UDLs are allowed. */
4779
4780static inline cp_expr
4781cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
4782{
4783 return cp_parser_string_literal_common (parser, translate, wide_ok,
4784 /*udl_ok=*/false,
4785 /*lookup_udlit=*/false,
4786 /*uneval=*/false);
4787}
4788
4789/* Parse a string literal or user defined string literal.
4790
4791 user-defined-string-literal :
4792 string-literal ud-suffix
4793
4794 If LOOKUP_UDLIT, perform a lookup for a suitable template function. */
4795
4796static inline cp_expr
4797cp_parser_userdef_string_literal (cp_parser *parser, bool lookup_udlit)
4798{
4799 return cp_parser_string_literal_common (parser, /*translate=*/true,
4800 /*wide_ok=*/true, /*udl_ok=*/true,
4801 lookup_udlit, /*uneval=*/false);
4802}
4803
4804/* Parse an unevaluated string literal.
4805
4806 unevaluated-string:
4807 string-literal */
4808
4809static inline cp_expr
4810cp_parser_unevaluated_string_literal (cp_parser *parser)
4811{
4812 return cp_parser_string_literal_common (parser, /*translate=*/false,
4813 /*wide_ok=*/false, /*udl_ok=*/false,
4814 /*lookup_udlit=*/false,
4815 /*uneval=*/true);
4816}
4817
4818/* Look up a literal operator with the name and the exact arguments. */
4819
4820static tree
4821lookup_literal_operator (tree name, vec<tree, va_gc> *args)
4822{
4823 tree decl = lookup_name (name);
4824 if (!decl || !is_overloaded_fn (decl))
4825 return error_mark_node;
4826
4827 for (lkp_iterator iter (decl); iter; ++iter)
4828 {
4829 tree fn = *iter;
4830
4831 if (tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn)))
4832 {
4833 unsigned int ix;
4834 bool found = true;
4835
4836 for (ix = 0;
4837 found && ix < vec_safe_length (v: args) && parmtypes != NULL_TREE;
4838 ++ix, parmtypes = TREE_CHAIN (parmtypes))
4839 {
4840 tree tparm = TREE_VALUE (parmtypes);
4841 tree targ = TREE_TYPE ((*args)[ix]);
4842 bool ptr = TYPE_PTR_P (tparm);
4843 bool arr = TREE_CODE (targ) == ARRAY_TYPE;
4844 if ((ptr || arr || !same_type_p (tparm, targ))
4845 && (!ptr || !arr
4846 || !same_type_p (TREE_TYPE (tparm),
4847 TREE_TYPE (targ))))
4848 found = false;
4849 }
4850
4851 if (found
4852 && ix == vec_safe_length (v: args)
4853 /* May be this should be sufficient_parms_p instead,
4854 depending on how exactly should user-defined literals
4855 work in presence of default arguments on the literal
4856 operator parameters. */
4857 && parmtypes == void_list_node)
4858 return decl;
4859 }
4860 }
4861
4862 return error_mark_node;
4863}
4864
4865/* Parse a user-defined char constant. Returns a call to a user-defined
4866 literal operator taking the character as an argument. */
4867
4868static cp_expr
4869cp_parser_userdef_char_literal (cp_parser *parser)
4870{
4871 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
4872 tree literal = token->u.value;
4873 tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
4874 tree value = USERDEF_LITERAL_VALUE (literal);
4875 tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
4876 tree decl, result;
4877
4878 /* Build up a call to the user-defined operator */
4879 /* Lookup the name we got back from the id-expression. */
4880 releasing_vec args;
4881 vec_safe_push (r&: args, t: value);
4882 decl = lookup_literal_operator (name, args);
4883 if (!decl || decl == error_mark_node)
4884 {
4885 error ("unable to find character literal operator %qD with %qT argument",
4886 name, TREE_TYPE (value));
4887 return error_mark_node;
4888 }
4889 result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
4890 return result;
4891}
4892
4893/* A subroutine of cp_parser_userdef_numeric_literal to
4894 create a char... template parameter pack from a string node. */
4895
4896static tree
4897make_char_string_pack (tree value)
4898{
4899 tree charvec;
4900 tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
4901 const unsigned char *str
4902 = (const unsigned char *) TREE_STRING_POINTER (value);
4903 int i, len = TREE_STRING_LENGTH (value) - 1;
4904 tree argvec = make_tree_vec (1);
4905
4906 /* Fill in CHARVEC with all of the parameters. */
4907 charvec = make_tree_vec (len);
4908 for (i = 0; i < len; ++i)
4909 {
4910 unsigned char s[3] = { '\'', str[i], '\'' };
4911 cpp_string in = { .len: 3, .text: s };
4912 cpp_string out = { .len: 0, .text: 0 };
4913 if (!cpp_interpret_string (parse_in, &in, 1, &out, CPP_STRING))
4914 return NULL_TREE;
4915 gcc_assert (out.len == 2);
4916 TREE_VEC_ELT (charvec, i) = build_int_cst (char_type_node,
4917 out.text[0]);
4918 }
4919
4920 /* Build the argument packs. */
4921 ARGUMENT_PACK_ARGS (argpack) = charvec;
4922
4923 TREE_VEC_ELT (argvec, 0) = argpack;
4924
4925 return argvec;
4926}
4927
4928/* A subroutine of cp_parser_userdef_numeric_literal to
4929 create a char... template parameter pack from a string node. */
4930
4931static tree
4932make_string_pack (tree value)
4933{
4934 tree charvec;
4935 tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
4936 const unsigned char *str
4937 = (const unsigned char *) TREE_STRING_POINTER (value);
4938 int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value))));
4939 int len = TREE_STRING_LENGTH (value) / sz - 1;
4940 tree argvec = make_tree_vec (2);
4941
4942 tree str_char_type_node = TREE_TYPE (TREE_TYPE (value));
4943 str_char_type_node = TYPE_MAIN_VARIANT (str_char_type_node);
4944
4945 /* First template parm is character type. */
4946 TREE_VEC_ELT (argvec, 0) = str_char_type_node;
4947
4948 /* Fill in CHARVEC with all of the parameters. */
4949 charvec = make_tree_vec (len);
4950 for (int i = 0; i < len; ++i)
4951 TREE_VEC_ELT (charvec, i)
4952 = double_int_to_tree (str_char_type_node,
4953 double_int::from_buffer (buffer: str + i * sz, len: sz));
4954
4955 /* Build the argument packs. */
4956 ARGUMENT_PACK_ARGS (argpack) = charvec;
4957
4958 TREE_VEC_ELT (argvec, 1) = argpack;
4959
4960 return argvec;
4961}
4962
4963/* Parse a user-defined numeric constant. returns a call to a user-defined
4964 literal operator. */
4965
4966static cp_expr
4967cp_parser_userdef_numeric_literal (cp_parser *parser)
4968{
4969 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
4970 tree literal = token->u.value;
4971 tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
4972 tree value = USERDEF_LITERAL_VALUE (literal);
4973 int overflow = USERDEF_LITERAL_OVERFLOW (literal);
4974 tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
4975 tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
4976 tree decl, result;
4977
4978 /* Look for a literal operator taking the exact type of numeric argument
4979 as the literal value. */
4980 releasing_vec args;
4981 vec_safe_push (r&: args, t: value);
4982 decl = lookup_literal_operator (name, args);
4983 if (decl && decl != error_mark_node)
4984 {
4985 result = finish_call_expr (decl, &args, false, true,
4986 tf_warning_or_error);
4987
4988 if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0)
4989 {
4990 warning_at (token->location, OPT_Woverflow,
4991 "integer literal exceeds range of %qT type",
4992 long_long_unsigned_type_node);
4993 }
4994 else
4995 {
4996 if (overflow > 0)
4997 warning_at (token->location, OPT_Woverflow,
4998 "floating literal exceeds range of %qT type",
4999 long_double_type_node);
5000 else if (overflow < 0)
5001 warning_at (token->location, OPT_Woverflow,
5002 "floating literal truncated to zero");
5003 }
5004
5005 return result;
5006 }
5007
5008 /* If the numeric argument didn't work, look for a raw literal
5009 operator taking a const char* argument consisting of the number
5010 in string format. */
5011 args->truncate (size: 0);
5012 vec_safe_push (r&: args, t: num_string);
5013 decl = lookup_literal_operator (name, args);
5014 if (decl && decl != error_mark_node)
5015 {
5016 result = finish_call_expr (decl, &args, false, true,
5017 tf_warning_or_error);
5018 return result;
5019 }
5020
5021 /* If the raw literal didn't work, look for a non-type template
5022 function with parameter pack char.... Call the function with
5023 template parameter characters representing the number. */
5024 args->truncate (size: 0);
5025 decl = lookup_literal_operator (name, args);
5026 if (decl && decl != error_mark_node)
5027 {
5028 tree tmpl_args = make_char_string_pack (value: num_string);
5029 if (tmpl_args == NULL_TREE)
5030 {
5031 error ("failed to translate literal to execution character set %qT",
5032 num_string);
5033 return error_mark_node;
5034 }
5035 decl = lookup_template_function (decl, tmpl_args);
5036 result = finish_call_expr (decl, &args, false, true,
5037 tf_warning_or_error);
5038 return result;
5039 }
5040
5041 /* In C++14 the standard library defines complex number suffixes that
5042 conflict with GNU extensions. Prefer them if <complex> is #included. */
5043 bool ext = cpp_get_options (parse_in)->ext_numeric_literals;
5044 bool i14 = (cxx_dialect > cxx11
5045 && (id_equal (id: suffix_id, str: "i")
5046 || id_equal (id: suffix_id, str: "if")
5047 || id_equal (id: suffix_id, str: "il")));
5048 diagnostic_t kind = DK_ERROR;
5049 int opt = 0;
5050
5051 if (i14 && ext)
5052 {
5053 tree cxlit = lookup_qualified_name (std_node, name: "complex_literals",
5054 LOOK_want::NORMAL, false);
5055 if (cxlit == error_mark_node)
5056 {
5057 /* No <complex>, so pedwarn and use GNU semantics. */
5058 kind = DK_PEDWARN;
5059 opt = OPT_Wpedantic;
5060 }
5061 }
5062
5063 bool complained
5064 = emit_diagnostic (kind, input_location, opt,
5065 "unable to find numeric literal operator %qD", name);
5066
5067 if (!complained)
5068 /* Don't inform either. */;
5069 else if (i14)
5070 {
5071 inform (token->location, "add %<using namespace std::complex_literals%> "
5072 "(from %<<complex>%>) to enable the C++14 user-defined literal "
5073 "suffixes");
5074 if (ext)
5075 inform (token->location, "or use %<j%> instead of %<i%> for the "
5076 "GNU built-in suffix");
5077 }
5078 else if (!ext)
5079 inform (token->location, "use %<-fext-numeric-literals%> "
5080 "to enable more built-in suffixes");
5081
5082 if (kind == DK_ERROR)
5083 value = error_mark_node;
5084 else
5085 {
5086 /* Use the built-in semantics. */
5087 tree type;
5088 if (id_equal (id: suffix_id, str: "i"))
5089 {
5090 if (TREE_CODE (value) == INTEGER_CST)
5091 type = integer_type_node;
5092 else
5093 type = double_type_node;
5094 }
5095 else if (id_equal (id: suffix_id, str: "if"))
5096 type = float_type_node;
5097 else /* if (id_equal (suffix_id, "il")) */
5098 type = long_double_type_node;
5099
5100 value = fold_build2 (COMPLEX_EXPR, build_complex_type (type),
5101 build_zero_cst (type), fold_convert (type, value));
5102 }
5103
5104 if (cp_parser_uncommitted_to_tentative_parse_p (parser))
5105 /* Avoid repeated diagnostics. */
5106 token->u.value = value;
5107 return value;
5108}
5109
5110/* Parse a user-defined string constant. Returns a call to a user-defined
5111 literal operator taking a character pointer and the length of the string
5112 as arguments. */
5113
5114static tree
5115finish_userdef_string_literal (tree literal)
5116{
5117 tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
5118 tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
5119 tree value = USERDEF_LITERAL_VALUE (literal);
5120 int len = TREE_STRING_LENGTH (value)
5121 / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
5122 tree decl;
5123
5124 /* Build up a call to the user-defined operator. */
5125 /* Lookup the name we got back from the id-expression. */
5126 releasing_vec args;
5127 vec_safe_push (r&: args, t: value);
5128 vec_safe_push (r&: args, t: build_int_cst (size_type_node, len));
5129 decl = lookup_literal_operator (name, args);
5130
5131 if (decl && decl != error_mark_node)
5132 return finish_call_expr (decl, &args, false, true,
5133 tf_warning_or_error);
5134
5135 /* Look for a suitable template function, either (C++20) with a single
5136 parameter of class type, or (N3599) with typename parameter CharT and
5137 parameter pack CharT... */
5138 args->truncate (size: 0);
5139 decl = lookup_literal_operator (name, args);
5140 if (decl && decl != error_mark_node)
5141 {
5142 /* Use resolve_nondeduced_context to try to choose one form of template
5143 or the other. */
5144 tree tmpl_args = make_tree_vec (1);
5145 TREE_VEC_ELT (tmpl_args, 0) = value;
5146 decl = lookup_template_function (decl, tmpl_args);
5147 tree res = resolve_nondeduced_context (decl, tf_none);
5148 if (DECL_P (res))
5149 decl = res;
5150 else
5151 {
5152 TREE_OPERAND (decl, 1) = make_string_pack (value);
5153 res = resolve_nondeduced_context (decl, tf_none);
5154 if (DECL_P (res))
5155 decl = res;
5156 }
5157 if (!DECL_P (decl) && cxx_dialect > cxx17)
5158 TREE_OPERAND (decl, 1) = tmpl_args;
5159 return finish_call_expr (decl, &args, false, true,
5160 tf_warning_or_error);
5161 }
5162
5163 error ("unable to find string literal operator %qD with %qT, %qT arguments",
5164 name, TREE_TYPE (value), size_type_node);
5165 return error_mark_node;
5166}
5167
5168
5169/* Basic concepts [gram.basic] */
5170
5171/* Parse a translation-unit.
5172
5173 translation-unit:
5174 declaration-seq [opt] */
5175
5176static void
5177cp_parser_translation_unit (cp_parser* parser)
5178{
5179 gcc_checking_assert (!cp_error_declarator);
5180
5181 /* Create the declarator obstack. */
5182 gcc_obstack_init (&declarator_obstack);
5183 /* Create the error declarator. */
5184 cp_error_declarator = make_declarator (kind: cdk_error);
5185 /* Create the empty parameter list. */
5186 no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE,
5187 UNKNOWN_LOCATION);
5188 /* Remember where the base of the declarator obstack lies. */
5189 void *declarator_obstack_base = obstack_next_free (&declarator_obstack);
5190
5191 push_deferring_access_checks (flag_access_control
5192 ? dk_no_deferred : dk_no_check);
5193
5194 module_parse mp_state = MP_NOT_MODULE;
5195 if (modules_p () && !header_module_p ())
5196 mp_state = MP_FIRST;
5197
5198 bool implicit_extern_c = false;
5199
5200 /* Parse until EOF. */
5201 for (;;)
5202 {
5203 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
5204
5205 /* If we're entering or exiting a region that's implicitly
5206 extern "C", modify the lang context appropriately. This is
5207 so horrible. Please die. */
5208 if (implicit_extern_c
5209 != cp_lexer_peek_token (lexer: parser->lexer)->implicit_extern_c)
5210 {
5211 implicit_extern_c = !implicit_extern_c;
5212 if (implicit_extern_c)
5213 push_lang_context (lang_name_c);
5214 else
5215 pop_lang_context ();
5216 }
5217
5218 if (token->type == CPP_EOF)
5219 break;
5220
5221 if (modules_p ())
5222 {
5223 /* Top-level module declarations are ok, and change the
5224 portion of file we're in. Top-level import declarations
5225 are significant for the import portions. */
5226
5227 cp_token *next = token;
5228 bool exporting = token->keyword == RID__EXPORT;
5229 if (exporting)
5230 {
5231 cp_lexer_consume_token (lexer: parser->lexer);
5232 next = cp_lexer_peek_token (lexer: parser->lexer);
5233 }
5234 if (next->keyword == RID__MODULE)
5235 {
5236 mp_state
5237 = cp_parser_module_declaration (parser, mp_state, exporting);
5238 continue;
5239 }
5240 else if (next->keyword == RID__IMPORT)
5241 {
5242 if (mp_state == MP_FIRST)
5243 mp_state = MP_NOT_MODULE;
5244 cp_parser_import_declaration (parser, mp_state, exporting);
5245 continue;
5246 }
5247 else
5248 gcc_checking_assert (!exporting);
5249
5250 if (mp_state == MP_GLOBAL && token->main_source_p)
5251 {
5252 static bool warned = false;
5253 if (!warned)
5254 {
5255 warned = true;
5256 pedwarn (token->location, OPT_Wglobal_module,
5257 "global module fragment contents must be"
5258 " from preprocessor inclusion");
5259 }
5260 }
5261 }
5262
5263 /* This relies on the ordering of module_parse values. */
5264 if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS)
5265 /* We're no longer in the import portion of a named module. */
5266 mp_state = module_parse (mp_state + 1);
5267 else if (mp_state == MP_FIRST)
5268 mp_state = MP_NOT_MODULE;
5269
5270 if (token->type == CPP_CLOSE_BRACE)
5271 {
5272 cp_parser_error (parser, gmsgid: "expected declaration");
5273 cp_lexer_consume_token (lexer: parser->lexer);
5274 /* If the next token is now a `;', consume it. */
5275 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
5276 cp_lexer_consume_token (lexer: parser->lexer);
5277 }
5278 else
5279 cp_parser_toplevel_declaration (parser);
5280 }
5281
5282 /* Get rid of the token array; we don't need it any more. */
5283 cp_lexer_destroy (lexer: parser->lexer);
5284 parser->lexer = NULL;
5285
5286 /* The EOF should have reset this. */
5287 gcc_checking_assert (!implicit_extern_c);
5288
5289 /* Make sure the declarator obstack was fully cleaned up. */
5290 gcc_assert (obstack_next_free (&declarator_obstack)
5291 == declarator_obstack_base);
5292}
5293
5294/* Return the appropriate tsubst flags for parsing, possibly in N3276
5295 decltype context. */
5296
5297static inline tsubst_flags_t
5298complain_flags (bool decltype_p)
5299{
5300 tsubst_flags_t complain = tf_warning_or_error;
5301 if (decltype_p)
5302 complain |= tf_decltype;
5303 return complain;
5304}
5305
5306/* We're about to parse a collection of statements. If we're currently
5307 parsing tentatively, set up a firewall so that any nested
5308 cp_parser_commit_to_tentative_parse won't affect the current context. */
5309
5310static cp_token_position
5311cp_parser_start_tentative_firewall (cp_parser *parser)
5312{
5313 if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
5314 return 0;
5315
5316 cp_parser_parse_tentatively (parser);
5317 cp_parser_commit_to_topmost_tentative_parse (parser);
5318 return cp_lexer_token_position (lexer: parser->lexer, previous_p: false);
5319}
5320
5321/* We've finished parsing the collection of statements. Wrap up the
5322 firewall and replace the relevant tokens with the parsed form. */
5323
5324static void
5325cp_parser_end_tentative_firewall (cp_parser *parser, cp_token_position start,
5326 tree expr)
5327{
5328 if (!start)
5329 return;
5330
5331 /* Finish the firewall level. */
5332 cp_parser_parse_definitely (parser);
5333 /* And remember the result of the parse for when we try again. */
5334 cp_token *token = cp_lexer_token_at (parser->lexer, pos: start);
5335 token->type = CPP_PREPARSED_EXPR;
5336 token->u.value = expr;
5337 token->keyword = RID_MAX;
5338 cp_lexer_purge_tokens_after (lexer: parser->lexer, tok: start);
5339}
5340
5341/* Like the above functions, but let the user modify the tokens. Used by
5342 CPP_DECLTYPE and CPP_TEMPLATE_ID, where we are saving the side-effects for
5343 later parses, so it makes sense to localize the effects of
5344 cp_parser_commit_to_tentative_parse. */
5345
5346struct tentative_firewall
5347{
5348 cp_parser *parser;
5349 bool set;
5350
5351 tentative_firewall (cp_parser *p): parser(p)
5352 {
5353 /* If we're currently parsing tentatively, start a committed level as a
5354 firewall and then an inner tentative parse. */
5355 if ((set = cp_parser_uncommitted_to_tentative_parse_p (parser)))
5356 {
5357 cp_parser_parse_tentatively (parser);
5358 cp_parser_commit_to_topmost_tentative_parse (parser);
5359 cp_parser_parse_tentatively (parser);
5360 }
5361 }
5362
5363 ~tentative_firewall()
5364 {
5365 if (set)
5366 {
5367 /* Finish the inner tentative parse and the firewall, propagating any
5368 uncommitted error state to the outer tentative parse. */
5369 bool err = cp_parser_error_occurred (parser);
5370 cp_parser_parse_definitely (parser);
5371 cp_parser_parse_definitely (parser);
5372 if (err)
5373 cp_parser_simulate_error (parser);
5374 }
5375 }
5376};
5377
5378/* Some tokens naturally come in pairs e.g.'(' and ')'.
5379 This class is for tracking such a matching pair of symbols.
5380 In particular, it tracks the location of the first token,
5381 so that if the second token is missing, we can highlight the
5382 location of the first token when notifying the user about the
5383 problem. */
5384
5385template <typename traits_t>
5386class token_pair
5387{
5388 public:
5389 /* token_pair's ctor. */
5390 token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
5391
5392 /* If the next token is the opening symbol for this pair, consume it and
5393 return true.
5394 Otherwise, issue an error and return false.
5395 In either case, record the location of the opening token. */
5396
5397 bool require_open (cp_parser *parser)
5398 {
5399 m_open_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
5400 return cp_parser_require (parser, traits_t::open_token_type,
5401 traits_t::required_token_open);
5402 }
5403
5404 /* Consume the next token from PARSER, recording its location as
5405 that of the opening token within the pair. */
5406
5407 cp_token * consume_open (cp_parser *parser)
5408 {
5409 cp_token *tok = cp_lexer_consume_token (lexer: parser->lexer);
5410 gcc_assert (tok->type == traits_t::open_token_type);
5411 m_open_loc = tok->location;
5412 return tok;
5413 }
5414
5415 /* If the next token is the closing symbol for this pair, consume it
5416 and return it.
5417 Otherwise, issue an error, highlighting the location of the
5418 corresponding opening token, and return NULL. */
5419
5420 cp_token *require_close (cp_parser *parser) const
5421 {
5422 return cp_parser_require (parser, traits_t::close_token_type,
5423 traits_t::required_token_close,
5424 m_open_loc);
5425 }
5426
5427 location_t open_location () const { return m_open_loc; }
5428
5429 private:
5430 location_t m_open_loc;
5431};
5432
5433/* Traits for token_pair<T> for tracking matching pairs of parentheses. */
5434
5435struct matching_paren_traits
5436{
5437 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
5438 static const enum required_token required_token_open = RT_OPEN_PAREN;
5439 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
5440 static const enum required_token required_token_close = RT_CLOSE_PAREN;
5441};
5442
5443/* "matching_parens" is a token_pair<T> class for tracking matching
5444 pairs of parentheses. */
5445
5446typedef token_pair<matching_paren_traits> matching_parens;
5447
5448/* Traits for token_pair<T> for tracking matching pairs of braces. */
5449
5450struct matching_brace_traits
5451{
5452 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
5453 static const enum required_token required_token_open = RT_OPEN_BRACE;
5454 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
5455 static const enum required_token required_token_close = RT_CLOSE_BRACE;
5456};
5457
5458/* "matching_braces" is a token_pair<T> class for tracking matching
5459 pairs of braces. */
5460
5461typedef token_pair<matching_brace_traits> matching_braces;
5462
5463
5464/* Parse a GNU statement-expression, i.e. ({ stmts }), except for the
5465 enclosing parentheses. */
5466
5467static cp_expr
5468cp_parser_statement_expr (cp_parser *parser)
5469{
5470 cp_token_position start = cp_parser_start_tentative_firewall (parser);
5471 auto oas = make_temp_override (var&: parser->omp_array_section_p, overrider: false);
5472
5473 /* Consume the '('. */
5474 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
5475 matching_parens parens;
5476 parens.consume_open (parser);
5477 /* Start the statement-expression. */
5478 tree expr = begin_stmt_expr ();
5479 /* Parse the compound-statement. */
5480 cp_parser_compound_statement (parser, expr, BCS_STMT_EXPR, false);
5481 /* Finish up. */
5482 expr = finish_stmt_expr (expr, false);
5483 /* Consume the ')'. */
5484 location_t finish_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
5485 if (!parens.require_close (parser))
5486 cp_parser_skip_to_end_of_statement (parser);
5487
5488 cp_parser_end_tentative_firewall (parser, start, expr);
5489 location_t combined_loc = make_location (caret: start_loc, start: start_loc, finish: finish_loc);
5490 return cp_expr (expr, combined_loc);
5491}
5492
5493/* Expressions [gram.expr] */
5494
5495/* Parse a fold-operator.
5496
5497 fold-operator:
5498 - * / % ^ & | = < > << >>
5499 = -= *= /= %= ^= &= |= <<= >>=
5500 == != <= >= && || , .* ->*
5501
5502 This returns the tree code corresponding to the matched operator
5503 as an int. When the current token matches a compound assignment
5504 operator, the resulting tree code is the negative value of the
5505 non-assignment operator. */
5506
5507static int
5508cp_parser_fold_operator (cp_token *token)
5509{
5510 switch (token->type)
5511 {
5512 case CPP_PLUS: return PLUS_EXPR;
5513 case CPP_MINUS: return MINUS_EXPR;
5514 case CPP_MULT: return MULT_EXPR;
5515 case CPP_DIV: return TRUNC_DIV_EXPR;
5516 case CPP_MOD: return TRUNC_MOD_EXPR;
5517 case CPP_XOR: return BIT_XOR_EXPR;
5518 case CPP_AND: return BIT_AND_EXPR;
5519 case CPP_OR: return BIT_IOR_EXPR;
5520 case CPP_LSHIFT: return LSHIFT_EXPR;
5521 case CPP_RSHIFT: return RSHIFT_EXPR;
5522
5523 case CPP_EQ: return -NOP_EXPR;
5524 case CPP_PLUS_EQ: return -PLUS_EXPR;
5525 case CPP_MINUS_EQ: return -MINUS_EXPR;
5526 case CPP_MULT_EQ: return -MULT_EXPR;
5527 case CPP_DIV_EQ: return -TRUNC_DIV_EXPR;
5528 case CPP_MOD_EQ: return -TRUNC_MOD_EXPR;
5529 case CPP_XOR_EQ: return -BIT_XOR_EXPR;
5530 case CPP_AND_EQ: return -BIT_AND_EXPR;
5531 case CPP_OR_EQ: return -BIT_IOR_EXPR;
5532 case CPP_LSHIFT_EQ: return -LSHIFT_EXPR;
5533 case CPP_RSHIFT_EQ: return -RSHIFT_EXPR;
5534
5535 case CPP_EQ_EQ: return EQ_EXPR;
5536 case CPP_NOT_EQ: return NE_EXPR;
5537 case CPP_LESS: return LT_EXPR;
5538 case CPP_GREATER: return GT_EXPR;
5539 case CPP_LESS_EQ: return LE_EXPR;
5540 case CPP_GREATER_EQ: return GE_EXPR;
5541
5542 case CPP_AND_AND: return TRUTH_ANDIF_EXPR;
5543 case CPP_OR_OR: return TRUTH_ORIF_EXPR;
5544
5545 case CPP_COMMA: return COMPOUND_EXPR;
5546
5547 case CPP_DOT_STAR: return DOTSTAR_EXPR;
5548 case CPP_DEREF_STAR: return MEMBER_REF;
5549
5550 default: return ERROR_MARK;
5551 }
5552}
5553
5554/* Returns true if CODE indicates a binary expression, which is not allowed in
5555 the LHS of a fold-expression. More codes will need to be added to use this
5556 function in other contexts. */
5557
5558static bool
5559is_binary_op (tree_code code)
5560{
5561 switch (code)
5562 {
5563 case PLUS_EXPR:
5564 case POINTER_PLUS_EXPR:
5565 case MINUS_EXPR:
5566 case MULT_EXPR:
5567 case TRUNC_DIV_EXPR:
5568 case TRUNC_MOD_EXPR:
5569 case BIT_XOR_EXPR:
5570 case BIT_AND_EXPR:
5571 case BIT_IOR_EXPR:
5572 case LSHIFT_EXPR:
5573 case RSHIFT_EXPR:
5574
5575 case MODOP_EXPR:
5576
5577 case EQ_EXPR:
5578 case NE_EXPR:
5579 case LE_EXPR:
5580 case GE_EXPR:
5581 case LT_EXPR:
5582 case GT_EXPR:
5583
5584 case TRUTH_ANDIF_EXPR:
5585 case TRUTH_ORIF_EXPR:
5586
5587 case COMPOUND_EXPR:
5588
5589 case DOTSTAR_EXPR:
5590 case MEMBER_REF:
5591 return true;
5592
5593 default:
5594 return false;
5595 }
5596}
5597
5598/* If the next token is a suitable fold operator, consume it and return as
5599 the function above. */
5600
5601static int
5602cp_parser_fold_operator (cp_parser *parser)
5603{
5604 cp_token* token = cp_lexer_peek_token (lexer: parser->lexer);
5605 int code = cp_parser_fold_operator (token);
5606 if (code != ERROR_MARK)
5607 cp_lexer_consume_token (lexer: parser->lexer);
5608 return code;
5609}
5610
5611/* Parse a fold-expression.
5612
5613 fold-expression:
5614 ( ... folding-operator cast-expression)
5615 ( cast-expression folding-operator ... )
5616 ( cast-expression folding operator ... folding-operator cast-expression)
5617
5618 Note that the '(' and ')' are matched in primary expression. */
5619
5620static cp_expr
5621cp_parser_fold_expression (cp_parser *parser, tree expr1)
5622{
5623 cp_id_kind pidk;
5624 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
5625 const cp_token *token = nullptr;
5626
5627 // Left fold.
5628 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
5629 {
5630 if (expr1)
5631 return error_mark_node;
5632 cp_lexer_consume_token (lexer: parser->lexer);
5633 token = cp_lexer_peek_token (lexer: parser->lexer);
5634 int op = cp_parser_fold_operator (parser);
5635 if (op == ERROR_MARK)
5636 {
5637 cp_parser_error (parser, gmsgid: "expected binary operator");
5638 return error_mark_node;
5639 }
5640
5641 tree expr = cp_parser_cast_expression (parser, false, false,
5642 false, &pidk);
5643 if (expr == error_mark_node)
5644 return error_mark_node;
5645 loc = make_location (caret: token->location, start: loc, lexer: parser->lexer);
5646 return finish_left_unary_fold_expr (loc, expr, op);
5647 }
5648
5649 token = cp_lexer_peek_token (lexer: parser->lexer);
5650 int op = cp_parser_fold_operator (parser);
5651 if (op == ERROR_MARK)
5652 {
5653 cp_parser_error (parser, gmsgid: "expected binary operator");
5654 return error_mark_node;
5655 }
5656
5657 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_ELLIPSIS))
5658 {
5659 cp_parser_error (parser, gmsgid: "expected ...");
5660 return error_mark_node;
5661 }
5662 cp_lexer_consume_token (lexer: parser->lexer);
5663
5664 /* The operands of a fold-expression are cast-expressions, so binary or
5665 conditional expressions are not allowed. We check this here to avoid
5666 tentative parsing. */
5667 if (EXPR_P (expr1) && warning_suppressed_p (expr1, OPT_Wparentheses))
5668 /* OK, the expression was parenthesized. */;
5669 else if (is_binary_op (TREE_CODE (expr1)))
5670 error_at (location_of (expr1),
5671 "binary expression in operand of fold-expression");
5672 else if (TREE_CODE (expr1) == COND_EXPR
5673 || (REFERENCE_REF_P (expr1)
5674 && TREE_CODE (TREE_OPERAND (expr1, 0)) == COND_EXPR))
5675 error_at (location_of (expr1),
5676 "conditional expression in operand of fold-expression");
5677
5678 // Right fold.
5679 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
5680 {
5681 loc = make_location (caret: token->location, start: loc, lexer: parser->lexer);
5682 return finish_right_unary_fold_expr (loc, expr1, op);
5683 }
5684
5685 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: token->type))
5686 {
5687 cp_parser_error (parser, gmsgid: "mismatched operator in fold-expression");
5688 return error_mark_node;
5689 }
5690 cp_lexer_consume_token (lexer: parser->lexer);
5691
5692 // Binary left or right fold.
5693 tree expr2 = cp_parser_cast_expression (parser, false, false, false, &pidk);
5694 if (expr2 == error_mark_node)
5695 return error_mark_node;
5696 loc = make_location (caret: token->location, start: loc, lexer: parser->lexer);
5697 return finish_binary_fold_expr (loc, expr1, expr2, op);
5698}
5699
5700/* Parse a primary-expression.
5701
5702 primary-expression:
5703 literal
5704 this
5705 ( expression )
5706 id-expression
5707 lambda-expression (C++11)
5708
5709 GNU Extensions:
5710
5711 primary-expression:
5712 ( compound-statement )
5713 __builtin_va_arg ( assignment-expression , type-id )
5714 __builtin_offsetof ( type-id , offsetof-expression )
5715
5716 C++ Extensions:
5717 __has_nothrow_assign ( type-id )
5718 __has_nothrow_constructor ( type-id )
5719 __has_nothrow_copy ( type-id )
5720 __has_trivial_assign ( type-id )
5721 __has_trivial_constructor ( type-id )
5722 __has_trivial_copy ( type-id )
5723 __has_trivial_destructor ( type-id )
5724 __has_virtual_destructor ( type-id )
5725 __is_abstract ( type-id )
5726 __is_base_of ( type-id , type-id )
5727 __is_class ( type-id )
5728 __is_empty ( type-id )
5729 __is_enum ( type-id )
5730 __is_final ( type-id )
5731 __is_literal_type ( type-id )
5732 __is_pod ( type-id )
5733 __is_polymorphic ( type-id )
5734 __is_std_layout ( type-id )
5735 __is_trivial ( type-id )
5736 __is_union ( type-id )
5737
5738 Objective-C++ Extension:
5739
5740 primary-expression:
5741 objc-expression
5742
5743 literal:
5744 __null
5745
5746 ADDRESS_P is true iff this expression was immediately preceded by
5747 "&" and therefore might denote a pointer-to-member. CAST_P is true
5748 iff this expression is the target of a cast. TEMPLATE_ARG_P is
5749 true iff this expression is a template argument.
5750
5751 Returns a representation of the expression. Upon return, *IDK
5752 indicates what kind of id-expression (if any) was present. */
5753
5754static cp_expr
5755cp_parser_primary_expression (cp_parser *parser,
5756 bool address_p,
5757 bool cast_p,
5758 bool template_arg_p,
5759 bool decltype_p,
5760 cp_id_kind *idk)
5761{
5762 cp_token *token = NULL;
5763
5764 /* Assume the primary expression is not an id-expression. */
5765 *idk = CP_ID_KIND_NONE;
5766
5767 /* Peek at the next token. */
5768 token = cp_lexer_peek_token (lexer: parser->lexer);
5769 switch ((int) token->type)
5770 {
5771 /* literal:
5772 integer-literal
5773 character-literal
5774 floating-literal
5775 string-literal
5776 boolean-literal
5777 pointer-literal
5778 user-defined-literal */
5779 case CPP_CHAR:
5780 case CPP_CHAR16:
5781 case CPP_CHAR32:
5782 case CPP_WCHAR:
5783 case CPP_UTF8CHAR:
5784 case CPP_NUMBER:
5785 case CPP_PREPARSED_EXPR:
5786 if (TREE_CODE (token->u.value) == USERDEF_LITERAL)
5787 return cp_parser_userdef_numeric_literal (parser);
5788 token = cp_lexer_consume_token (lexer: parser->lexer);
5789 if (TREE_CODE (token->u.value) == FIXED_CST)
5790 {
5791 error_at (token->location,
5792 "fixed-point types not supported in C++");
5793 return error_mark_node;
5794 }
5795 /* Floating-point literals are only allowed in an integral
5796 constant expression if they are cast to an integral or
5797 enumeration type. */
5798 if ((TREE_CODE (token->u.value) == REAL_CST
5799 || (TREE_CODE (token->u.value) == EXCESS_PRECISION_EXPR
5800 && TREE_CODE (TREE_OPERAND (token->u.value, 0)) == REAL_CST))
5801 && parser->integral_constant_expression_p
5802 && pedantic)
5803 {
5804 /* CAST_P will be set even in invalid code like "int(2.7 +
5805 ...)". Therefore, we have to check that the next token
5806 is sure to end the cast. */
5807 if (cast_p)
5808 {
5809 cp_token *next_token;
5810
5811 next_token = cp_lexer_peek_token (lexer: parser->lexer);
5812 if (/* The comma at the end of an
5813 enumerator-definition. */
5814 next_token->type != CPP_COMMA
5815 /* The curly brace at the end of an enum-specifier. */
5816 && next_token->type != CPP_CLOSE_BRACE
5817 /* The end of a statement. */
5818 && next_token->type != CPP_SEMICOLON
5819 /* The end of the cast-expression. */
5820 && next_token->type != CPP_CLOSE_PAREN
5821 /* The end of an array bound. */
5822 && next_token->type != CPP_CLOSE_SQUARE
5823 /* The closing ">" in a template-argument-list. */
5824 && (next_token->type != CPP_GREATER
5825 || parser->greater_than_is_operator_p)
5826 /* C++0x only: A ">>" treated like two ">" tokens,
5827 in a template-argument-list. */
5828 && (next_token->type != CPP_RSHIFT
5829 || (cxx_dialect == cxx98)
5830 || parser->greater_than_is_operator_p))
5831 cast_p = false;
5832 }
5833
5834 /* If we are within a cast, then the constraint that the
5835 cast is to an integral or enumeration type will be
5836 checked at that point. If we are not within a cast, then
5837 this code is invalid. */
5838 if (!cast_p)
5839 cp_parser_non_integral_constant_expression (parser, thing: NIC_FLOAT);
5840 }
5841 return (cp_expr (token->u.value, token->location, token->flags & DECIMAL_INT)
5842 .maybe_add_location_wrapper ());
5843
5844 case CPP_CHAR_USERDEF:
5845 case CPP_CHAR16_USERDEF:
5846 case CPP_CHAR32_USERDEF:
5847 case CPP_WCHAR_USERDEF:
5848 case CPP_UTF8CHAR_USERDEF:
5849 return cp_parser_userdef_char_literal (parser);
5850
5851 case CPP_STRING:
5852 case CPP_STRING16:
5853 case CPP_STRING32:
5854 case CPP_WSTRING:
5855 case CPP_UTF8STRING:
5856 case CPP_STRING_USERDEF:
5857 case CPP_STRING16_USERDEF:
5858 case CPP_STRING32_USERDEF:
5859 case CPP_WSTRING_USERDEF:
5860 case CPP_UTF8STRING_USERDEF:
5861 /* ??? Should wide strings be allowed when parser->translate_strings_p
5862 is false (i.e. in attributes)? If not, we can kill the third
5863 argument to cp_parser_string_literal. */
5864 if (parser->translate_strings_p)
5865 return (cp_parser_userdef_string_literal (parser,
5866 /*lookup_udlit=*/true)
5867 .maybe_add_location_wrapper ());
5868 else
5869 return (cp_parser_string_literal (parser,
5870 /*translate=*/false,
5871 /*wide_ok=*/true)
5872 .maybe_add_location_wrapper ());
5873
5874 case CPP_OPEN_PAREN:
5875 /* If we see `( { ' then we are looking at the beginning of
5876 a GNU statement-expression. */
5877 if (cp_parser_allow_gnu_extensions_p (parser)
5878 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_BRACE))
5879 {
5880 /* Statement-expressions are not allowed by the standard. */
5881 pedwarn (token->location, OPT_Wpedantic,
5882 "ISO C++ forbids braced-groups within expressions");
5883
5884 /* And they're not allowed outside of a function-body; you
5885 cannot, for example, write:
5886
5887 int i = ({ int j = 3; j + 1; });
5888
5889 at class or namespace scope. */
5890 if (!parser->in_function_body
5891 || parser->in_template_argument_list_p)
5892 {
5893 error_at (token->location,
5894 "statement-expressions are not allowed outside "
5895 "functions nor in template-argument lists");
5896 cp_parser_skip_to_end_of_block_or_statement (parser);
5897 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
5898 cp_lexer_consume_token (lexer: parser->lexer);
5899 return error_mark_node;
5900 }
5901 else
5902 return cp_parser_statement_expr (parser);
5903 }
5904 /* Otherwise it's a normal parenthesized expression. */
5905 {
5906 cp_expr expr;
5907 bool saved_greater_than_is_operator_p;
5908
5909 location_t open_paren_loc = token->location;
5910
5911 /* Consume the `('. */
5912 matching_parens parens;
5913 parens.consume_open (parser);
5914 /* Within a parenthesized expression, a `>' token is always
5915 the greater-than operator. */
5916 saved_greater_than_is_operator_p
5917 = parser->greater_than_is_operator_p;
5918 parser->greater_than_is_operator_p = true;
5919
5920 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
5921 /* Left fold expression. */
5922 expr = NULL_TREE;
5923 else
5924 /* Parse the parenthesized expression. */
5925 expr = cp_parser_expression (parser, idk, cast_p, decltype_p);
5926
5927 token = cp_lexer_peek_token (lexer: parser->lexer);
5928 if (token->type == CPP_ELLIPSIS || cp_parser_fold_operator (token))
5929 {
5930 expr = cp_parser_fold_expression (parser, expr1: expr);
5931 if (expr != error_mark_node
5932 && cxx_dialect < cxx17)
5933 pedwarn (input_location, OPT_Wc__17_extensions,
5934 "fold-expressions only available with %<-std=c++17%> "
5935 "or %<-std=gnu++17%>");
5936 }
5937 else
5938 /* Let the front end know that this expression was
5939 enclosed in parentheses. This matters in case, for
5940 example, the expression is of the form `A::B', since
5941 `&A::B' might be a pointer-to-member, but `&(A::B)' is
5942 not. */
5943 expr = finish_parenthesized_expr (expr);
5944
5945 /* DR 705: Wrapping an unqualified name in parentheses
5946 suppresses arg-dependent lookup. We want to pass back
5947 CP_ID_KIND_QUALIFIED for suppressing vtable lookup
5948 (c++/37862), but none of the others. */
5949 if (*idk != CP_ID_KIND_QUALIFIED)
5950 *idk = CP_ID_KIND_NONE;
5951
5952 /* The `>' token might be the end of a template-id or
5953 template-parameter-list now. */
5954 parser->greater_than_is_operator_p
5955 = saved_greater_than_is_operator_p;
5956
5957 /* Consume the `)'. */
5958 token = cp_lexer_peek_token (lexer: parser->lexer);
5959 location_t close_paren_loc = token->location;
5960 bool no_wparens = warning_suppressed_p (expr, OPT_Wparentheses);
5961 expr.set_range (start: open_paren_loc, finish: close_paren_loc);
5962 if (no_wparens)
5963 suppress_warning (expr, OPT_Wparentheses);
5964 if (!parens.require_close (parser)
5965 && !cp_parser_uncommitted_to_tentative_parse_p (parser))
5966 cp_parser_skip_to_end_of_statement (parser);
5967
5968 return expr;
5969 }
5970
5971 case CPP_OPEN_SQUARE:
5972 {
5973 if (c_dialect_objc ())
5974 {
5975 /* We might have an Objective-C++ message. */
5976 cp_parser_parse_tentatively (parser);
5977 tree msg = cp_parser_objc_message_expression (parser);
5978 /* If that works out, we're done ... */
5979 if (cp_parser_parse_definitely (parser))
5980 return msg;
5981 /* ... else, fall though to see if it's a lambda. */
5982 }
5983 cp_expr lam = cp_parser_lambda_expression (parser);
5984 /* Don't warn about a failed tentative parse. */
5985 if (cp_parser_error_occurred (parser))
5986 return error_mark_node;
5987 maybe_warn_cpp0x (str: CPP0X_LAMBDA_EXPR);
5988 return lam;
5989 }
5990
5991 case CPP_OBJC_STRING:
5992 if (c_dialect_objc ())
5993 /* We have an Objective-C++ string literal. */
5994 return cp_parser_objc_expression (parser);
5995 cp_parser_error (parser, gmsgid: "expected primary-expression");
5996 return error_mark_node;
5997
5998 case CPP_KEYWORD:
5999 switch (token->keyword)
6000 {
6001 /* These two are the boolean literals. */
6002 case RID_TRUE:
6003 cp_lexer_consume_token (lexer: parser->lexer);
6004 return cp_expr (boolean_true_node, token->location);
6005 case RID_FALSE:
6006 cp_lexer_consume_token (lexer: parser->lexer);
6007 return cp_expr (boolean_false_node, token->location);
6008
6009 /* The `__null' literal. */
6010 case RID_NULL:
6011 cp_lexer_consume_token (lexer: parser->lexer);
6012 return cp_expr (null_node, token->location);
6013
6014 /* The `nullptr' literal. */
6015 case RID_NULLPTR:
6016 cp_lexer_consume_token (lexer: parser->lexer);
6017 return cp_expr (nullptr_node, token->location);
6018
6019 /* Recognize the `this' keyword. */
6020 case RID_THIS:
6021 cp_lexer_consume_token (lexer: parser->lexer);
6022 if (parser->local_variables_forbidden_p & THIS_FORBIDDEN)
6023 {
6024 error_at (token->location,
6025 "%<this%> may not be used in this context");
6026 return error_mark_node;
6027 }
6028 /* Pointers cannot appear in constant-expressions. */
6029 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_THIS))
6030 return error_mark_node;
6031 return cp_expr (finish_this_expr (), token->location);
6032
6033 /* The `operator' keyword can be the beginning of an
6034 id-expression. */
6035 case RID_OPERATOR:
6036 goto id_expression;
6037
6038 case RID_FUNCTION_NAME:
6039 case RID_PRETTY_FUNCTION_NAME:
6040 case RID_C99_FUNCTION_NAME:
6041 {
6042 non_integral_constant name;
6043
6044 /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
6045 __func__ are the names of variables -- but they are
6046 treated specially. Therefore, they are handled here,
6047 rather than relying on the generic id-expression logic
6048 below. Grammatically, these names are id-expressions.
6049
6050 Consume the token. */
6051 token = cp_lexer_consume_token (lexer: parser->lexer);
6052
6053 switch (token->keyword)
6054 {
6055 case RID_FUNCTION_NAME:
6056 name = NIC_FUNC_NAME;
6057 break;
6058 case RID_PRETTY_FUNCTION_NAME:
6059 name = NIC_PRETTY_FUNC;
6060 break;
6061 case RID_C99_FUNCTION_NAME:
6062 name = NIC_C99_FUNC;
6063 break;
6064 default:
6065 gcc_unreachable ();
6066 }
6067
6068 if (cp_parser_non_integral_constant_expression (parser, thing: name))
6069 return error_mark_node;
6070
6071 /* Look up the name. */
6072 return finish_fname (token->u.value);
6073 }
6074
6075 case RID_VA_ARG:
6076 {
6077 tree expression;
6078 tree type;
6079 location_t type_location;
6080 location_t start_loc
6081 = cp_lexer_peek_token (lexer: parser->lexer)->location;
6082 /* The `__builtin_va_arg' construct is used to handle
6083 `va_arg'. Consume the `__builtin_va_arg' token. */
6084 cp_lexer_consume_token (lexer: parser->lexer);
6085 /* Look for the opening `('. */
6086 matching_parens parens;
6087 parens.require_open (parser);
6088 /* Now, parse the assignment-expression. */
6089 expression = cp_parser_assignment_expression (parser);
6090 /* Look for the `,'. */
6091 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
6092 type_location = cp_lexer_peek_token (lexer: parser->lexer)->location;
6093 /* Parse the type-id. */
6094 {
6095 type_id_in_expr_sentinel s (parser);
6096 type = cp_parser_type_id (parser);
6097 }
6098 /* Look for the closing `)'. */
6099 location_t finish_loc
6100 = cp_lexer_peek_token (lexer: parser->lexer)->location;
6101 parens.require_close (parser);
6102 /* Using `va_arg' in a constant-expression is not
6103 allowed. */
6104 if (cp_parser_non_integral_constant_expression (parser,
6105 thing: NIC_VA_ARG))
6106 return error_mark_node;
6107 /* Construct a location of the form:
6108 __builtin_va_arg (v, int)
6109 ~~~~~~~~~~~~~~~~~~~~~^~~~
6110 with the caret at the type, ranging from the start of the
6111 "__builtin_va_arg" token to the close paren. */
6112 location_t combined_loc
6113 = make_location (caret: type_location, start: start_loc, finish: finish_loc);
6114 return build_x_va_arg (combined_loc, expression, type);
6115 }
6116
6117 case RID_OFFSETOF:
6118 return cp_parser_builtin_offsetof (parser);
6119
6120 // C++ concepts
6121 case RID_REQUIRES:
6122 return cp_parser_requires_expression (parser);
6123
6124 /* Objective-C++ expressions. */
6125 case RID_AT_ENCODE:
6126 case RID_AT_PROTOCOL:
6127 case RID_AT_SELECTOR:
6128 return cp_parser_objc_expression (parser);
6129
6130 case RID_OMP_ALL_MEMORY:
6131 gcc_assert (flag_openmp);
6132 cp_lexer_consume_token (lexer: parser->lexer);
6133 error_at (token->location,
6134 "%<omp_all_memory%> may only be used in OpenMP "
6135 "%<depend%> clause");
6136 return error_mark_node;
6137
6138 case RID_TEMPLATE:
6139 if (parser->in_function_body
6140 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
6141 == CPP_LESS))
6142 {
6143 error_at (token->location,
6144 "a template declaration cannot appear at block scope");
6145 cp_parser_skip_to_end_of_block_or_statement (parser);
6146 return error_mark_node;
6147 }
6148 /* FALLTHRU */
6149 default:
6150 cp_parser_error (parser, gmsgid: "expected primary-expression");
6151 return error_mark_node;
6152 }
6153
6154 /* An id-expression can start with either an identifier, a
6155 `::' as the beginning of a qualified-id, or the "operator"
6156 keyword. */
6157 case CPP_NAME:
6158 if (const cp_trait* trait = cp_lexer_peek_trait_expr (lexer: parser->lexer))
6159 return cp_parser_trait (parser, trait);
6160 /* FALLTHRU */
6161 case CPP_SCOPE:
6162 case CPP_TEMPLATE_ID:
6163 case CPP_NESTED_NAME_SPECIFIER:
6164 {
6165 id_expression:
6166 cp_expr id_expression;
6167 cp_expr decl;
6168 const char *error_msg;
6169 bool template_p;
6170 bool done;
6171 cp_token *id_expr_token;
6172
6173 /* Parse the id-expression. */
6174 id_expression
6175 = cp_parser_id_expression (parser,
6176 /*template_keyword_p=*/false,
6177 /*check_dependency_p=*/true,
6178 &template_p,
6179 /*declarator_p=*/false,
6180 /*optional_p=*/false);
6181 if (id_expression == error_mark_node)
6182 return error_mark_node;
6183 id_expr_token = token;
6184 token = cp_lexer_peek_token (lexer: parser->lexer);
6185 done = (token->type != CPP_OPEN_SQUARE
6186 && token->type != CPP_OPEN_PAREN
6187 && token->type != CPP_DOT
6188 && token->type != CPP_DEREF
6189 && token->type != CPP_PLUS_PLUS
6190 && token->type != CPP_MINUS_MINUS);
6191 /* If we have a template-id, then no further lookup is
6192 required. If the template-id was for a template-class, we
6193 will sometimes have a TYPE_DECL at this point. */
6194 if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR
6195 || TREE_CODE (id_expression) == TYPE_DECL)
6196 decl = id_expression;
6197 /* Look up the name. */
6198 else
6199 {
6200 tree ambiguous_decls;
6201
6202 /* If we already know that this lookup is ambiguous, then
6203 we've already issued an error message; there's no reason
6204 to check again. */
6205 if (id_expr_token->type == CPP_NAME
6206 && id_expr_token->error_reported)
6207 {
6208 cp_parser_simulate_error (parser);
6209 return error_mark_node;
6210 }
6211
6212 decl = cp_parser_lookup_name (parser, id_expression,
6213 none_type,
6214 template_p,
6215 /*is_namespace=*/false,
6216 /*check_dependency=*/true,
6217 &ambiguous_decls,
6218 id_expression.get_location ());
6219 /* If the lookup was ambiguous, an error will already have
6220 been issued. */
6221 if (ambiguous_decls)
6222 return error_mark_node;
6223
6224 /* In Objective-C++, we may have an Objective-C 2.0
6225 dot-syntax for classes here. */
6226 if (c_dialect_objc ()
6227 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_DOT
6228 && TREE_CODE (decl) == TYPE_DECL
6229 && objc_is_class_name (decl))
6230 {
6231 tree component;
6232 cp_lexer_consume_token (lexer: parser->lexer);
6233 component = cp_parser_identifier (parser);
6234 if (component == error_mark_node)
6235 return error_mark_node;
6236
6237 tree result = objc_build_class_component_ref (id_expression,
6238 component);
6239 /* Build a location of the form:
6240 expr.component
6241 ~~~~~^~~~~~~~~
6242 with caret at the start of the component name (at
6243 input_location), ranging from the start of the id_expression
6244 to the end of the component name. */
6245 location_t combined_loc
6246 = make_location (caret: input_location, start: id_expression.get_start (),
6247 finish: get_finish (loc: input_location));
6248 protected_set_expr_location (result, combined_loc);
6249 return result;
6250 }
6251
6252 /* In Objective-C++, an instance variable (ivar) may be preferred
6253 to whatever cp_parser_lookup_name() found.
6254 Call objc_lookup_ivar. To avoid exposing cp_expr to the
6255 rest of c-family, we have to do a little extra work to preserve
6256 any location information in cp_expr "decl". Given that
6257 objc_lookup_ivar is implemented in "c-family" and "objc", we
6258 have a trip through the pure "tree" type, rather than cp_expr.
6259 Naively copying it back to "decl" would implicitly give the
6260 new cp_expr value an UNKNOWN_LOCATION for nodes that don't
6261 store an EXPR_LOCATION. Hence we only update "decl" (and
6262 hence its location_t) if we get back a different tree node. */
6263 tree decl_tree = objc_lookup_ivar (decl.get_value (),
6264 id_expression);
6265 if (decl_tree != decl.get_value ())
6266 decl = cp_expr (decl_tree);
6267
6268 /* If name lookup gives us a SCOPE_REF, then the
6269 qualifying scope was dependent. */
6270 if (TREE_CODE (decl) == SCOPE_REF)
6271 {
6272 /* At this point, we do not know if DECL is a valid
6273 integral constant expression. We assume that it is
6274 in fact such an expression, so that code like:
6275
6276 template <int N> struct A {
6277 int a[B<N>::i];
6278 };
6279
6280 is accepted. At template-instantiation time, we
6281 will check that B<N>::i is actually a constant. */
6282 return decl;
6283 }
6284 /* Check to see if DECL is a local variable in a context
6285 where that is forbidden. */
6286 if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
6287 && local_variable_p (decl)
6288 /* DR 2082 permits local variables in unevaluated contexts
6289 within a default argument. */
6290 && !cp_unevaluated_operand)
6291 {
6292 const char *msg
6293 = (TREE_CODE (decl) == PARM_DECL
6294 ? G_("parameter %qD may not appear in this context")
6295 : G_("local variable %qD may not appear in this context"));
6296 error_at (id_expression.get_location (), msg,
6297 decl.get_value ());
6298 return error_mark_node;
6299 }
6300 }
6301
6302 decl = (finish_id_expression
6303 (id_expression, decl, parser->scope,
6304 idk,
6305 parser->integral_constant_expression_p,
6306 parser->allow_non_integral_constant_expression_p,
6307 &parser->non_integral_constant_expression_p,
6308 template_p, done, address_p,
6309 template_arg_p,
6310 &error_msg,
6311 id_expression.get_location ()));
6312 if (error_msg)
6313 cp_parser_error (parser, gmsgid: error_msg);
6314 /* Build a location for an id-expression of the form:
6315 ::ns::id
6316 ~~~~~~^~
6317 or:
6318 id
6319 ^~
6320 i.e. from the start of the first token to the end of the final
6321 token, with the caret at the start of the unqualified-id. */
6322 location_t caret_loc = get_pure_location (loc: id_expression.get_location ());
6323 location_t start_loc = get_start (loc: id_expr_token->location);
6324 location_t finish_loc = get_finish (loc: id_expression.get_location ());
6325 location_t combined_loc
6326 = make_location (caret: caret_loc, start: start_loc, finish: finish_loc);
6327
6328 decl.set_location (combined_loc);
6329 return decl;
6330 }
6331
6332 /* Anything else is an error. */
6333 default:
6334 cp_parser_error (parser, gmsgid: "expected primary-expression");
6335 return error_mark_node;
6336 }
6337}
6338
6339static inline cp_expr
6340cp_parser_primary_expression (cp_parser *parser,
6341 bool address_p,
6342 bool cast_p,
6343 bool template_arg_p,
6344 cp_id_kind *idk)
6345{
6346 return cp_parser_primary_expression (parser, address_p, cast_p, template_arg_p,
6347 /*decltype*/decltype_p: false, idk);
6348}
6349
6350/* Complain about missing template keyword when naming a dependent
6351 member template. */
6352
6353static void
6354missing_template_diag (location_t loc, diagnostic_t diag_kind = DK_WARNING)
6355{
6356 if (warning_suppressed_at (loc, OPT_Wmissing_template_keyword))
6357 return;
6358
6359 gcc_rich_location richloc (loc);
6360 richloc.add_fixit_insert_before (new_content: "template");
6361 emit_diagnostic (diag_kind, &richloc, OPT_Wmissing_template_keyword,
6362 "expected %qs keyword before dependent "
6363 "template name", "template");
6364 suppress_warning_at (loc, OPT_Wmissing_template_keyword);
6365}
6366
6367/* Parse an id-expression.
6368
6369 id-expression:
6370 unqualified-id
6371 qualified-id
6372
6373 qualified-id:
6374 :: [opt] nested-name-specifier template [opt] unqualified-id
6375 :: identifier
6376 :: operator-function-id
6377 :: template-id
6378
6379 Return a representation of the unqualified portion of the
6380 identifier. Sets PARSER->SCOPE to the qualifying scope if there is
6381 a `::' or nested-name-specifier.
6382
6383 Often, if the id-expression was a qualified-id, the caller will
6384 want to make a SCOPE_REF to represent the qualified-id. This
6385 function does not do this in order to avoid wastefully creating
6386 SCOPE_REFs when they are not required.
6387
6388 If TEMPLATE_KEYWORD_P is true, then we have just seen the
6389 `template' keyword.
6390
6391 If CHECK_DEPENDENCY_P is false, then names are looked up inside
6392 uninstantiated templates.
6393
6394 If *TEMPLATE_P is non-NULL, it is set to true iff the
6395 `template' keyword is used to explicitly indicate that the entity
6396 named is a template.
6397
6398 If DECLARATOR_P is true, the id-expression is appearing as part of
6399 a declarator, rather than as part of an expression. */
6400
6401static cp_expr
6402cp_parser_id_expression (cp_parser *parser,
6403 bool template_keyword_p,
6404 bool check_dependency_p,
6405 bool *template_p,
6406 bool declarator_p,
6407 bool optional_p)
6408{
6409 bool global_scope_p;
6410 bool nested_name_specifier_p;
6411
6412 /* Assume the `template' keyword was not used. */
6413 if (template_p)
6414 *template_p = template_keyword_p;
6415
6416 /* Look for the optional `::' operator. */
6417 global_scope_p
6418 = (!template_keyword_p
6419 && (cp_parser_global_scope_opt (parser,
6420 /*current_scope_valid_p=*/false)
6421 != NULL_TREE));
6422
6423 /* Look for the optional nested-name-specifier. */
6424 nested_name_specifier_p
6425 = (cp_parser_nested_name_specifier_opt (parser,
6426 /*typename_keyword_p=*/false,
6427 check_dependency_p,
6428 /*type_p=*/false,
6429 declarator_p,
6430 template_keyword_p)
6431 != NULL_TREE);
6432
6433 cp_expr id = NULL_TREE;
6434 tree scope = parser->scope;
6435
6436 /* Peek at the next token. */
6437 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
6438
6439 /* If there is a nested-name-specifier, then we are looking at
6440 the first qualified-id production. */
6441 if (nested_name_specifier_p)
6442 {
6443 tree saved_object_scope;
6444 tree saved_qualifying_scope;
6445
6446 /* See if the next token is the `template' keyword. */
6447 if (!template_p)
6448 template_p = &template_keyword_p;
6449 *template_p = cp_parser_optional_template_keyword (parser);
6450 /* Name lookup we do during the processing of the
6451 unqualified-id might obliterate SCOPE. */
6452 saved_object_scope = parser->object_scope;
6453 saved_qualifying_scope = parser->qualifying_scope;
6454 /* Process the final unqualified-id. */
6455 id = cp_parser_unqualified_id (parser, *template_p,
6456 check_dependency_p,
6457 declarator_p,
6458 /*optional_p=*/false);
6459 /* Restore the SAVED_SCOPE for our caller. */
6460 parser->scope = scope;
6461 parser->object_scope = saved_object_scope;
6462 parser->qualifying_scope = saved_qualifying_scope;
6463 }
6464 /* Otherwise, if we are in global scope, then we are looking at one
6465 of the other qualified-id productions. */
6466 else if (global_scope_p)
6467 {
6468 /* If it's an identifier, and the next token is not a "<", then
6469 we can avoid the template-id case. This is an optimization
6470 for this common case. */
6471 if (token->type == CPP_NAME
6472 && !cp_parser_nth_token_starts_template_argument_list_p
6473 (parser, 2))
6474 return cp_parser_identifier (parser);
6475
6476 cp_parser_parse_tentatively (parser);
6477 /* Try a template-id. */
6478 id = cp_parser_template_id_expr (parser,
6479 /*template_keyword_p=*/false,
6480 /*check_dependency_p=*/true,
6481 declarator_p);
6482 /* If that worked, we're done. */
6483 if (cp_parser_parse_definitely (parser))
6484 return id;
6485
6486 /* Peek at the next token. (Changes in the token buffer may
6487 have invalidated the pointer obtained above.) */
6488 token = cp_lexer_peek_token (lexer: parser->lexer);
6489
6490 switch (token->type)
6491 {
6492 case CPP_NAME:
6493 id = cp_parser_identifier (parser);
6494 break;
6495
6496 case CPP_KEYWORD:
6497 if (token->keyword == RID_OPERATOR)
6498 {
6499 id = cp_parser_operator_function_id (parser);
6500 break;
6501 }
6502 /* Fall through. */
6503
6504 default:
6505 cp_parser_error (parser, gmsgid: "expected id-expression");
6506 return error_mark_node;
6507 }
6508 }
6509 else
6510 {
6511 if (!scope)
6512 scope = parser->context->object_type;
6513 id = cp_parser_unqualified_id (parser, template_keyword_p,
6514 /*check_dependency_p=*/true,
6515 declarator_p,
6516 optional_p);
6517 }
6518
6519 if (id && TREE_CODE (id) == IDENTIFIER_NODE
6520 && warn_missing_template_keyword
6521 && !template_keyword_p
6522 /* Don't warn if we're looking inside templates. */
6523 && check_dependency_p
6524 /* In a template argument list a > could be closing
6525 the enclosing targs. */
6526 && !parser->in_template_argument_list_p
6527 && scope && dependentish_scope_p (scope)
6528 /* Don't confuse an ill-formed constructor declarator for a missing
6529 template keyword in a return type. */
6530 && !(declarator_p && constructor_name_p (id, scope))
6531 && cp_parser_nth_token_starts_template_argument_list_p (parser, 1)
6532 && warning_enabled_at (loc: token->location,
6533 opt: OPT_Wmissing_template_keyword))
6534 {
6535 saved_token_sentinel toks (parser->lexer, STS_ROLLBACK);
6536 if (cp_parser_skip_entire_template_parameter_list (parser)
6537 /* An operator after the > suggests that the > ends a
6538 template-id; a name or literal suggests that the > is an
6539 operator. */
6540 && (cp_lexer_peek_token (lexer: parser->lexer)->type
6541 <= CPP_LAST_PUNCTUATOR))
6542 missing_template_diag (loc: token->location);
6543 }
6544
6545 return id;
6546}
6547
6548/* Parse an unqualified-id.
6549
6550 unqualified-id:
6551 identifier
6552 operator-function-id
6553 conversion-function-id
6554 ~ class-name
6555 template-id
6556
6557 If TEMPLATE_KEYWORD_P is TRUE, we have just seen the `template'
6558 keyword, in a construct like `A::template ...'.
6559
6560 Returns a representation of unqualified-id. For the `identifier'
6561 production, an IDENTIFIER_NODE is returned. For the `~ class-name'
6562 production a BIT_NOT_EXPR is returned; the operand of the
6563 BIT_NOT_EXPR is an IDENTIFIER_NODE for the class-name. For the
6564 other productions, see the documentation accompanying the
6565 corresponding parsing functions. If CHECK_DEPENDENCY_P is false,
6566 names are looked up in uninstantiated templates. If DECLARATOR_P
6567 is true, the unqualified-id is appearing as part of a declarator,
6568 rather than as part of an expression. */
6569
6570static cp_expr
6571cp_parser_unqualified_id (cp_parser* parser,
6572 bool template_keyword_p,
6573 bool check_dependency_p,
6574 bool declarator_p,
6575 bool optional_p)
6576{
6577 cp_token *token;
6578
6579 /* Peek at the next token. */
6580 token = cp_lexer_peek_token (lexer: parser->lexer);
6581
6582 switch ((int) token->type)
6583 {
6584 case CPP_NAME:
6585 {
6586 tree id;
6587
6588 /* We don't know yet whether or not this will be a
6589 template-id. */
6590 cp_parser_parse_tentatively (parser);
6591 /* Try a template-id. */
6592 id = cp_parser_template_id_expr (parser, template_keyword_p,
6593 check_dependency_p,
6594 declarator_p);
6595 /* If it worked, we're done. */
6596 if (cp_parser_parse_definitely (parser))
6597 return id;
6598 /* Otherwise, it's an ordinary identifier. */
6599 return cp_parser_identifier (parser);
6600 }
6601
6602 case CPP_TEMPLATE_ID:
6603 return cp_parser_template_id_expr (parser, template_keyword_p,
6604 check_dependency_p,
6605 declarator_p);
6606
6607 case CPP_COMPL:
6608 {
6609 tree type_decl;
6610 tree qualifying_scope;
6611 tree object_scope;
6612 tree scope;
6613 bool done;
6614 location_t tilde_loc = token->location;
6615
6616 /* Consume the `~' token. */
6617 cp_lexer_consume_token (lexer: parser->lexer);
6618 /* Parse the class-name. The standard, as written, seems to
6619 say that:
6620
6621 template <typename T> struct S { ~S (); };
6622 template <typename T> S<T>::~S() {}
6623
6624 is invalid, since `~' must be followed by a class-name, but
6625 `S<T>' is dependent, and so not known to be a class.
6626 That's not right; we need to look in uninstantiated
6627 templates. A further complication arises from:
6628
6629 template <typename T> void f(T t) {
6630 t.T::~T();
6631 }
6632
6633 Here, it is not possible to look up `T' in the scope of `T'
6634 itself. We must look in both the current scope, and the
6635 scope of the containing complete expression.
6636
6637 Yet another issue is:
6638
6639 struct S {
6640 int S;
6641 ~S();
6642 };
6643
6644 S::~S() {}
6645
6646 The standard does not seem to say that the `S' in `~S'
6647 should refer to the type `S' and not the data member
6648 `S::S'. */
6649
6650 /* DR 244 says that we look up the name after the "~" in the
6651 same scope as we looked up the qualifying name. That idea
6652 isn't fully worked out; it's more complicated than that. */
6653 scope = parser->scope;
6654 object_scope = parser->object_scope;
6655 qualifying_scope = parser->qualifying_scope;
6656
6657 /* Check for invalid scopes. */
6658 if (scope == error_mark_node)
6659 {
6660 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
6661 cp_lexer_consume_token (lexer: parser->lexer);
6662 return error_mark_node;
6663 }
6664 if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
6665 {
6666 if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
6667 error_at (token->location,
6668 "scope %qT before %<~%> is not a class-name",
6669 scope);
6670 cp_parser_simulate_error (parser);
6671 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
6672 cp_lexer_consume_token (lexer: parser->lexer);
6673 return error_mark_node;
6674 }
6675 if (template_keyword_p)
6676 {
6677 if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
6678 error_at (tilde_loc, "%<template%> keyword not permitted in "
6679 "destructor name");
6680 cp_parser_simulate_error (parser);
6681 return error_mark_node;
6682 }
6683
6684 gcc_assert (!scope || TYPE_P (scope));
6685
6686 token = cp_lexer_peek_token (lexer: parser->lexer);
6687
6688 /* Create a location with caret == start at the tilde,
6689 finishing at the end of the peeked token, e.g:
6690 ~token
6691 ^~~~~~. */
6692 location_t loc
6693 = make_location (caret: tilde_loc, start: tilde_loc, finish: token->location);
6694
6695 /* If the name is of the form "X::~X" it's OK even if X is a
6696 typedef. */
6697
6698 if (scope
6699 && token->type == CPP_NAME
6700 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
6701 != CPP_LESS)
6702 && (token->u.value == TYPE_IDENTIFIER (scope)
6703 || (CLASS_TYPE_P (scope)
6704 && constructor_name_p (token->u.value, scope))))
6705 {
6706 cp_lexer_consume_token (lexer: parser->lexer);
6707 return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
6708 }
6709
6710 /* ~auto means the destructor of whatever the object is. */
6711 if (cp_parser_is_keyword (token, keyword: RID_AUTO))
6712 {
6713 if (cxx_dialect < cxx14)
6714 pedwarn (loc, OPT_Wc__14_extensions,
6715 "%<~auto%> only available with "
6716 "%<-std=c++14%> or %<-std=gnu++14%>");
6717 cp_lexer_consume_token (lexer: parser->lexer);
6718 return build_min_nt_loc (loc, BIT_NOT_EXPR, make_auto ());
6719 }
6720
6721 /* DR 2237 (C++20 only): A simple-template-id is no longer valid as the
6722 declarator-id of a constructor or destructor. */
6723 if (token->type == CPP_TEMPLATE_ID && declarator_p)
6724 {
6725 auto_diagnostic_group d;
6726 bool w = false;
6727 if (cxx_dialect >= cxx20 && !cp_parser_simulate_error (parser))
6728 w = pedwarn (tilde_loc, OPT_Wtemplate_id_cdtor,
6729 "template-id not allowed for destructor in C++20");
6730 else if (cxx_dialect < cxx20
6731 && !cp_parser_uncommitted_to_tentative_parse_p (parser))
6732 w = warning_at (tilde_loc, OPT_Wtemplate_id_cdtor,
6733 "template-id not allowed for destructor in C++20");
6734 if (w)
6735 inform (tilde_loc, "remove the %qs", "< >");
6736 }
6737
6738 /* If there was an explicit qualification (S::~T), first look
6739 in the scope given by the qualification (i.e., S).
6740
6741 Note: in the calls to cp_parser_class_name below we pass
6742 typename_type so that lookup finds the injected-class-name
6743 rather than the constructor. */
6744 done = false;
6745 type_decl = NULL_TREE;
6746 if (scope)
6747 {
6748 cp_parser_parse_tentatively (parser);
6749 type_decl = cp_parser_class_name (parser,
6750 /*typename_keyword_p=*/false,
6751 /*template_keyword_p=*/false,
6752 typename_type,
6753 /*check_dependency=*/false,
6754 /*class_head_p=*/false,
6755 declarator_p);
6756 if (cp_parser_parse_definitely (parser))
6757 done = true;
6758 }
6759 /* In "N::S::~S", look in "N" as well. */
6760 if (!done && scope && qualifying_scope)
6761 {
6762 cp_parser_parse_tentatively (parser);
6763 parser->scope = qualifying_scope;
6764 parser->object_scope = NULL_TREE;
6765 parser->qualifying_scope = NULL_TREE;
6766 type_decl
6767 = cp_parser_class_name (parser,
6768 /*typename_keyword_p=*/false,
6769 /*template_keyword_p=*/false,
6770 typename_type,
6771 /*check_dependency=*/false,
6772 /*class_head_p=*/false,
6773 declarator_p);
6774 if (cp_parser_parse_definitely (parser))
6775 done = true;
6776 }
6777 /* In "p->S::~T", look in the scope given by "*p" as well. */
6778 else if (!done && object_scope)
6779 {
6780 cp_parser_parse_tentatively (parser);
6781 parser->scope = object_scope;
6782 parser->object_scope = NULL_TREE;
6783 parser->qualifying_scope = NULL_TREE;
6784 type_decl
6785 = cp_parser_class_name (parser,
6786 /*typename_keyword_p=*/false,
6787 /*template_keyword_p=*/false,
6788 typename_type,
6789 /*check_dependency=*/false,
6790 /*class_head_p=*/false,
6791 declarator_p);
6792 if (cp_parser_parse_definitely (parser))
6793 done = true;
6794 }
6795 /* Look in the surrounding context. */
6796 if (!done)
6797 {
6798 parser->scope = NULL_TREE;
6799 parser->object_scope = NULL_TREE;
6800 parser->qualifying_scope = NULL_TREE;
6801 if (processing_template_decl)
6802 cp_parser_parse_tentatively (parser);
6803 type_decl
6804 = cp_parser_class_name (parser,
6805 /*typename_keyword_p=*/false,
6806 /*template_keyword_p=*/false,
6807 typename_type,
6808 /*check_dependency=*/false,
6809 /*class_head_p=*/false,
6810 declarator_p);
6811 if (processing_template_decl
6812 && ! cp_parser_parse_definitely (parser))
6813 {
6814 /* We couldn't find a type with this name. If we're parsing
6815 tentatively, fail and try something else. */
6816 if (cp_parser_uncommitted_to_tentative_parse_p (parser))
6817 {
6818 cp_parser_simulate_error (parser);
6819 return error_mark_node;
6820 }
6821 /* Otherwise, accept it and check for a match at instantiation
6822 time. */
6823 type_decl = cp_parser_identifier (parser);
6824 if (type_decl != error_mark_node)
6825 type_decl = build_min_nt_loc (loc, BIT_NOT_EXPR, type_decl);
6826 return type_decl;
6827 }
6828 }
6829 /* If an error occurred, assume that the name of the
6830 destructor is the same as the name of the qualifying
6831 class. That allows us to keep parsing after running
6832 into ill-formed destructor names. */
6833 if (type_decl == error_mark_node && scope)
6834 return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
6835 else if (type_decl == error_mark_node)
6836 return error_mark_node;
6837
6838 /* Check that destructor name and scope match. */
6839 if (declarator_p && scope && !check_dtor_name (scope, type_decl))
6840 {
6841 if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
6842 error_at (loc,
6843 "declaration of %<~%T%> as member of %qT",
6844 type_decl, scope);
6845 cp_parser_simulate_error (parser);
6846 return error_mark_node;
6847 }
6848
6849 /* [class.dtor]
6850
6851 A typedef-name that names a class shall not be used as the
6852 identifier in the declarator for a destructor declaration. */
6853 if (declarator_p
6854 && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
6855 && !DECL_SELF_REFERENCE_P (type_decl)
6856 && !cp_parser_uncommitted_to_tentative_parse_p (parser))
6857 error_at (loc,
6858 "typedef-name %qD used as destructor declarator",
6859 type_decl);
6860
6861 return build_min_nt_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type_decl));
6862 }
6863
6864 case CPP_KEYWORD:
6865 if (token->keyword == RID_OPERATOR)
6866 {
6867 cp_expr id;
6868
6869 /* This could be a template-id, so we try that first. */
6870 cp_parser_parse_tentatively (parser);
6871 /* Try a template-id. */
6872 id = cp_parser_template_id_expr (parser, template_keyword_p,
6873 /*check_dependency_p=*/true,
6874 declarator_p);
6875 /* If that worked, we're done. */
6876 if (cp_parser_parse_definitely (parser))
6877 return id;
6878 /* We still don't know whether we're looking at an
6879 operator-function-id or a conversion-function-id. */
6880 cp_parser_parse_tentatively (parser);
6881 /* Try an operator-function-id. */
6882 id = cp_parser_operator_function_id (parser);
6883 /* If that didn't work, try a conversion-function-id. */
6884 if (!cp_parser_parse_definitely (parser))
6885 id = cp_parser_conversion_function_id (parser);
6886
6887 return id;
6888 }
6889 /* Fall through. */
6890
6891 default:
6892 if (optional_p)
6893 return NULL_TREE;
6894 cp_parser_error (parser, gmsgid: "expected unqualified-id");
6895 return error_mark_node;
6896 }
6897}
6898
6899/* Check [temp.names]/5: A name prefixed by the keyword template shall
6900 be a template-id or the name shall refer to a class template or an
6901 alias template. */
6902
6903static void
6904check_template_keyword_in_nested_name_spec (tree name)
6905{
6906 if (CLASS_TYPE_P (name)
6907 && ((CLASSTYPE_USE_TEMPLATE (name)
6908 && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (name)))
6909 || CLASSTYPE_IS_TEMPLATE (name)))
6910 return;
6911
6912 if (TREE_CODE (name) == TYPENAME_TYPE
6913 && TREE_CODE (TYPENAME_TYPE_FULLNAME (name)) == TEMPLATE_ID_EXPR)
6914 return;
6915 /* Alias templates are also OK. */
6916 else if (alias_template_specialization_p (name, nt_opaque))
6917 return;
6918
6919 permerror (input_location, TYPE_P (name)
6920 ? G_("%qT is not a template")
6921 : G_("%qD is not a template"),
6922 name);
6923}
6924
6925/* Parse an (optional) nested-name-specifier.
6926
6927 nested-name-specifier: [C++98]
6928 class-or-namespace-name :: nested-name-specifier [opt]
6929 class-or-namespace-name :: template nested-name-specifier [opt]
6930
6931 nested-name-specifier: [C++0x]
6932 type-name ::
6933 namespace-name ::
6934 nested-name-specifier identifier ::
6935 nested-name-specifier template [opt] simple-template-id ::
6936
6937 PARSER->SCOPE should be set appropriately before this function is
6938 called. TYPENAME_KEYWORD_P is TRUE if the `typename' keyword is in
6939 effect. TYPE_P is TRUE if we non-type bindings should be ignored
6940 in name lookups.
6941
6942 Sets PARSER->SCOPE to the class (TYPE) or namespace
6943 (NAMESPACE_DECL) specified by the nested-name-specifier, or leaves
6944 it unchanged if there is no nested-name-specifier. Returns the new
6945 scope iff there is a nested-name-specifier, or NULL_TREE otherwise.
6946
6947 If CHECK_DEPENDENCY_P is FALSE, names are looked up in dependent scopes.
6948
6949 If IS_DECLARATION is TRUE, the nested-name-specifier is known to be
6950 part of a declaration and/or decl-specifier. */
6951
6952static tree
6953cp_parser_nested_name_specifier_opt (cp_parser *parser,
6954 bool typename_keyword_p,
6955 bool check_dependency_p,
6956 bool type_p,
6957 bool is_declaration,
6958 bool template_keyword_p /* = false */)
6959{
6960 bool success = false;
6961 cp_token_position start = 0;
6962 cp_token *token;
6963
6964 /* Remember where the nested-name-specifier starts. */
6965 if (cp_parser_uncommitted_to_tentative_parse_p (parser)
6966 && cp_lexer_next_token_is_not (lexer: parser->lexer, CPP_NESTED_NAME_SPECIFIER))
6967 {
6968 start = cp_lexer_token_position (lexer: parser->lexer, previous_p: false);
6969 push_deferring_access_checks (dk_deferred);
6970 }
6971
6972 while (true)
6973 {
6974 tree new_scope;
6975 tree old_scope;
6976 tree saved_qualifying_scope;
6977
6978 /* Spot cases that cannot be the beginning of a
6979 nested-name-specifier. */
6980 token = cp_lexer_peek_token (lexer: parser->lexer);
6981
6982 /* If the next token is CPP_NESTED_NAME_SPECIFIER, just process
6983 the already parsed nested-name-specifier. */
6984 if (token->type == CPP_NESTED_NAME_SPECIFIER)
6985 {
6986 /* Grab the nested-name-specifier and continue the loop. */
6987 cp_parser_pre_parsed_nested_name_specifier (parser);
6988 /* If we originally encountered this nested-name-specifier
6989 with CHECK_DEPENDENCY_P set to true, we will not have
6990 resolved TYPENAME_TYPEs, so we must do so here. */
6991 if (is_declaration
6992 && !check_dependency_p
6993 && TREE_CODE (parser->scope) == TYPENAME_TYPE)
6994 {
6995 new_scope = resolve_typename_type (parser->scope,
6996 /*only_current_p=*/false);
6997 if (TREE_CODE (new_scope) != TYPENAME_TYPE)
6998 parser->scope = new_scope;
6999 }
7000 success = true;
7001 continue;
7002 }
7003
7004 /* Spot cases that cannot be the beginning of a
7005 nested-name-specifier. On the second and subsequent times
7006 through the loop, we look for the `template' keyword. */
7007 if (success && token->keyword == RID_TEMPLATE)
7008 ;
7009 /* A template-id can start a nested-name-specifier. */
7010 else if (token->type == CPP_TEMPLATE_ID)
7011 ;
7012 /* DR 743: decltype can be used in a nested-name-specifier. */
7013 else if (token_is_decltype (t: token))
7014 ;
7015 else
7016 {
7017 /* If the next token is not an identifier, then it is
7018 definitely not a type-name or namespace-name. */
7019 if (token->type != CPP_NAME)
7020 break;
7021 /* If the following token is neither a `<' (to begin a
7022 template-id), nor a `::', then we are not looking at a
7023 nested-name-specifier. */
7024 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
7025
7026 if (token->type == CPP_COLON
7027 && parser->colon_corrects_to_scope_p
7028 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type == CPP_NAME
7029 /* name:name is a valid sequence in an Objective C message. */
7030 && !parser->objective_c_message_context_p)
7031 {
7032 gcc_rich_location richloc (token->location);
7033 richloc.add_fixit_replace (new_content: "::");
7034 error_at (&richloc,
7035 "found %<:%> in nested-name-specifier, "
7036 "expected %<::%>");
7037 token->type = CPP_SCOPE;
7038 }
7039
7040 if (token->type != CPP_SCOPE
7041 && !cp_parser_nth_token_starts_template_argument_list_p
7042 (parser, 2))
7043 break;
7044 }
7045
7046 /* The nested-name-specifier is optional, so we parse
7047 tentatively. */
7048 cp_parser_parse_tentatively (parser);
7049
7050 /* Look for the optional `template' keyword, if this isn't the
7051 first time through the loop. */
7052 if (success)
7053 {
7054 template_keyword_p = cp_parser_optional_template_keyword (parser);
7055 /* DR1710: "In a qualified-id used as the name in
7056 a typename-specifier, elaborated-type-specifier, using-declaration,
7057 or class-or-decltype, an optional keyword template appearing at
7058 the top level is ignored." */
7059 if (!template_keyword_p
7060 && typename_keyword_p
7061 && cp_parser_nth_token_starts_template_argument_list_p (parser, 2))
7062 template_keyword_p = true;
7063 }
7064
7065 /* Save the old scope since the name lookup we are about to do
7066 might destroy it. */
7067 old_scope = parser->scope;
7068 saved_qualifying_scope = parser->qualifying_scope;
7069 /* In a declarator-id like "X<T>::I::Y<T>" we must be able to
7070 look up names in "X<T>::I" in order to determine that "Y" is
7071 a template. So, if we have a typename at this point, we make
7072 an effort to look through it. */
7073 if (is_declaration
7074 && !check_dependency_p
7075 && !typename_keyword_p
7076 && parser->scope
7077 && TREE_CODE (parser->scope) == TYPENAME_TYPE)
7078 parser->scope = resolve_typename_type (parser->scope,
7079 /*only_current_p=*/false);
7080 /* Parse the qualifying entity. */
7081 new_scope
7082 = cp_parser_qualifying_entity (parser,
7083 typename_keyword_p,
7084 template_keyword_p,
7085 check_dependency_p,
7086 type_p,
7087 is_declaration);
7088 /* Look for the `::' token. */
7089 cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
7090
7091 /* If we found what we wanted, we keep going; otherwise, we're
7092 done. */
7093 if (!cp_parser_parse_definitely (parser))
7094 {
7095 bool error_p = false;
7096
7097 /* Restore the OLD_SCOPE since it was valid before the
7098 failed attempt at finding the last
7099 class-or-namespace-name. */
7100 parser->scope = old_scope;
7101 parser->qualifying_scope = saved_qualifying_scope;
7102
7103 /* If the next token is a decltype, and the one after that is a
7104 `::', then the decltype has failed to resolve to a class or
7105 enumeration type. Give this error even when parsing
7106 tentatively since it can't possibly be valid--and we're going
7107 to replace it with a CPP_NESTED_NAME_SPECIFIER below, so we
7108 won't get another chance.*/
7109 if (cp_lexer_next_token_is (lexer: parser->lexer, CPP_DECLTYPE)
7110 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
7111 == CPP_SCOPE))
7112 {
7113 token = cp_lexer_consume_token (lexer: parser->lexer);
7114 tree dtype = token->u.tree_check_value->value;
7115 if (dtype != error_mark_node)
7116 error_at (token->location, "%<decltype%> evaluates to %qT, "
7117 "which is not a class or enumeration type",
7118 dtype);
7119 parser->scope = error_mark_node;
7120 error_p = true;
7121 /* As below. */
7122 success = true;
7123 cp_lexer_consume_token (lexer: parser->lexer);
7124 }
7125
7126 if (cp_lexer_next_token_is (lexer: parser->lexer, CPP_TEMPLATE_ID)
7127 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_SCOPE))
7128 {
7129 /* If we have a non-type template-id followed by ::, it can't
7130 possibly be valid. */
7131 token = cp_lexer_peek_token (lexer: parser->lexer);
7132 tree tid = token->u.tree_check_value->value;
7133 if (TREE_CODE (tid) == TEMPLATE_ID_EXPR
7134 && TREE_CODE (TREE_OPERAND (tid, 0)) != IDENTIFIER_NODE)
7135 {
7136 tree tmpl = NULL_TREE;
7137 if (is_overloaded_fn (tid))
7138 {
7139 tree fns = get_fns (tid);
7140 if (OVL_SINGLE_P (fns))
7141 tmpl = OVL_FIRST (fns);
7142 if (function_concept_p (t: fns))
7143 error_at (token->location, "concept-id %qD "
7144 "in nested-name-specifier", tid);
7145 else
7146 error_at (token->location, "function template-id "
7147 "%qD in nested-name-specifier", tid);
7148 }
7149 else
7150 {
7151 tmpl = TREE_OPERAND (tid, 0);
7152 if (variable_concept_p (t: tmpl)
7153 || standard_concept_p (t: tmpl))
7154 error_at (token->location, "concept-id %qD "
7155 "in nested-name-specifier", tid);
7156 else
7157 {
7158 /* Variable template. */
7159 gcc_assert (variable_template_p (tmpl));
7160 error_at (token->location, "variable template-id "
7161 "%qD in nested-name-specifier", tid);
7162 }
7163 }
7164 if (tmpl)
7165 inform (DECL_SOURCE_LOCATION (tmpl),
7166 "%qD declared here", tmpl);
7167
7168 parser->scope = error_mark_node;
7169 error_p = true;
7170 /* As below. */
7171 success = true;
7172 cp_lexer_consume_token (lexer: parser->lexer);
7173 cp_lexer_consume_token (lexer: parser->lexer);
7174 }
7175 }
7176
7177 if (cp_parser_uncommitted_to_tentative_parse_p (parser))
7178 break;
7179 /* If the next token is an identifier, and the one after
7180 that is a `::', then any valid interpretation would have
7181 found a class-or-namespace-name. */
7182 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
7183 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
7184 == CPP_SCOPE)
7185 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type
7186 != CPP_COMPL))
7187 {
7188 token = cp_lexer_consume_token (lexer: parser->lexer);
7189 if (!error_p)
7190 {
7191 if (!token->error_reported)
7192 {
7193 tree decl;
7194 tree ambiguous_decls;
7195
7196 decl = cp_parser_lookup_name (parser, token->u.value,
7197 none_type,
7198 /*is_template=*/false,
7199 /*is_namespace=*/false,
7200 /*check_dependency=*/true,
7201 &ambiguous_decls,
7202 token->location);
7203 if (TREE_CODE (decl) == TEMPLATE_DECL)
7204 error_at (token->location,
7205 "%qD used without template arguments",
7206 decl);
7207 else if (ambiguous_decls)
7208 {
7209 // cp_parser_lookup_name has the same diagnostic,
7210 // thus make sure to emit it at most once.
7211 if (cp_parser_uncommitted_to_tentative_parse_p
7212 (parser))
7213 {
7214 error_at (token->location,
7215 "reference to %qD is ambiguous",
7216 token->u.value);
7217 print_candidates (ambiguous_decls);
7218 }
7219 decl = error_mark_node;
7220 }
7221 else
7222 {
7223 if (cxx_dialect != cxx98)
7224 cp_parser_name_lookup_error
7225 (parser, name: token->u.value, decl, desired: NLE_NOT_CXX98,
7226 location: token->location);
7227 else
7228 cp_parser_name_lookup_error
7229 (parser, name: token->u.value, decl, desired: NLE_CXX98,
7230 location: token->location);
7231 }
7232 }
7233 parser->scope = error_mark_node;
7234 error_p = true;
7235 /* Treat this as a successful nested-name-specifier
7236 due to:
7237
7238 [basic.lookup.qual]
7239
7240 If the name found is not a class-name (clause
7241 _class_) or namespace-name (_namespace.def_), the
7242 program is ill-formed. */
7243 success = true;
7244 }
7245 cp_lexer_consume_token (lexer: parser->lexer);
7246 }
7247 break;
7248 }
7249 /* We've found one valid nested-name-specifier. */
7250 success = true;
7251 /* Name lookup always gives us a DECL. */
7252 if (TREE_CODE (new_scope) == TYPE_DECL)
7253 new_scope = TREE_TYPE (new_scope);
7254 /* Uses of "template" must be followed by actual templates. */
7255 if (template_keyword_p)
7256 check_template_keyword_in_nested_name_spec (name: new_scope);
7257 /* If it is a class scope, try to complete it; we are about to
7258 be looking up names inside the class. */
7259 if (TYPE_P (new_scope)
7260 /* Since checking types for dependency can be expensive,
7261 avoid doing it if the type is already complete. */
7262 && !COMPLETE_TYPE_P (new_scope)
7263 /* Do not try to complete dependent types. */
7264 && !dependent_type_p (new_scope))
7265 {
7266 new_scope = complete_type (new_scope);
7267 /* If it is a typedef to current class, use the current
7268 class instead, as the typedef won't have any names inside
7269 it yet. */
7270 if (!COMPLETE_TYPE_P (new_scope)
7271 && currently_open_class (new_scope))
7272 new_scope = TYPE_MAIN_VARIANT (new_scope);
7273 }
7274 /* Make sure we look in the right scope the next time through
7275 the loop. */
7276 parser->scope = new_scope;
7277 }
7278
7279 /* If parsing tentatively, replace the sequence of tokens that makes
7280 up the nested-name-specifier with a CPP_NESTED_NAME_SPECIFIER
7281 token. That way, should we re-parse the token stream, we will
7282 not have to repeat the effort required to do the parse, nor will
7283 we issue duplicate error messages. */
7284 if (success && start)
7285 {
7286 cp_token *token;
7287
7288 token = cp_lexer_token_at (parser->lexer, pos: start);
7289 /* Reset the contents of the START token. */
7290 token->type = CPP_NESTED_NAME_SPECIFIER;
7291 /* Retrieve any deferred checks. Do not pop this access checks yet
7292 so the memory will not be reclaimed during token replacing below. */
7293 token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
7294 token->tree_check_p = true;
7295 token->u.tree_check_value->value = parser->scope;
7296 token->u.tree_check_value->checks = get_deferred_access_checks ();
7297 token->u.tree_check_value->qualifying_scope =
7298 parser->qualifying_scope;
7299 token->keyword = RID_MAX;
7300
7301 /* Purge all subsequent tokens. */
7302 cp_lexer_purge_tokens_after (lexer: parser->lexer, tok: start);
7303 }
7304
7305 if (start)
7306 pop_to_parent_deferring_access_checks ();
7307
7308 return success ? parser->scope : NULL_TREE;
7309}
7310
7311/* Parse a nested-name-specifier. See
7312 cp_parser_nested_name_specifier_opt for details. This function
7313 behaves identically, except that it will an issue an error if no
7314 nested-name-specifier is present. */
7315
7316static tree
7317cp_parser_nested_name_specifier (cp_parser *parser,
7318 bool typename_keyword_p,
7319 bool check_dependency_p,
7320 bool type_p,
7321 bool is_declaration)
7322{
7323 tree scope;
7324
7325 /* Look for the nested-name-specifier. */
7326 scope = cp_parser_nested_name_specifier_opt (parser,
7327 typename_keyword_p,
7328 check_dependency_p,
7329 type_p,
7330 is_declaration);
7331 /* If it was not present, issue an error message. */
7332 if (!scope)
7333 {
7334 cp_parser_error (parser, gmsgid: "expected nested-name-specifier");
7335 parser->scope = NULL_TREE;
7336 }
7337
7338 return scope;
7339}
7340
7341/* Parse the qualifying entity in a nested-name-specifier. For C++98,
7342 this is either a class-name or a namespace-name (which corresponds
7343 to the class-or-namespace-name production in the grammar). For
7344 C++0x, it can also be a type-name that refers to an enumeration
7345 type or a simple-template-id.
7346
7347 TYPENAME_KEYWORD_P is TRUE iff the `typename' keyword is in effect.
7348 TEMPLATE_KEYWORD_P is TRUE iff the `template' keyword is in effect.
7349 CHECK_DEPENDENCY_P is FALSE iff dependent names should be looked up.
7350 TYPE_P is TRUE iff the next name should be taken as a class-name,
7351 even the same name is declared to be another entity in the same
7352 scope.
7353
7354 Returns the class (TYPE_DECL) or namespace (NAMESPACE_DECL)
7355 specified by the class-or-namespace-name. If neither is found the
7356 ERROR_MARK_NODE is returned. */
7357
7358static tree
7359cp_parser_qualifying_entity (cp_parser *parser,
7360 bool typename_keyword_p,
7361 bool template_keyword_p,
7362 bool check_dependency_p,
7363 bool type_p,
7364 bool is_declaration)
7365{
7366 tree saved_scope;
7367 tree saved_qualifying_scope;
7368 tree saved_object_scope;
7369 tree scope;
7370 bool only_class_p;
7371 bool successful_parse_p;
7372
7373 /* DR 743: decltype can appear in a nested-name-specifier. */
7374 if (cp_lexer_next_token_is_decltype (lexer: parser->lexer))
7375 {
7376 scope = cp_parser_decltype (parser);
7377 if (TREE_CODE (scope) != ENUMERAL_TYPE
7378 && !MAYBE_CLASS_TYPE_P (scope))
7379 {
7380 cp_parser_simulate_error (parser);
7381 return error_mark_node;
7382 }
7383 if (TYPE_NAME (scope))
7384 scope = TYPE_NAME (scope);
7385 return scope;
7386 }
7387
7388 /* Before we try to parse the class-name, we must save away the
7389 current PARSER->SCOPE since cp_parser_class_name will destroy
7390 it. */
7391 saved_scope = parser->scope;
7392 saved_qualifying_scope = parser->qualifying_scope;
7393 saved_object_scope = parser->object_scope;
7394 /* Try for a class-name first. If the SAVED_SCOPE is a type, then
7395 there is no need to look for a namespace-name. */
7396 only_class_p = template_keyword_p
7397 || (saved_scope && TYPE_P (saved_scope) && cxx_dialect == cxx98);
7398 if (!only_class_p)
7399 cp_parser_parse_tentatively (parser);
7400 scope = cp_parser_class_name (parser,
7401 typename_keyword_p,
7402 template_keyword_p,
7403 type_p ? class_type : none_type,
7404 check_dependency_p,
7405 /*class_head_p=*/false,
7406 is_declaration,
7407 /*enum_ok=*/cxx_dialect > cxx98);
7408 successful_parse_p = only_class_p || cp_parser_parse_definitely (parser);
7409 /* If that didn't work, try for a namespace-name. */
7410 if (!only_class_p && !successful_parse_p)
7411 {
7412 /* Restore the saved scope. */
7413 parser->scope = saved_scope;
7414 parser->qualifying_scope = saved_qualifying_scope;
7415 parser->object_scope = saved_object_scope;
7416 /* If we are not looking at an identifier followed by the scope
7417 resolution operator, then this is not part of a
7418 nested-name-specifier. (Note that this function is only used
7419 to parse the components of a nested-name-specifier.) */
7420 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NAME)
7421 || cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type != CPP_SCOPE)
7422 return error_mark_node;
7423 scope = cp_parser_namespace_name (parser);
7424 }
7425
7426 return scope;
7427}
7428
7429/* Return true if we are looking at a compound-literal, false otherwise. */
7430
7431static bool
7432cp_parser_compound_literal_p (cp_parser *parser)
7433{
7434 cp_lexer_save_tokens (lexer: parser->lexer);
7435
7436 /* Skip tokens until the next token is a closing parenthesis.
7437 If we find the closing `)', and the next token is a `{', then
7438 we are looking at a compound-literal. */
7439 bool compound_literal_p
7440 = (cp_parser_skip_to_closing_parenthesis (parser, recovering: false, or_comma: false,
7441 /*consume_paren=*/true)
7442 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE));
7443
7444 /* Roll back the tokens we skipped. */
7445 cp_lexer_rollback_tokens (lexer: parser->lexer);
7446
7447 return compound_literal_p;
7448}
7449
7450/* Return true if EXPR is the integer constant zero or a complex constant
7451 of zero, without any folding, but ignoring location wrappers. */
7452
7453bool
7454literal_integer_zerop (const_tree expr)
7455{
7456 return (location_wrapper_p (exp: expr)
7457 && integer_zerop (TREE_OPERAND (expr, 0)));
7458}
7459
7460/* Parse a postfix-expression.
7461
7462 postfix-expression:
7463 primary-expression
7464 postfix-expression [ expression ]
7465 postfix-expression ( expression-list [opt] )
7466 simple-type-specifier ( expression-list [opt] )
7467 typename :: [opt] nested-name-specifier identifier
7468 ( expression-list [opt] )
7469 typename :: [opt] nested-name-specifier template [opt] template-id
7470 ( expression-list [opt] )
7471 postfix-expression . template [opt] id-expression
7472 postfix-expression -> template [opt] id-expression
7473 postfix-expression . pseudo-destructor-name
7474 postfix-expression -> pseudo-destructor-name
7475 postfix-expression ++
7476 postfix-expression --
7477 dynamic_cast < type-id > ( expression )
7478 static_cast < type-id > ( expression )
7479 reinterpret_cast < type-id > ( expression )
7480 const_cast < type-id > ( expression )
7481 typeid ( expression )
7482 typeid ( type-id )
7483
7484 GNU Extension:
7485
7486 postfix-expression:
7487 ( type-id ) { initializer-list , [opt] }
7488
7489 This extension is a GNU version of the C99 compound-literal
7490 construct. (The C99 grammar uses `type-name' instead of `type-id',
7491 but they are essentially the same concept.)
7492
7493 If ADDRESS_P is true, the postfix expression is the operand of the
7494 `&' operator. CAST_P is true if this expression is the target of a
7495 cast.
7496
7497 If MEMBER_ACCESS_ONLY_P, we only allow postfix expressions that are
7498 class member access expressions [expr.ref].
7499
7500 Returns a representation of the expression. */
7501
7502static cp_expr
7503cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
7504 bool member_access_only_p, bool decltype_p,
7505 cp_id_kind * pidk_return)
7506{
7507 cp_token *token;
7508 location_t loc;
7509 enum rid keyword;
7510 cp_id_kind idk = CP_ID_KIND_NONE;
7511 cp_expr postfix_expression = NULL_TREE;
7512 bool is_member_access = false;
7513
7514 /* Peek at the next token. */
7515 token = cp_lexer_peek_token (lexer: parser->lexer);
7516 loc = token->location;
7517 location_t start_loc = get_range_from_loc (set: line_table, loc).m_start;
7518
7519 /* Some of the productions are determined by keywords. */
7520 keyword = token->keyword;
7521 switch (keyword)
7522 {
7523 case RID_DYNCAST:
7524 case RID_STATCAST:
7525 case RID_REINTCAST:
7526 case RID_CONSTCAST:
7527 {
7528 tree type;
7529 cp_expr expression;
7530 const char *saved_message;
7531 bool saved_in_type_id_in_expr_p;
7532
7533 /* All of these can be handled in the same way from the point
7534 of view of parsing. Begin by consuming the token
7535 identifying the cast. */
7536 cp_lexer_consume_token (lexer: parser->lexer);
7537
7538 /* New types cannot be defined in the cast. */
7539 saved_message = parser->type_definition_forbidden_message;
7540 parser->type_definition_forbidden_message
7541 = G_("types may not be defined in casts");
7542
7543 /* Look for the opening `<'. */
7544 cp_parser_require (parser, CPP_LESS, RT_LESS);
7545 /* Parse the type to which we are casting. */
7546 saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
7547 parser->in_type_id_in_expr_p = true;
7548 type = cp_parser_type_id (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
7549 NULL);
7550 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
7551 /* Look for the closing `>'. */
7552 cp_parser_require (parser, CPP_GREATER, RT_GREATER);
7553 /* Restore the old message. */
7554 parser->type_definition_forbidden_message = saved_message;
7555
7556 bool saved_greater_than_is_operator_p
7557 = parser->greater_than_is_operator_p;
7558 parser->greater_than_is_operator_p = true;
7559
7560 /* And the expression which is being cast. */
7561 matching_parens parens;
7562 parens.require_open (parser);
7563 expression = cp_parser_expression (parser, & idk, /*cast_p=*/true);
7564 cp_token *close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN,
7565 RT_CLOSE_PAREN);
7566 location_t end_loc = close_paren ?
7567 close_paren->location : UNKNOWN_LOCATION;
7568
7569 parser->greater_than_is_operator_p
7570 = saved_greater_than_is_operator_p;
7571
7572 /* Only type conversions to integral or enumeration types
7573 can be used in constant-expressions. */
7574 if (!cast_valid_in_integral_constant_expression_p (type)
7575 && cp_parser_non_integral_constant_expression (parser, thing: NIC_CAST))
7576 {
7577 postfix_expression = error_mark_node;
7578 break;
7579 }
7580
7581 /* Construct a location e.g. :
7582 reinterpret_cast <int *> (expr)
7583 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7584 ranging from the start of the "*_cast" token to the final closing
7585 paren, with the caret at the start. */
7586 location_t cp_cast_loc = make_location (caret: start_loc, start: start_loc, finish: end_loc);
7587
7588 switch (keyword)
7589 {
7590 case RID_DYNCAST:
7591 postfix_expression
7592 = build_dynamic_cast (cp_cast_loc, type, expression,
7593 tf_warning_or_error);
7594 break;
7595 case RID_STATCAST:
7596 postfix_expression
7597 = build_static_cast (cp_cast_loc, type, expression,
7598 tf_warning_or_error);
7599 break;
7600 case RID_REINTCAST:
7601 postfix_expression
7602 = build_reinterpret_cast (cp_cast_loc, type, expression,
7603 tf_warning_or_error);
7604 break;
7605 case RID_CONSTCAST:
7606 postfix_expression
7607 = build_const_cast (cp_cast_loc, type, expression,
7608 tf_warning_or_error);
7609 break;
7610 default:
7611 gcc_unreachable ();
7612 }
7613 }
7614 break;
7615
7616 case RID_TYPEID:
7617 {
7618 tree type;
7619 const char *saved_message;
7620 bool saved_in_type_id_in_expr_p;
7621
7622 /* Consume the `typeid' token. */
7623 cp_lexer_consume_token (lexer: parser->lexer);
7624 /* Look for the `(' token. */
7625 matching_parens parens;
7626 parens.require_open (parser);
7627 /* Types cannot be defined in a `typeid' expression. */
7628 saved_message = parser->type_definition_forbidden_message;
7629 parser->type_definition_forbidden_message
7630 = G_("types may not be defined in a %<typeid%> expression");
7631 /* We can't be sure yet whether we're looking at a type-id or an
7632 expression. */
7633 cp_parser_parse_tentatively (parser);
7634 /* Try a type-id first. */
7635 saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
7636 parser->in_type_id_in_expr_p = true;
7637 type = cp_parser_type_id (parser);
7638 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
7639 /* Look for the `)' token. Otherwise, we can't be sure that
7640 we're not looking at an expression: consider `typeid (int
7641 (3))', for example. */
7642 cp_token *close_paren = parens.require_close (parser);
7643 /* If all went well, simply lookup the type-id. */
7644 if (cp_parser_parse_definitely (parser))
7645 postfix_expression = get_typeid (type, tf_warning_or_error);
7646 /* Otherwise, fall back to the expression variant. */
7647 else
7648 {
7649 tree expression;
7650
7651 /* Look for an expression. */
7652 expression = cp_parser_expression (parser, & idk);
7653 /* Compute its typeid. */
7654 postfix_expression = build_typeid (expression, tf_warning_or_error);
7655 /* Look for the `)' token. */
7656 close_paren = parens.require_close (parser);
7657 }
7658 /* Restore the saved message. */
7659 parser->type_definition_forbidden_message = saved_message;
7660 /* `typeid' may not appear in an integral constant expression. */
7661 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_TYPEID))
7662 postfix_expression = error_mark_node;
7663
7664 /* Construct a location e.g. :
7665 typeid (expr)
7666 ^~~~~~~~~~~~~
7667 ranging from the start of the "typeid" token to the final closing
7668 paren, with the caret at the start. */
7669 if (close_paren)
7670 {
7671 location_t typeid_loc
7672 = make_location (caret: start_loc, start: start_loc, finish: close_paren->location);
7673 postfix_expression.set_location (typeid_loc);
7674 postfix_expression.maybe_add_location_wrapper ();
7675 }
7676 }
7677 break;
7678
7679 case RID_TYPENAME:
7680 {
7681 tree type;
7682 /* The syntax permitted here is the same permitted for an
7683 elaborated-type-specifier. */
7684 ++parser->prevent_constrained_type_specifiers;
7685 type = cp_parser_elaborated_type_specifier (parser,
7686 /*is_friend=*/false,
7687 /*is_declaration=*/false);
7688 --parser->prevent_constrained_type_specifiers;
7689 postfix_expression = cp_parser_functional_cast (parser, type);
7690 }
7691 break;
7692
7693 case RID_ADDRESSOF:
7694 case RID_BUILTIN_SHUFFLE:
7695 case RID_BUILTIN_SHUFFLEVECTOR:
7696 case RID_BUILTIN_LAUNDER:
7697 case RID_BUILTIN_ASSOC_BARRIER:
7698 {
7699 vec<tree, va_gc> *vec;
7700
7701 cp_lexer_consume_token (lexer: parser->lexer);
7702 vec = cp_parser_parenthesized_expression_list (parser, non_attr,
7703 /*cast_p=*/false, /*allow_expansion_p=*/true,
7704 /*non_constant_p=*/NULL);
7705 if (vec == NULL)
7706 {
7707 postfix_expression = error_mark_node;
7708 break;
7709 }
7710
7711 for (tree p : *vec)
7712 mark_exp_read (p);
7713
7714 switch (keyword)
7715 {
7716 case RID_ADDRESSOF:
7717 if (vec->length () == 1)
7718 postfix_expression
7719 = cp_build_addressof (loc, (*vec)[0], tf_warning_or_error);
7720 else
7721 {
7722 error_at (loc, "wrong number of arguments to "
7723 "%<__builtin_addressof%>");
7724 postfix_expression = error_mark_node;
7725 }
7726 break;
7727
7728 case RID_BUILTIN_LAUNDER:
7729 if (vec->length () == 1)
7730 postfix_expression = finish_builtin_launder (loc, (*vec)[0],
7731 tf_warning_or_error);
7732 else
7733 {
7734 error_at (loc, "wrong number of arguments to "
7735 "%<__builtin_launder%>");
7736 postfix_expression = error_mark_node;
7737 }
7738 break;
7739
7740 case RID_BUILTIN_ASSOC_BARRIER:
7741 if (vec->length () == 1)
7742 postfix_expression = build1_loc (loc, code: PAREN_EXPR,
7743 TREE_TYPE ((*vec)[0]),
7744 arg1: (*vec)[0]);
7745 else
7746 {
7747 error_at (loc, "wrong number of arguments to "
7748 "%<__builtin_assoc_barrier%>");
7749 postfix_expression = error_mark_node;
7750 }
7751 break;
7752
7753 case RID_BUILTIN_SHUFFLE:
7754 if (vec->length () == 2)
7755 postfix_expression
7756 = build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE,
7757 (*vec)[1], tf_warning_or_error);
7758 else if (vec->length () == 3)
7759 postfix_expression
7760 = build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1],
7761 (*vec)[2], tf_warning_or_error);
7762 else
7763 {
7764 error_at (loc, "wrong number of arguments to "
7765 "%<__builtin_shuffle%>");
7766 postfix_expression = error_mark_node;
7767 }
7768 break;
7769
7770 case RID_BUILTIN_SHUFFLEVECTOR:
7771 if (vec->length () < 3)
7772 {
7773 error_at (loc, "wrong number of arguments to "
7774 "%<__builtin_shufflevector%>");
7775 postfix_expression = error_mark_node;
7776 }
7777 else
7778 {
7779 postfix_expression
7780 = build_x_shufflevector (loc, vec, tf_warning_or_error);
7781 }
7782 break;
7783
7784 default:
7785 gcc_unreachable ();
7786 }
7787 break;
7788 }
7789
7790 case RID_BUILTIN_CONVERTVECTOR:
7791 {
7792 tree expression;
7793 tree type;
7794 /* Consume the `__builtin_convertvector' token. */
7795 cp_lexer_consume_token (lexer: parser->lexer);
7796 /* Look for the opening `('. */
7797 matching_parens parens;
7798 parens.require_open (parser);
7799 /* Now, parse the assignment-expression. */
7800 expression = cp_parser_assignment_expression (parser);
7801 /* Look for the `,'. */
7802 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
7803 location_t type_location
7804 = cp_lexer_peek_token (lexer: parser->lexer)->location;
7805 /* Parse the type-id. */
7806 {
7807 type_id_in_expr_sentinel s (parser);
7808 type = cp_parser_type_id (parser);
7809 }
7810 /* Look for the closing `)'. */
7811 parens.require_close (parser);
7812 postfix_expression
7813 = cp_build_vec_convert (expression, type_location, type,
7814 tf_warning_or_error);
7815 break;
7816 }
7817
7818 case RID_BUILTIN_BIT_CAST:
7819 {
7820 tree expression;
7821 tree type;
7822 /* Consume the `__builtin_bit_cast' token. */
7823 cp_lexer_consume_token (lexer: parser->lexer);
7824 /* Look for the opening `('. */
7825 matching_parens parens;
7826 parens.require_open (parser);
7827 location_t type_location
7828 = cp_lexer_peek_token (lexer: parser->lexer)->location;
7829 /* Parse the type-id. */
7830 {
7831 type_id_in_expr_sentinel s (parser);
7832 type = cp_parser_type_id (parser);
7833 }
7834 /* Look for the `,'. */
7835 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
7836 /* Now, parse the assignment-expression. */
7837 expression = cp_parser_assignment_expression (parser);
7838 /* Look for the closing `)'. */
7839 parens.require_close (parser);
7840 postfix_expression
7841 = cp_build_bit_cast (type_location, type, expression,
7842 tf_warning_or_error);
7843 break;
7844 }
7845
7846 default:
7847 {
7848 tree type;
7849
7850 /* If the next thing is a simple-type-specifier, we may be
7851 looking at a functional cast. We could also be looking at
7852 an id-expression. So, we try the functional cast, and if
7853 that doesn't work we fall back to the primary-expression. */
7854 cp_parser_parse_tentatively (parser);
7855 /* Look for the simple-type-specifier. */
7856 ++parser->prevent_constrained_type_specifiers;
7857 type = cp_parser_simple_type_specifier (parser,
7858 /*decl_specs=*/NULL,
7859 CP_PARSER_FLAGS_NONE);
7860 --parser->prevent_constrained_type_specifiers;
7861 /* Parse the cast itself. */
7862 if (!cp_parser_error_occurred (parser))
7863 postfix_expression
7864 = cp_parser_functional_cast (parser, type);
7865 /* If that worked, we're done. */
7866 if (cp_parser_parse_definitely (parser))
7867 break;
7868
7869 /* If the functional-cast didn't work out, try a
7870 compound-literal. */
7871 if (cp_parser_allow_gnu_extensions_p (parser)
7872 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
7873 {
7874 cp_expr initializer = NULL_TREE;
7875
7876 cp_parser_parse_tentatively (parser);
7877
7878 matching_parens parens;
7879 parens.consume_open (parser);
7880
7881 /* Avoid calling cp_parser_type_id pointlessly, see comment
7882 in cp_parser_cast_expression about c++/29234. */
7883 if (!cp_parser_compound_literal_p (parser))
7884 cp_parser_simulate_error (parser);
7885 else
7886 {
7887 /* Parse the type. */
7888 bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
7889 parser->in_type_id_in_expr_p = true;
7890 type = cp_parser_type_id (parser);
7891 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
7892 parens.require_close (parser);
7893 }
7894
7895 /* If things aren't going well, there's no need to
7896 keep going. */
7897 if (!cp_parser_error_occurred (parser))
7898 /* Parse the brace-enclosed initializer list. */
7899 initializer = cp_parser_braced_list (parser);
7900 /* If that worked, we're definitely looking at a
7901 compound-literal expression. */
7902 if (cp_parser_parse_definitely (parser))
7903 {
7904 /* Warn the user that a compound literal is not
7905 allowed in standard C++. */
7906 pedwarn (input_location, OPT_Wpedantic,
7907 "ISO C++ forbids compound-literals");
7908 /* For simplicity, we disallow compound literals in
7909 constant-expressions. We could
7910 allow compound literals of integer type, whose
7911 initializer was a constant, in constant
7912 expressions. Permitting that usage, as a further
7913 extension, would not change the meaning of any
7914 currently accepted programs. (Of course, as
7915 compound literals are not part of ISO C++, the
7916 standard has nothing to say.) */
7917 if (cp_parser_non_integral_constant_expression (parser,
7918 thing: NIC_NCC))
7919 {
7920 postfix_expression = error_mark_node;
7921 break;
7922 }
7923 /* Form the representation of the compound-literal. */
7924 postfix_expression
7925 = finish_compound_literal (type, initializer,
7926 tf_warning_or_error, fcl_c99);
7927 postfix_expression.set_location (initializer.get_location ());
7928 break;
7929 }
7930 }
7931
7932 /* It must be a primary-expression. */
7933 postfix_expression
7934 = cp_parser_primary_expression (parser, address_p, cast_p,
7935 /*template_arg_p=*/false,
7936 decltype_p,
7937 idk: &idk);
7938 }
7939 break;
7940 }
7941
7942 /* Note that we don't need to worry about calling build_cplus_new on a
7943 class-valued CALL_EXPR in decltype when it isn't the end of the
7944 postfix-expression; unary_complex_lvalue will take care of that for
7945 all these cases. */
7946
7947 /* Keep looping until the postfix-expression is complete. */
7948 while (true)
7949 {
7950 if (idk == CP_ID_KIND_UNQUALIFIED
7951 && identifier_p (t: postfix_expression)
7952 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_PAREN))
7953 /* It is not a Koenig lookup function call. */
7954 postfix_expression
7955 = unqualified_name_lookup_error (postfix_expression);
7956
7957 /* Peek at the next token. */
7958 token = cp_lexer_peek_token (lexer: parser->lexer);
7959
7960 switch (token->type)
7961 {
7962 case CPP_OPEN_SQUARE:
7963 if (cp_next_tokens_can_be_std_attribute_p (parser))
7964 {
7965 cp_parser_error (parser,
7966 gmsgid: "two consecutive %<[%> shall "
7967 "only introduce an attribute");
7968 return error_mark_node;
7969 }
7970 postfix_expression
7971 = cp_parser_postfix_open_square_expression (parser,
7972 postfix_expression,
7973 false,
7974 decltype_p);
7975 postfix_expression.set_range (start: start_loc,
7976 finish: postfix_expression.get_location ());
7977
7978 idk = CP_ID_KIND_NONE;
7979 is_member_access = false;
7980 break;
7981
7982 case CPP_OPEN_PAREN:
7983 /* postfix-expression ( expression-list [opt] ) */
7984 {
7985 bool koenig_p;
7986 bool is_builtin_constant_p;
7987 bool saved_integral_constant_expression_p = false;
7988 bool saved_non_integral_constant_expression_p = false;
7989 tsubst_flags_t complain = complain_flags (decltype_p);
7990 vec<tree, va_gc> *args;
7991 location_t close_paren_loc = UNKNOWN_LOCATION;
7992 location_t combined_loc = UNKNOWN_LOCATION;
7993
7994 is_member_access = false;
7995
7996 tree stripped_expression
7997 = tree_strip_any_location_wrapper (exp: postfix_expression);
7998 is_builtin_constant_p
7999 = DECL_IS_BUILTIN_CONSTANT_P (stripped_expression);
8000 if (is_builtin_constant_p)
8001 {
8002 /* The whole point of __builtin_constant_p is to allow
8003 non-constant expressions to appear as arguments. */
8004 saved_integral_constant_expression_p
8005 = parser->integral_constant_expression_p;
8006 saved_non_integral_constant_expression_p
8007 = parser->non_integral_constant_expression_p;
8008 parser->integral_constant_expression_p = false;
8009 }
8010 else if (TREE_CODE (stripped_expression) == FUNCTION_DECL
8011 && fndecl_built_in_p (node: stripped_expression,
8012 name1: BUILT_IN_CLASSIFY_TYPE))
8013 {
8014 /* __builtin_classify_type (type) */
8015 auto cl1 = make_temp_override
8016 (var&: parser->type_definition_forbidden_message,
8017 G_("types may not be defined in "
8018 "%<__builtin_classify_type%> calls"));
8019 auto cl2 = make_temp_override
8020 (var&: parser->type_definition_forbidden_message_arg,
8021 NULL);
8022 auto cl3 = make_temp_override (var&: parser->in_type_id_in_expr_p,
8023 overrider: true);
8024 cp_unevaluated uev;
8025 cp_parser_parse_tentatively (parser);
8026 matching_parens parens;
8027 parens.consume_open (parser);
8028 tree type = cp_parser_type_id (parser);
8029 parens.require_close (parser);
8030 if (cp_parser_parse_definitely (parser))
8031 {
8032 if (dependent_type_p (type))
8033 {
8034 postfix_expression = build_vl_exp (CALL_EXPR, 4);
8035 CALL_EXPR_FN (postfix_expression)
8036 = stripped_expression;
8037 CALL_EXPR_STATIC_CHAIN (postfix_expression) = type;
8038 CALL_EXPR_ARG (postfix_expression, 0)
8039 = build_min (SIZEOF_EXPR, size_type_node, type);
8040 TREE_TYPE (postfix_expression) = integer_type_node;
8041 }
8042 else
8043 {
8044 postfix_expression
8045 = build_int_cst (integer_type_node,
8046 type_to_class (type));
8047 }
8048 break;
8049 }
8050 }
8051 args = (cp_parser_parenthesized_expression_list
8052 (parser, non_attr,
8053 /*cast_p=*/false, /*allow_expansion_p=*/true,
8054 /*non_constant_p=*/NULL,
8055 /*close_paren_loc=*/&close_paren_loc,
8056 /*wrap_locations_p=*/true));
8057 if (is_builtin_constant_p)
8058 {
8059 parser->integral_constant_expression_p
8060 = saved_integral_constant_expression_p;
8061 parser->non_integral_constant_expression_p
8062 = saved_non_integral_constant_expression_p;
8063 }
8064
8065 if (args == NULL)
8066 {
8067 postfix_expression = error_mark_node;
8068 break;
8069 }
8070
8071 /* Function calls are not permitted in
8072 constant-expressions. */
8073 if (! builtin_valid_in_constant_expr_p (postfix_expression)
8074 && cp_parser_non_integral_constant_expression (parser,
8075 thing: NIC_FUNC_CALL))
8076 {
8077 postfix_expression = error_mark_node;
8078 release_tree_vector (args);
8079 break;
8080 }
8081
8082 koenig_p = false;
8083 if (idk == CP_ID_KIND_UNQUALIFIED
8084 || idk == CP_ID_KIND_TEMPLATE_ID)
8085 {
8086 if (identifier_p (t: postfix_expression)
8087 /* In C++20, we may need to perform ADL for a template
8088 name. */
8089 || (TREE_CODE (postfix_expression) == TEMPLATE_ID_EXPR
8090 && identifier_p (TREE_OPERAND (postfix_expression, 0))))
8091 {
8092 if (!args->is_empty ())
8093 {
8094 koenig_p = true;
8095 if (!any_type_dependent_arguments_p (args))
8096 postfix_expression
8097 = perform_koenig_lookup (postfix_expression, args,
8098 complain);
8099 }
8100 else
8101 postfix_expression
8102 = unqualified_fn_lookup_error (postfix_expression);
8103 }
8104 /* We do not perform argument-dependent lookup if
8105 normal lookup finds a non-function, in accordance
8106 with the expected resolution of DR 218. */
8107 else if (!args->is_empty ()
8108 && is_overloaded_fn (postfix_expression))
8109 {
8110 /* Do not do argument dependent lookup if regular
8111 lookup finds a member function or a block-scope
8112 function declaration. [basic.lookup.argdep]/3 */
8113 bool do_adl_p = true;
8114 tree fns = get_fns (postfix_expression);
8115 for (lkp_iterator iter (fns); iter; ++iter)
8116 {
8117 tree fn = STRIP_TEMPLATE (*iter);
8118 if ((TREE_CODE (fn) == USING_DECL
8119 && DECL_DEPENDENT_P (fn))
8120 || DECL_FUNCTION_MEMBER_P (fn)
8121 || DECL_LOCAL_DECL_P (fn))
8122 {
8123 do_adl_p = false;
8124 break;
8125 }
8126 }
8127
8128 if (do_adl_p)
8129 {
8130 koenig_p = true;
8131 if (!any_type_dependent_arguments_p (args))
8132 postfix_expression
8133 = perform_koenig_lookup (postfix_expression, args,
8134 complain);
8135 }
8136 }
8137 }
8138
8139 /* Temporarily set input_location to the combined location
8140 with call expression range, as e.g. build_out_target_exprs
8141 called from convert_default_arg relies on input_location,
8142 so updating it only when the call is fully built results
8143 in inconsistencies between location handling in templates
8144 and outside of templates. */
8145 if (close_paren_loc != UNKNOWN_LOCATION)
8146 combined_loc = make_location (caret: token->location, start: start_loc,
8147 finish: close_paren_loc);
8148 iloc_sentinel ils (combined_loc);
8149
8150 if (TREE_CODE (postfix_expression) == OFFSET_REF
8151 || TREE_CODE (postfix_expression) == MEMBER_REF
8152 || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
8153 postfix_expression = (build_offset_ref_call_from_tree
8154 (postfix_expression, &args,
8155 complain));
8156 else
8157 /* All other function calls. */
8158 {
8159 if (DECL_P (postfix_expression)
8160 && parser->omp_for_parse_state
8161 && parser->omp_for_parse_state->in_intervening_code
8162 && omp_runtime_api_call (fndecl: postfix_expression))
8163 {
8164 error_at (loc, "calls to the OpenMP runtime API are "
8165 "not permitted in intervening code");
8166 parser->omp_for_parse_state->fail = true;
8167 }
8168 bool disallow_virtual = (idk == CP_ID_KIND_QUALIFIED);
8169 postfix_expression
8170 = finish_call_expr (postfix_expression, &args,
8171 disallow_virtual,
8172 koenig_p,
8173 complain);
8174 }
8175
8176 if (close_paren_loc != UNKNOWN_LOCATION)
8177 postfix_expression.set_location (combined_loc);
8178
8179 /* The POSTFIX_EXPRESSION is certainly no longer an id. */
8180 idk = CP_ID_KIND_NONE;
8181
8182 release_tree_vector (args);
8183 }
8184 break;
8185
8186 case CPP_DOT:
8187 case CPP_DEREF:
8188 /* postfix-expression . template [opt] id-expression
8189 postfix-expression . pseudo-destructor-name
8190 postfix-expression -> template [opt] id-expression
8191 postfix-expression -> pseudo-destructor-name */
8192
8193 /* Consume the `.' or `->' operator. */
8194 cp_lexer_consume_token (lexer: parser->lexer);
8195
8196 postfix_expression
8197 = cp_parser_postfix_dot_deref_expression (parser, token->type,
8198 postfix_expression,
8199 false, &idk, loc);
8200
8201 is_member_access = true;
8202 break;
8203
8204 case CPP_PLUS_PLUS:
8205 /* postfix-expression ++ */
8206 /* Consume the `++' token. */
8207 cp_lexer_consume_token (lexer: parser->lexer);
8208 /* Generate a representation for the complete expression. */
8209 postfix_expression
8210 = finish_increment_expr (postfix_expression,
8211 POSTINCREMENT_EXPR);
8212 /* Increments may not appear in constant-expressions. */
8213 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_INC))
8214 postfix_expression = error_mark_node;
8215 idk = CP_ID_KIND_NONE;
8216 is_member_access = false;
8217 break;
8218
8219 case CPP_MINUS_MINUS:
8220 /* postfix-expression -- */
8221 /* Consume the `--' token. */
8222 cp_lexer_consume_token (lexer: parser->lexer);
8223 /* Generate a representation for the complete expression. */
8224 postfix_expression
8225 = finish_increment_expr (postfix_expression,
8226 POSTDECREMENT_EXPR);
8227 /* Decrements may not appear in constant-expressions. */
8228 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_DEC))
8229 postfix_expression = error_mark_node;
8230 idk = CP_ID_KIND_NONE;
8231 is_member_access = false;
8232 break;
8233
8234 default:
8235 if (pidk_return != NULL)
8236 * pidk_return = idk;
8237 if (member_access_only_p)
8238 return is_member_access
8239 ? postfix_expression
8240 : cp_expr (error_mark_node);
8241 else
8242 return postfix_expression;
8243 }
8244 }
8245}
8246
8247/* Helper function for cp_parser_parenthesized_expression_list and
8248 cp_parser_postfix_open_square_expression. Parse a single element
8249 of parenthesized expression list. */
8250
8251static cp_expr
8252cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p,
8253 bool allow_expansion_p,
8254 bool *non_constant_p)
8255{
8256 cp_expr expr (NULL_TREE);
8257 bool expr_non_constant_p;
8258
8259 /* Parse the next assignment-expression. */
8260 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
8261 {
8262 /* A braced-init-list. */
8263 cp_lexer_set_source_position (lexer: parser->lexer);
8264 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
8265 expr = cp_parser_braced_list (parser,
8266 (non_constant_p != nullptr
8267 ? &expr_non_constant_p
8268 : nullptr));
8269 if (non_constant_p && expr_non_constant_p)
8270 *non_constant_p = true;
8271 }
8272 else if (non_constant_p)
8273 {
8274 expr = cp_parser_constant_expression (parser,
8275 /*allow_non_constant_p=*/true,
8276 &expr_non_constant_p);
8277 if (expr_non_constant_p)
8278 *non_constant_p = true;
8279 }
8280 else
8281 expr = cp_parser_assignment_expression (parser, /*pidk=*/NULL, cast_p);
8282
8283 /* If we have an ellipsis, then this is an expression expansion. */
8284 if (allow_expansion_p
8285 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
8286 {
8287 /* Consume the `...'. */
8288 cp_lexer_consume_token (lexer: parser->lexer);
8289
8290 /* Build the argument pack. */
8291 expr = make_pack_expansion (expr);
8292 }
8293 return expr;
8294}
8295
8296/* A subroutine of cp_parser_postfix_expression that also gets hijacked
8297 by cp_parser_builtin_offsetof. We're looking for
8298
8299 postfix-expression [ expression ]
8300 postfix-expression [ braced-init-list ] (C++11)
8301 postfix-expression [ expression-list[opt] ] (C++23)
8302
8303 FOR_OFFSETOF is set if we're being called in that context, which
8304 changes how we deal with integer constant expressions. */
8305
8306static tree
8307cp_parser_postfix_open_square_expression (cp_parser *parser,
8308 tree postfix_expression,
8309 bool for_offsetof,
8310 bool decltype_p)
8311{
8312 tree index = NULL_TREE;
8313 releasing_vec expression_list = NULL;
8314 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
8315 bool saved_greater_than_is_operator_p;
8316 bool saved_colon_corrects_to_scope_p;
8317
8318 /* Consume the `[' token. */
8319 cp_lexer_consume_token (lexer: parser->lexer);
8320
8321 saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
8322 parser->greater_than_is_operator_p = true;
8323
8324 saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
8325 if (parser->omp_array_section_p)
8326 parser->colon_corrects_to_scope_p = false;
8327
8328 /* Parse the index expression. */
8329 /* ??? For offsetof, there is a question of what to allow here. If
8330 offsetof is not being used in an integral constant expression context,
8331 then we *could* get the right answer by computing the value at runtime.
8332 If we are in an integral constant expression context, then we might
8333 could accept any constant expression; hard to say without analysis.
8334 Rather than open the barn door too wide right away, allow only integer
8335 constant expressions here. */
8336 if (for_offsetof)
8337 index = cp_parser_constant_expression (parser);
8338 else if (!parser->omp_array_section_p
8339 || cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COLON))
8340 {
8341 if (cxx_dialect >= cxx23
8342 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_SQUARE))
8343 *&expression_list = make_tree_vector ();
8344 else if (cxx_dialect >= cxx23)
8345 {
8346 while (true)
8347 {
8348 cp_expr expr
8349 = cp_parser_parenthesized_expression_list_elt (parser,
8350 /*cast_p=*/
8351 false,
8352 /*allow_exp_p=*/
8353 allow_expansion_p: true,
8354 /*non_cst_p=*/
8355 NULL);
8356
8357 if (expr == error_mark_node)
8358 index = error_mark_node;
8359 else if (expression_list.get () == NULL
8360 && !PACK_EXPANSION_P (expr.get_value ()))
8361 index = expr.get_value ();
8362 else
8363 vec_safe_push (r&: expression_list, t: expr.get_value ());
8364
8365 /* If the next token isn't a `,', then we are done. */
8366 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
8367 break;
8368
8369 if (expression_list.get () == NULL && index != error_mark_node)
8370 {
8371 *&expression_list = make_tree_vector_single (index);
8372 index = NULL_TREE;
8373 }
8374
8375 /* Otherwise, consume the `,' and keep going. */
8376 cp_lexer_consume_token (lexer: parser->lexer);
8377 }
8378 if (expression_list.get () && index == error_mark_node)
8379 expression_list.release ();
8380 }
8381 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
8382 {
8383 cp_lexer_set_source_position (lexer: parser->lexer);
8384 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
8385 index = cp_parser_braced_list (parser);
8386 }
8387 else
8388 index = cp_parser_expression (parser, NULL, /*cast_p=*/false,
8389 /*decltype_p=*/false,
8390 /*warn_comma_p=*/warn_comma_subscript);
8391 }
8392
8393 parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
8394
8395 if (cxx_dialect >= cxx23
8396 && parser->omp_array_section_p
8397 && expression_list.get () != NULL
8398 && vec_safe_length (r&: expression_list) > 1)
8399 {
8400 error_at (loc, "cannot use multidimensional subscript in OpenMP array "
8401 "section");
8402 index = error_mark_node;
8403 }
8404 if (parser->omp_array_section_p
8405 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
8406 {
8407 cp_lexer_consume_token (lexer: parser->lexer);
8408 tree length = NULL_TREE;
8409 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_SQUARE))
8410 {
8411 if (cxx_dialect >= cxx23)
8412 {
8413 cp_expr expr
8414 = cp_parser_parenthesized_expression_list_elt (parser,
8415 /*cast_p=*/
8416 false,
8417 /*allow_exp_p=*/
8418 allow_expansion_p: true,
8419 /*non_cst_p=*/
8420 NULL);
8421
8422 if (expr == error_mark_node)
8423 length = error_mark_node;
8424 else
8425 length = expr.get_value ();
8426
8427 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
8428 {
8429 error_at (loc, "cannot use multidimensional subscript in "
8430 "OpenMP array section");
8431 length = error_mark_node;
8432 }
8433 }
8434 else
8435 length
8436 = cp_parser_expression (parser, NULL, /*cast_p=*/false,
8437 /*decltype_p=*/false,
8438 /*warn_comma_p=*/warn_comma_subscript);
8439 }
8440
8441 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
8442
8443 if (index == error_mark_node || length == error_mark_node)
8444 {
8445 cp_parser_skip_to_closing_square_bracket (parser);
8446 return error_mark_node;
8447 }
8448 else
8449 cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
8450
8451 return grok_omp_array_section (input_location, postfix_expression, index,
8452 length);
8453 }
8454
8455 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
8456
8457 /* Look for the closing `]'. */
8458 cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
8459
8460 /* Build the ARRAY_REF. */
8461 postfix_expression = grok_array_decl (loc, postfix_expression,
8462 index, &expression_list,
8463 tf_warning_or_error
8464 | (decltype_p ? tf_decltype : 0));
8465
8466 /* When not doing offsetof, array references are not permitted in
8467 constant-expressions. */
8468 if (!for_offsetof
8469 && (cp_parser_non_integral_constant_expression (parser, thing: NIC_ARRAY_REF)))
8470 postfix_expression = error_mark_node;
8471
8472 return postfix_expression;
8473}
8474
8475/* A subroutine of cp_parser_postfix_dot_deref_expression. Handle dot
8476 dereference of incomplete type, returns true if error_mark_node should
8477 be returned from caller, otherwise adjusts *SCOPE, *POSTFIX_EXPRESSION
8478 and *DEPENDENT_P. */
8479
8480bool
8481cp_parser_dot_deref_incomplete (tree *scope, cp_expr *postfix_expression,
8482 bool *dependent_p)
8483{
8484 /* In a template, be permissive by treating an object expression
8485 of incomplete type as dependent (after a pedwarn). */
8486 diagnostic_t kind = (processing_template_decl
8487 && MAYBE_CLASS_TYPE_P (*scope) ? DK_PEDWARN : DK_ERROR);
8488
8489 switch (TREE_CODE (*postfix_expression))
8490 {
8491 case CAST_EXPR:
8492 case REINTERPRET_CAST_EXPR:
8493 case CONST_CAST_EXPR:
8494 case STATIC_CAST_EXPR:
8495 case DYNAMIC_CAST_EXPR:
8496 case IMPLICIT_CONV_EXPR:
8497 case VIEW_CONVERT_EXPR:
8498 case NON_LVALUE_EXPR:
8499 kind = DK_ERROR;
8500 break;
8501 case OVERLOAD:
8502 /* Don't emit any diagnostic for OVERLOADs. */
8503 kind = DK_IGNORED;
8504 break;
8505 default:
8506 /* Avoid clobbering e.g. DECLs. */
8507 if (!EXPR_P (*postfix_expression))
8508 kind = DK_ERROR;
8509 break;
8510 }
8511
8512 if (kind == DK_IGNORED)
8513 return false;
8514
8515 location_t exploc = location_of (*postfix_expression);
8516 cxx_incomplete_type_diagnostic (exploc, *postfix_expression, *scope, kind);
8517 if (!MAYBE_CLASS_TYPE_P (*scope))
8518 return true;
8519 if (kind == DK_ERROR)
8520 *scope = *postfix_expression = error_mark_node;
8521 else if (processing_template_decl)
8522 {
8523 *dependent_p = true;
8524 *scope = TREE_TYPE (*postfix_expression) = NULL_TREE;
8525 }
8526 return false;
8527}
8528
8529/* A subroutine of cp_parser_postfix_expression that also gets hijacked
8530 by cp_parser_builtin_offsetof. We're looking for
8531
8532 postfix-expression . template [opt] id-expression
8533 postfix-expression . pseudo-destructor-name
8534 postfix-expression -> template [opt] id-expression
8535 postfix-expression -> pseudo-destructor-name
8536
8537 FOR_OFFSETOF is set if we're being called in that context. That sorta
8538 limits what of the above we'll actually accept, but nevermind.
8539 TOKEN_TYPE is the "." or "->" token, which will already have been
8540 removed from the stream. */
8541
8542static tree
8543cp_parser_postfix_dot_deref_expression (cp_parser *parser,
8544 enum cpp_ttype token_type,
8545 cp_expr postfix_expression,
8546 bool for_offsetof, cp_id_kind *idk,
8547 location_t location)
8548{
8549 tree name;
8550 bool dependent_p;
8551 bool pseudo_destructor_p;
8552 tree scope = NULL_TREE;
8553 location_t start_loc = postfix_expression.get_start ();
8554
8555 /* If this is a `->' operator, dereference the pointer. */
8556 if (token_type == CPP_DEREF)
8557 postfix_expression = build_x_arrow (location, postfix_expression,
8558 tf_warning_or_error);
8559 /* Check to see whether or not the expression is type-dependent and
8560 not the current instantiation. */
8561 dependent_p = type_dependent_object_expression_p (postfix_expression);
8562 /* The identifier following the `->' or `.' is not qualified. */
8563 parser->scope = NULL_TREE;
8564 parser->qualifying_scope = NULL_TREE;
8565 parser->object_scope = NULL_TREE;
8566 *idk = CP_ID_KIND_NONE;
8567
8568 /* Enter the scope corresponding to the type of the object
8569 given by the POSTFIX_EXPRESSION. */
8570 if (!dependent_p)
8571 {
8572 scope = TREE_TYPE (postfix_expression);
8573 /* According to the standard, no expression should ever have
8574 reference type. Unfortunately, we do not currently match
8575 the standard in this respect in that our internal representation
8576 of an expression may have reference type even when the standard
8577 says it does not. Therefore, we have to manually obtain the
8578 underlying type here. */
8579 scope = non_reference (scope);
8580 /* The type of the POSTFIX_EXPRESSION must be complete. */
8581 /* Unlike the object expression in other contexts, *this is not
8582 required to be of complete type for purposes of class member
8583 access (5.2.5) outside the member function body. */
8584 if (postfix_expression != current_class_ref
8585 && scope != error_mark_node
8586 && !currently_open_class (scope))
8587 {
8588 scope = complete_type (scope);
8589 if (!COMPLETE_TYPE_P (scope)
8590 && cp_parser_dot_deref_incomplete (scope: &scope, postfix_expression: &postfix_expression,
8591 dependent_p: &dependent_p))
8592 return error_mark_node;
8593 }
8594
8595 if (!dependent_p)
8596 {
8597 /* Let the name lookup machinery know that we are processing a
8598 class member access expression. */
8599 parser->context->object_type = scope;
8600 /* If something went wrong, we want to be able to discern that case,
8601 as opposed to the case where there was no SCOPE due to the type
8602 of expression being dependent. */
8603 if (!scope)
8604 scope = error_mark_node;
8605 /* If the SCOPE was erroneous, make the various semantic analysis
8606 functions exit quickly -- and without issuing additional error
8607 messages. */
8608 if (scope == error_mark_node)
8609 postfix_expression = error_mark_node;
8610 }
8611 }
8612
8613 if (dependent_p)
8614 {
8615 tree type = TREE_TYPE (postfix_expression);
8616 /* If we don't have a (type-dependent) object of class type, use
8617 typeof to figure out the type of the object. */
8618 if (type == NULL_TREE || is_auto (type))
8619 type = finish_typeof (postfix_expression);
8620 parser->context->object_type = type;
8621 }
8622
8623 /* Assume this expression is not a pseudo-destructor access. */
8624 pseudo_destructor_p = false;
8625
8626 /* If the SCOPE is a scalar type, then, if this is a valid program,
8627 we must be looking at a pseudo-destructor-name. If POSTFIX_EXPRESSION
8628 is type dependent, it can be pseudo-destructor-name or something else.
8629 Try to parse it as pseudo-destructor-name first. */
8630 if ((scope && SCALAR_TYPE_P (scope)) || dependent_p)
8631 {
8632 tree s;
8633 tree type;
8634
8635 cp_parser_parse_tentatively (parser);
8636 /* Parse the pseudo-destructor-name. */
8637 s = NULL_TREE;
8638 cp_parser_pseudo_destructor_name (parser, postfix_expression,
8639 &s, &type);
8640 if (dependent_p
8641 && (cp_parser_error_occurred (parser)
8642 || !SCALAR_TYPE_P (type)))
8643 cp_parser_abort_tentative_parse (parser);
8644 else if (cp_parser_parse_definitely (parser))
8645 {
8646 pseudo_destructor_p = true;
8647 postfix_expression
8648 = finish_pseudo_destructor_expr (postfix_expression,
8649 s, type, location);
8650 }
8651 }
8652
8653 if (!pseudo_destructor_p)
8654 {
8655 /* If the SCOPE is not a scalar type, we are looking at an
8656 ordinary class member access expression, rather than a
8657 pseudo-destructor-name. */
8658 bool template_p;
8659 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
8660 /* Parse the id-expression. */
8661 name = (cp_parser_id_expression
8662 (parser,
8663 template_keyword_p: cp_parser_optional_template_keyword (parser),
8664 /*check_dependency_p=*/true,
8665 template_p: &template_p,
8666 /*declarator_p=*/false,
8667 /*optional_p=*/false));
8668 /* In general, build a SCOPE_REF if the member name is qualified.
8669 However, if the name was not dependent and has already been
8670 resolved; there is no need to build the SCOPE_REF. For example;
8671
8672 struct X { void f(); };
8673 template <typename T> void f(T* t) { t->X::f(); }
8674
8675 Even though "t" is dependent, "X::f" is not and has been resolved
8676 to a BASELINK; there is no need to include scope information. */
8677
8678 /* But we do need to remember that there was an explicit scope for
8679 virtual function calls. */
8680 if (parser->scope)
8681 *idk = CP_ID_KIND_QUALIFIED;
8682
8683 /* If the name is a template-id that names a type, we will get a
8684 TYPE_DECL here. That is invalid code. */
8685 if (TREE_CODE (name) == TYPE_DECL)
8686 {
8687 error_at (token->location, "invalid use of %qD", name);
8688 postfix_expression = error_mark_node;
8689 }
8690 else
8691 {
8692 if (name != error_mark_node && !BASELINK_P (name) && parser->scope)
8693 {
8694 if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
8695 {
8696 error_at (token->location, "%<%D::%D%> is not a class member",
8697 parser->scope, name);
8698 postfix_expression = error_mark_node;
8699 }
8700 else
8701 name = build_qualified_name (/*type=*/NULL_TREE,
8702 parser->scope,
8703 name,
8704 template_p);
8705 parser->scope = NULL_TREE;
8706 parser->qualifying_scope = NULL_TREE;
8707 parser->object_scope = NULL_TREE;
8708 }
8709 if (parser->scope && name && BASELINK_P (name))
8710 adjust_result_of_qualified_name_lookup
8711 (name, parser->scope, scope);
8712 postfix_expression
8713 = finish_class_member_access_expr (postfix_expression, name,
8714 template_p,
8715 tf_warning_or_error);
8716 /* Build a location e.g.:
8717 ptr->access_expr
8718 ~~~^~~~~~~~~~~~~
8719 where the caret is at the deref token, ranging from
8720 the start of postfix_expression to the end of the access expr. */
8721 location_t combined_loc
8722 = make_location (caret: input_location, start: start_loc, lexer: parser->lexer);
8723 protected_set_expr_location (postfix_expression, combined_loc);
8724 }
8725 }
8726
8727 /* We no longer need to look up names in the scope of the object on
8728 the left-hand side of the `.' or `->' operator. */
8729 parser->context->object_type = NULL_TREE;
8730
8731 /* Outside of offsetof, these operators may not appear in
8732 constant-expressions. */
8733 if (!for_offsetof
8734 && (cp_parser_non_integral_constant_expression
8735 (parser, thing: token_type == CPP_DEREF ? NIC_ARROW : NIC_POINT)))
8736 postfix_expression = error_mark_node;
8737
8738 return postfix_expression;
8739}
8740
8741/* Parse a parenthesized expression-list.
8742
8743 expression-list:
8744 assignment-expression
8745 expression-list, assignment-expression
8746
8747 attribute-list:
8748 expression-list
8749 identifier
8750 identifier, expression-list
8751
8752 CAST_P is true if this expression is the target of a cast.
8753
8754 ALLOW_EXPANSION_P is true if this expression allows expansion of an
8755 argument pack.
8756
8757 WRAP_LOCATIONS_P is true if expressions within this list for which
8758 CAN_HAVE_LOCATION_P is false should be wrapped with nodes expressing
8759 their source locations.
8760
8761 Returns a vector of trees. Each element is a representation of an
8762 assignment-expression. NULL is returned if the ( and or ) are
8763 missing. An empty, but allocated, vector is returned on no
8764 expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is id_attr
8765 if we are parsing an attribute list for an attribute that wants a
8766 plain identifier argument, normal_attr for an attribute that wants
8767 an expression, or non_attr if we aren't parsing an attribute list. If
8768 NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
8769 not all of the expressions in the list were constant.
8770 If CLOSE_PAREN_LOC is non-NULL, and no errors occur, then *CLOSE_PAREN_LOC
8771 will be written to with the location of the closing parenthesis. If
8772 an error occurs, it may or may not be written to. */
8773
8774static vec<tree, va_gc> *
8775cp_parser_parenthesized_expression_list (cp_parser* parser,
8776 int is_attribute_list,
8777 bool cast_p,
8778 bool allow_expansion_p,
8779 bool *non_constant_p,
8780 location_t *close_paren_loc,
8781 bool wrap_locations_p)
8782{
8783 vec<tree, va_gc> *expression_list;
8784 bool saved_greater_than_is_operator_p;
8785 bool saved_omp_array_section_p;
8786
8787 /* Assume all the expressions will be constant. */
8788 if (non_constant_p)
8789 *non_constant_p = false;
8790
8791 matching_parens parens;
8792 if (!parens.require_open (parser))
8793 return NULL;
8794
8795 expression_list = make_tree_vector ();
8796
8797 /* Within a parenthesized expression, a `>' token is always
8798 the greater-than operator. */
8799 saved_greater_than_is_operator_p
8800 = parser->greater_than_is_operator_p;
8801 parser->greater_than_is_operator_p = true;
8802
8803 saved_omp_array_section_p = parser->omp_array_section_p;
8804 parser->omp_array_section_p = false;
8805
8806 cp_expr expr (NULL_TREE);
8807
8808 /* Consume expressions until there are no more. */
8809 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
8810 while (true)
8811 {
8812 /* At the beginning of attribute lists, check to see if the
8813 next token is an identifier. */
8814 if (is_attribute_list == id_attr
8815 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_NAME)
8816 expr = cp_lexer_consume_token (lexer: parser->lexer)->u.value;
8817 else if (is_attribute_list == assume_attr)
8818 expr = cp_parser_conditional_expression (parser);
8819 else if (is_attribute_list == uneval_string_attr)
8820 expr = cp_parser_unevaluated_string_literal (parser);
8821 else
8822 expr
8823 = cp_parser_parenthesized_expression_list_elt (parser, cast_p,
8824 allow_expansion_p,
8825 non_constant_p);
8826
8827 if (wrap_locations_p)
8828 expr.maybe_add_location_wrapper ();
8829
8830 /* Add it to the list. We add error_mark_node
8831 expressions to the list, so that we can still tell if
8832 the correct form for a parenthesized expression-list
8833 is found. That gives better errors. */
8834 vec_safe_push (v&: expression_list, obj: expr.get_value ());
8835
8836 if (expr == error_mark_node)
8837 goto skip_comma;
8838
8839 /* After the first item, attribute lists look the same as
8840 expression lists. */
8841 is_attribute_list = non_attr;
8842
8843 get_comma:;
8844 /* If the next token isn't a `,', then we are done. */
8845 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
8846 break;
8847
8848 /* Otherwise, consume the `,' and keep going. */
8849 cp_lexer_consume_token (lexer: parser->lexer);
8850 }
8851
8852 if (close_paren_loc)
8853 *close_paren_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
8854
8855 if (!parens.require_close (parser))
8856 {
8857 int ending;
8858
8859 skip_comma:;
8860 /* We try and resync to an unnested comma, as that will give the
8861 user better diagnostics. */
8862 ending = cp_parser_skip_to_closing_parenthesis (parser,
8863 /*recovering=*/true,
8864 /*or_comma=*/true,
8865 /*consume_paren=*/true);
8866 if (ending < 0)
8867 goto get_comma;
8868 if (!ending)
8869 {
8870 parser->greater_than_is_operator_p
8871 = saved_greater_than_is_operator_p;
8872 parser->omp_array_section_p = saved_omp_array_section_p;
8873 return NULL;
8874 }
8875 }
8876
8877 parser->greater_than_is_operator_p
8878 = saved_greater_than_is_operator_p;
8879 parser->omp_array_section_p = saved_omp_array_section_p;
8880
8881 return expression_list;
8882}
8883
8884/* Parse a pseudo-destructor-name.
8885
8886 pseudo-destructor-name:
8887 :: [opt] nested-name-specifier [opt] type-name :: ~ type-name
8888 :: [opt] nested-name-specifier template template-id :: ~ type-name
8889 :: [opt] nested-name-specifier [opt] ~ type-name
8890
8891 If either of the first two productions is used, sets *SCOPE to the
8892 TYPE specified before the final `::'. Otherwise, *SCOPE is set to
8893 NULL_TREE. *TYPE is set to the TYPE_DECL for the final type-name,
8894 or ERROR_MARK_NODE if the parse fails. */
8895
8896static void
8897cp_parser_pseudo_destructor_name (cp_parser* parser,
8898 tree object,
8899 tree* scope,
8900 tree* type)
8901{
8902 bool nested_name_specifier_p;
8903
8904 /* Handle ~auto. */
8905 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMPL)
8906 && cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_AUTO)
8907 && !type_dependent_expression_p (object))
8908 {
8909 if (cxx_dialect < cxx14)
8910 pedwarn (input_location, OPT_Wc__14_extensions,
8911 "%<~auto%> only available with "
8912 "%<-std=c++14%> or %<-std=gnu++14%>");
8913 cp_lexer_consume_token (lexer: parser->lexer);
8914 cp_lexer_consume_token (lexer: parser->lexer);
8915 *scope = NULL_TREE;
8916 *type = TREE_TYPE (object);
8917 return;
8918 }
8919
8920 /* Assume that things will not work out. */
8921 *type = error_mark_node;
8922
8923 /* Look for the optional `::' operator. */
8924 cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/true);
8925 /* Look for the optional nested-name-specifier. */
8926 nested_name_specifier_p
8927 = (cp_parser_nested_name_specifier_opt (parser,
8928 /*typename_keyword_p=*/false,
8929 /*check_dependency_p=*/true,
8930 /*type_p=*/false,
8931 /*is_declaration=*/false)
8932 != NULL_TREE);
8933 /* Now, if we saw a nested-name-specifier, we might be doing the
8934 second production. */
8935 if (nested_name_specifier_p
8936 && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TEMPLATE))
8937 {
8938 /* Consume the `template' keyword. */
8939 cp_lexer_consume_token (lexer: parser->lexer);
8940 /* Parse the template-id. */
8941 cp_parser_template_id (parser,
8942 /*template_keyword_p=*/true,
8943 /*check_dependency_p=*/false,
8944 class_type,
8945 /*is_declaration=*/true);
8946 /* Look for the `::' token. */
8947 cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
8948 }
8949 /* If the next token is not a `~', then there might be some
8950 additional qualification. */
8951 else if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMPL))
8952 {
8953 /* At this point, we're looking for "type-name :: ~". The type-name
8954 must not be a class-name, since this is a pseudo-destructor. So,
8955 it must be either an enum-name, or a typedef-name -- both of which
8956 are just identifiers. So, we peek ahead to check that the "::"
8957 and "~" tokens are present; if they are not, then we can avoid
8958 calling type_name. */
8959 if (cp_lexer_peek_token (lexer: parser->lexer)->type != CPP_NAME
8960 || cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type != CPP_SCOPE
8961 || cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type != CPP_COMPL)
8962 {
8963 cp_parser_error (parser, gmsgid: "non-scalar type");
8964 return;
8965 }
8966
8967 /* Look for the type-name. */
8968 *scope = TREE_TYPE (cp_parser_nonclass_name (parser));
8969 if (*scope == error_mark_node)
8970 return;
8971
8972 /* Look for the `::' token. */
8973 cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
8974 }
8975 else
8976 *scope = NULL_TREE;
8977
8978 /* Look for the `~'. */
8979 cp_parser_require (parser, CPP_COMPL, RT_COMPL);
8980
8981 /* Once we see the ~, this has to be a pseudo-destructor. */
8982 if (!processing_template_decl && !cp_parser_error_occurred (parser))
8983 cp_parser_commit_to_topmost_tentative_parse (parser);
8984
8985 /* Look for the type-name again. We are not responsible for
8986 checking that it matches the first type-name. */
8987 *type = TREE_TYPE (cp_parser_nonclass_name (parser));
8988}
8989
8990/* Parse a unary-expression.
8991
8992 unary-expression:
8993 postfix-expression
8994 ++ cast-expression
8995 -- cast-expression
8996 await-expression
8997 unary-operator cast-expression
8998 sizeof unary-expression
8999 sizeof ( type-id )
9000 alignof ( type-id ) [C++0x]
9001 new-expression
9002 delete-expression
9003
9004 GNU Extensions:
9005
9006 unary-expression:
9007 __extension__ cast-expression
9008 __alignof__ unary-expression
9009 __alignof__ ( type-id )
9010 alignof unary-expression [C++0x]
9011 __real__ cast-expression
9012 __imag__ cast-expression
9013 && identifier
9014 sizeof ( type-id ) { initializer-list , [opt] }
9015 alignof ( type-id ) { initializer-list , [opt] } [C++0x]
9016 __alignof__ ( type-id ) { initializer-list , [opt] }
9017
9018 ADDRESS_P is true iff the unary-expression is appearing as the
9019 operand of the `&' operator. CAST_P is true if this expression is
9020 the target of a cast.
9021
9022 Returns a representation of the expression. */
9023
9024static cp_expr
9025cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
9026 bool address_p, bool cast_p, bool decltype_p)
9027{
9028 cp_token *token;
9029 enum tree_code unary_operator;
9030
9031 /* Peek at the next token. */
9032 token = cp_lexer_peek_token (lexer: parser->lexer);
9033 /* Some keywords give away the kind of expression. */
9034 if (token->type == CPP_KEYWORD)
9035 {
9036 enum rid keyword = token->keyword;
9037
9038 switch (keyword)
9039 {
9040 case RID_ALIGNOF:
9041 case RID_SIZEOF:
9042 {
9043 tree operand, ret;
9044 enum tree_code op;
9045 location_t start_loc = token->location;
9046
9047 op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
9048 bool std_alignof = id_equal (id: token->u.value, str: "alignof");
9049
9050 /* Consume the token. */
9051 cp_lexer_consume_token (lexer: parser->lexer);
9052 /* Parse the operand. */
9053 operand = cp_parser_sizeof_operand (parser, keyword);
9054
9055 /* Construct a location e.g. :
9056 alignof (expr)
9057 ^~~~~~~~~~~~~~
9058 with start == caret at the start of the "alignof"/"sizeof"
9059 token, with the endpoint at the final closing paren. */
9060 location_t compound_loc
9061 = make_location (caret: start_loc, start: start_loc, lexer: parser->lexer);
9062
9063 if (TYPE_P (operand))
9064 ret = cxx_sizeof_or_alignof_type (compound_loc, operand, op,
9065 std_alignof, true);
9066 else
9067 {
9068 /* ISO C++ defines alignof only with types, not with
9069 expressions. So pedwarn if alignof is used with a non-
9070 type expression. However, __alignof__ is ok. */
9071 if (std_alignof)
9072 pedwarn (token->location, OPT_Wpedantic,
9073 "ISO C++ does not allow %<alignof%> "
9074 "with a non-type");
9075
9076 ret = cxx_sizeof_or_alignof_expr (compound_loc, operand, op,
9077 std_alignof, true);
9078 }
9079 /* For SIZEOF_EXPR, just issue diagnostics, but keep
9080 SIZEOF_EXPR with the original operand. */
9081 if (op == SIZEOF_EXPR && ret != error_mark_node)
9082 {
9083 if (TREE_CODE (ret) != SIZEOF_EXPR || TYPE_P (operand))
9084 {
9085 if (!processing_template_decl && TYPE_P (operand))
9086 {
9087 ret = build_min (SIZEOF_EXPR, size_type_node,
9088 build1 (NOP_EXPR, operand,
9089 error_mark_node));
9090 SIZEOF_EXPR_TYPE_P (ret) = 1;
9091 }
9092 else
9093 ret = build_min (SIZEOF_EXPR, size_type_node, operand);
9094 TREE_SIDE_EFFECTS (ret) = 0;
9095 TREE_READONLY (ret) = 1;
9096 SET_EXPR_LOCATION (ret, compound_loc);
9097 }
9098 }
9099
9100 cp_expr ret_expr (ret, compound_loc);
9101 ret_expr = ret_expr.maybe_add_location_wrapper ();
9102 return ret_expr;
9103 }
9104
9105 case RID_BUILTIN_HAS_ATTRIBUTE:
9106 return cp_parser_has_attribute_expression (parser);
9107
9108 case RID_NEW:
9109 return cp_parser_new_expression (parser);
9110
9111 case RID_DELETE:
9112 return cp_parser_delete_expression (parser);
9113
9114 case RID_EXTENSION:
9115 {
9116 /* The saved value of the PEDANTIC flag. */
9117 int saved_pedantic;
9118 tree expr;
9119
9120 /* Save away the PEDANTIC flag. */
9121 cp_parser_extension_opt (parser, &saved_pedantic);
9122 /* Parse the cast-expression. */
9123 expr = cp_parser_simple_cast_expression (parser);
9124 /* Restore the PEDANTIC flag. */
9125 pedantic = saved_pedantic;
9126
9127 return expr;
9128 }
9129
9130 case RID_REALPART:
9131 case RID_IMAGPART:
9132 {
9133 tree expression;
9134
9135 /* Consume the `__real__' or `__imag__' token. */
9136 cp_lexer_consume_token (lexer: parser->lexer);
9137 /* Parse the cast-expression. */
9138 expression = cp_parser_simple_cast_expression (parser);
9139 /* Create the complete representation. */
9140 return build_x_unary_op (token->location,
9141 (keyword == RID_REALPART
9142 ? REALPART_EXPR : IMAGPART_EXPR),
9143 expression, NULL_TREE,
9144 tf_warning_or_error);
9145 }
9146 break;
9147
9148 case RID_TRANSACTION_ATOMIC:
9149 case RID_TRANSACTION_RELAXED:
9150 return cp_parser_transaction_expression (parser, keyword);
9151
9152 case RID_NOEXCEPT:
9153 {
9154 tree expr;
9155 const char *saved_message;
9156 bool saved_integral_constant_expression_p;
9157 bool saved_non_integral_constant_expression_p;
9158 bool saved_greater_than_is_operator_p;
9159
9160 location_t start_loc = token->location;
9161
9162 cp_lexer_consume_token (lexer: parser->lexer);
9163 matching_parens parens;
9164 parens.require_open (parser);
9165
9166 saved_message = parser->type_definition_forbidden_message;
9167 parser->type_definition_forbidden_message
9168 = G_("types may not be defined in %<noexcept%> expressions");
9169
9170 saved_integral_constant_expression_p
9171 = parser->integral_constant_expression_p;
9172 saved_non_integral_constant_expression_p
9173 = parser->non_integral_constant_expression_p;
9174 parser->integral_constant_expression_p = false;
9175
9176 saved_greater_than_is_operator_p
9177 = parser->greater_than_is_operator_p;
9178 parser->greater_than_is_operator_p = true;
9179
9180 ++cp_unevaluated_operand;
9181 ++c_inhibit_evaluation_warnings;
9182 ++cp_noexcept_operand;
9183 expr = cp_parser_expression (parser);
9184 --cp_noexcept_operand;
9185 --c_inhibit_evaluation_warnings;
9186 --cp_unevaluated_operand;
9187
9188 parser->greater_than_is_operator_p
9189 = saved_greater_than_is_operator_p;
9190
9191 parser->integral_constant_expression_p
9192 = saved_integral_constant_expression_p;
9193 parser->non_integral_constant_expression_p
9194 = saved_non_integral_constant_expression_p;
9195
9196 parser->type_definition_forbidden_message = saved_message;
9197
9198 parens.require_close (parser);
9199
9200 /* Construct a location of the form:
9201 noexcept (expr)
9202 ^~~~~~~~~~~~~~~
9203 with start == caret, finishing at the close-paren. */
9204 location_t noexcept_loc
9205 = make_location (caret: start_loc, start: start_loc, lexer: parser->lexer);
9206
9207 return cp_expr (finish_noexcept_expr (expr, tf_warning_or_error),
9208 noexcept_loc);
9209 }
9210
9211 case RID_CO_AWAIT:
9212 {
9213 tree expr;
9214 location_t kw_loc = token->location;
9215
9216 /* Consume the `co_await' token. */
9217 cp_lexer_consume_token (lexer: parser->lexer);
9218 /* Parse its cast-expression. */
9219 expr = cp_parser_simple_cast_expression (parser);
9220 if (expr == error_mark_node)
9221 return error_mark_node;
9222
9223 /* Handle [expr.await]. */
9224 return cp_expr (finish_co_await_expr (kw_loc, expr));
9225 }
9226
9227 default:
9228 break;
9229 }
9230 }
9231
9232 /* Look for the `:: new' and `:: delete', which also signal the
9233 beginning of a new-expression, or delete-expression,
9234 respectively. If the next token is `::', then it might be one of
9235 these. */
9236 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE))
9237 {
9238 enum rid keyword;
9239
9240 /* See if the token after the `::' is one of the keywords in
9241 which we're interested. */
9242 keyword = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->keyword;
9243 /* If it's `new', we have a new-expression. */
9244 if (keyword == RID_NEW)
9245 return cp_parser_new_expression (parser);
9246 /* Similarly, for `delete'. */
9247 else if (keyword == RID_DELETE)
9248 return cp_parser_delete_expression (parser);
9249 }
9250
9251 /* Look for a unary operator. */
9252 unary_operator = cp_parser_unary_operator (token);
9253 /* The `++' and `--' operators can be handled similarly, even though
9254 they are not technically unary-operators in the grammar. */
9255 if (unary_operator == ERROR_MARK)
9256 {
9257 if (token->type == CPP_PLUS_PLUS)
9258 unary_operator = PREINCREMENT_EXPR;
9259 else if (token->type == CPP_MINUS_MINUS)
9260 unary_operator = PREDECREMENT_EXPR;
9261 /* Handle the GNU address-of-label extension. */
9262 else if (cp_parser_allow_gnu_extensions_p (parser)
9263 && token->type == CPP_AND_AND)
9264 {
9265 tree identifier;
9266 tree expression;
9267 location_t start_loc = token->location;
9268
9269 /* Consume the '&&' token. */
9270 cp_lexer_consume_token (lexer: parser->lexer);
9271 /* Look for the identifier. */
9272 identifier = cp_parser_identifier (parser);
9273 /* Construct a location of the form:
9274 &&label
9275 ^~~~~~~
9276 with caret==start at the "&&", finish at the end of the label. */
9277 location_t combined_loc
9278 = make_location (caret: start_loc, start: start_loc, lexer: parser->lexer);
9279 /* Create an expression representing the address. */
9280 expression = finish_label_address_expr (identifier, combined_loc);
9281 if (TREE_CODE (expression) == ADDR_EXPR)
9282 mark_label_addressed (identifier);
9283 if (cp_parser_non_integral_constant_expression (parser,
9284 thing: NIC_ADDR_LABEL))
9285 expression = error_mark_node;
9286 return expression;
9287 }
9288 }
9289 if (unary_operator != ERROR_MARK)
9290 {
9291 cp_expr cast_expression;
9292 cp_expr expression = error_mark_node;
9293 non_integral_constant non_constant_p = NIC_NONE;
9294 location_t loc = token->location;
9295 tsubst_flags_t complain = complain_flags (decltype_p);
9296
9297 /* Consume the operator token. */
9298 token = cp_lexer_consume_token (lexer: parser->lexer);
9299 enum cpp_ttype op_ttype = cp_lexer_peek_token (lexer: parser->lexer)->type;
9300
9301 /* Parse the cast-expression. */
9302 cast_expression
9303 = cp_parser_cast_expression (parser,
9304 unary_operator == ADDR_EXPR,
9305 /*cast_p=*/false,
9306 /*decltype*/false,
9307 pidk);
9308
9309 /* Make a location:
9310 OP_TOKEN CAST_EXPRESSION
9311 ^~~~~~~~~~~~~~~~~~~~~~~~~
9312 with start==caret at the operator token, and
9313 extending to the end of the cast_expression. */
9314 loc = make_location (caret: loc, start: loc, finish: cast_expression.get_finish ());
9315
9316 /* Now, build an appropriate representation. */
9317 switch (unary_operator)
9318 {
9319 case INDIRECT_REF:
9320 non_constant_p = NIC_STAR;
9321 expression = build_x_indirect_ref (loc, cast_expression,
9322 RO_UNARY_STAR, NULL_TREE,
9323 complain);
9324 /* TODO: build_x_indirect_ref does not always honor the
9325 location, so ensure it is set. */
9326 expression.set_location (loc);
9327 break;
9328
9329 case ADDR_EXPR:
9330 non_constant_p = NIC_ADDR;
9331 /* Fall through. */
9332 case BIT_NOT_EXPR:
9333 expression = build_x_unary_op (loc, unary_operator,
9334 cast_expression,
9335 NULL_TREE, complain);
9336 /* TODO: build_x_unary_op does not always honor the location,
9337 so ensure it is set. */
9338 expression.set_location (loc);
9339 break;
9340
9341 case PREINCREMENT_EXPR:
9342 case PREDECREMENT_EXPR:
9343 non_constant_p = unary_operator == PREINCREMENT_EXPR
9344 ? NIC_PREINCREMENT : NIC_PREDECREMENT;
9345 /* Fall through. */
9346 case NEGATE_EXPR:
9347 /* Immediately fold negation of a constant, unless the constant is 0
9348 (since -0 == 0) or it would overflow. */
9349 if (unary_operator == NEGATE_EXPR && op_ttype == CPP_NUMBER)
9350 {
9351 tree stripped_expr
9352 = tree_strip_any_location_wrapper (exp: cast_expression);
9353 if (CONSTANT_CLASS_P (stripped_expr)
9354 && !integer_zerop (stripped_expr)
9355 && !TREE_OVERFLOW (stripped_expr))
9356 {
9357 tree folded = fold_build1 (unary_operator,
9358 TREE_TYPE (stripped_expr),
9359 stripped_expr);
9360 if (CONSTANT_CLASS_P (folded) && !TREE_OVERFLOW (folded))
9361 {
9362 expression = maybe_wrap_with_location (folded, loc);
9363 break;
9364 }
9365 }
9366 }
9367 /* Fall through. */
9368 case UNARY_PLUS_EXPR:
9369 case TRUTH_NOT_EXPR:
9370 expression = finish_unary_op_expr (loc, unary_operator,
9371 cast_expression, complain);
9372 break;
9373
9374 default:
9375 gcc_unreachable ();
9376 }
9377
9378 if (non_constant_p != NIC_NONE
9379 && cp_parser_non_integral_constant_expression (parser,
9380 thing: non_constant_p))
9381 expression = error_mark_node;
9382
9383 return expression;
9384 }
9385
9386 return cp_parser_postfix_expression (parser, address_p, cast_p,
9387 /*member_access_only_p=*/false,
9388 decltype_p,
9389 pidk_return: pidk);
9390}
9391
9392/* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a
9393 unary-operator, the corresponding tree code is returned. */
9394
9395static enum tree_code
9396cp_parser_unary_operator (cp_token* token)
9397{
9398 switch (token->type)
9399 {
9400 case CPP_MULT:
9401 return INDIRECT_REF;
9402
9403 case CPP_AND:
9404 return ADDR_EXPR;
9405
9406 case CPP_PLUS:
9407 return UNARY_PLUS_EXPR;
9408
9409 case CPP_MINUS:
9410 return NEGATE_EXPR;
9411
9412 case CPP_NOT:
9413 return TRUTH_NOT_EXPR;
9414
9415 case CPP_COMPL:
9416 return BIT_NOT_EXPR;
9417
9418 default:
9419 return ERROR_MARK;
9420 }
9421}
9422
9423/* Parse a __builtin_has_attribute([expr|type], attribute-spec) expression.
9424 Returns a representation of the expression. */
9425
9426static tree
9427cp_parser_has_attribute_expression (cp_parser *parser)
9428{
9429 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
9430
9431 /* Consume the __builtin_has_attribute token. */
9432 cp_lexer_consume_token (lexer: parser->lexer);
9433
9434 matching_parens parens;
9435 if (!parens.require_open (parser))
9436 return error_mark_node;
9437
9438 /* Types cannot be defined in a `sizeof' expression. Save away the
9439 old message. */
9440 const char *saved_message = parser->type_definition_forbidden_message;
9441 const char *saved_message_arg
9442 = parser->type_definition_forbidden_message_arg;
9443 parser->type_definition_forbidden_message
9444 = G_("types may not be defined in %qs expressions");
9445 parser->type_definition_forbidden_message_arg
9446 = IDENTIFIER_POINTER (ridpointers[RID_BUILTIN_HAS_ATTRIBUTE]);
9447
9448 /* The restrictions on constant-expressions do not apply inside
9449 sizeof expressions. */
9450 bool saved_integral_constant_expression_p
9451 = parser->integral_constant_expression_p;
9452 bool saved_non_integral_constant_expression_p
9453 = parser->non_integral_constant_expression_p;
9454 parser->integral_constant_expression_p = false;
9455
9456 /* Do not actually evaluate the expression. */
9457 ++cp_unevaluated_operand;
9458 ++c_inhibit_evaluation_warnings;
9459
9460 tree oper = NULL_TREE;
9461
9462 /* We can't be sure yet whether we're looking at a type-id or an
9463 expression. */
9464 cp_parser_parse_tentatively (parser);
9465
9466 bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
9467 parser->in_type_id_in_expr_p = true;
9468 /* Look for the type-id. */
9469 oper = cp_parser_type_id (parser);
9470 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
9471
9472 cp_parser_parse_definitely (parser);
9473
9474 /* If the type-id production did not work out, then we must be
9475 looking at an expression. */
9476 if (!oper || oper == error_mark_node)
9477 oper = cp_parser_assignment_expression (parser);
9478
9479 STRIP_ANY_LOCATION_WRAPPER (oper);
9480
9481 /* Go back to evaluating expressions. */
9482 --cp_unevaluated_operand;
9483 --c_inhibit_evaluation_warnings;
9484
9485 /* And restore the old one. */
9486 parser->type_definition_forbidden_message = saved_message;
9487 parser->type_definition_forbidden_message_arg = saved_message_arg;
9488 parser->integral_constant_expression_p
9489 = saved_integral_constant_expression_p;
9490 parser->non_integral_constant_expression_p
9491 = saved_non_integral_constant_expression_p;
9492
9493 /* Consume the comma if it's there. */
9494 if (!cp_parser_require (parser, CPP_COMMA, RT_COMMA))
9495 {
9496 cp_parser_skip_to_closing_parenthesis (parser, recovering: false, or_comma: false,
9497 /*consume_paren=*/true);
9498 return error_mark_node;
9499 }
9500
9501 /* Parse the attribute specification. */
9502 bool ret = false;
9503 location_t atloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
9504 if (tree attr = cp_parser_gnu_attribute_list (parser, /*exactly_one=*/true))
9505 {
9506 if (oper == error_mark_node)
9507 /* Nothing. */;
9508 else if (processing_template_decl && uses_template_parms (oper))
9509 sorry_at (atloc, "%<__builtin_has_attribute%> with dependent argument "
9510 "not supported yet");
9511 else
9512 {
9513 /* Fold constant expressions used in attributes first. */
9514 cp_check_const_attributes (attr);
9515
9516 /* Finally, see if OPER has been declared with ATTR. */
9517 ret = has_attribute (atloc, oper, attr, default_conversion);
9518 }
9519
9520 parens.require_close (parser);
9521 }
9522 else
9523 {
9524 error_at (atloc, "expected identifier");
9525 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false, consume_paren: true);
9526 }
9527
9528 /* Construct a location e.g. :
9529 __builtin_has_attribute (oper, attr)
9530 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9531 with start == caret at the start of the built-in token,
9532 and with the endpoint at the final closing paren. */
9533 location_t compound_loc
9534 = make_location (caret: start_loc, start: start_loc, lexer: parser->lexer);
9535
9536 cp_expr ret_expr (ret ? boolean_true_node : boolean_false_node);
9537 ret_expr.set_location (compound_loc);
9538 ret_expr = ret_expr.maybe_add_location_wrapper ();
9539 return ret_expr;
9540}
9541
9542/* Parse a new-expression.
9543
9544 new-expression:
9545 :: [opt] new new-placement [opt] new-type-id new-initializer [opt]
9546 :: [opt] new new-placement [opt] ( type-id ) new-initializer [opt]
9547
9548 Returns a representation of the expression. */
9549
9550static tree
9551cp_parser_new_expression (cp_parser* parser)
9552{
9553 bool global_scope_p;
9554 vec<tree, va_gc> *placement;
9555 tree type;
9556 vec<tree, va_gc> *initializer;
9557 tree nelts = NULL_TREE;
9558 tree ret;
9559
9560 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
9561
9562 /* Look for the optional `::' operator. */
9563 global_scope_p
9564 = (cp_parser_global_scope_opt (parser,
9565 /*current_scope_valid_p=*/false)
9566 != NULL_TREE);
9567 /* Look for the `new' operator. */
9568 cp_parser_require_keyword (parser, RID_NEW, RT_NEW);
9569 /* There's no easy way to tell a new-placement from the
9570 `( type-id )' construct. */
9571 cp_parser_parse_tentatively (parser);
9572 /* Look for a new-placement. */
9573 placement = cp_parser_new_placement (parser);
9574 /* If that didn't work out, there's no new-placement. */
9575 if (!cp_parser_parse_definitely (parser))
9576 {
9577 if (placement != NULL)
9578 release_tree_vector (placement);
9579 placement = NULL;
9580 }
9581
9582 /* If the next token is a `(', then we have a parenthesized
9583 type-id. */
9584 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
9585 {
9586 cp_token *token;
9587 const char *saved_message = parser->type_definition_forbidden_message;
9588
9589 /* Consume the `('. */
9590 matching_parens parens;
9591 parens.consume_open (parser);
9592
9593 /* Parse the type-id. */
9594 parser->type_definition_forbidden_message
9595 = G_("types may not be defined in a new-expression");
9596 {
9597 type_id_in_expr_sentinel s (parser);
9598 type = cp_parser_type_id (parser);
9599 }
9600 parser->type_definition_forbidden_message = saved_message;
9601
9602 /* Look for the closing `)'. */
9603 parens.require_close (parser);
9604 token = cp_lexer_peek_token (lexer: parser->lexer);
9605 /* There should not be a direct-new-declarator in this production,
9606 but GCC used to allowed this, so we check and emit a sensible error
9607 message for this case. */
9608 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
9609 {
9610 error_at (token->location,
9611 "array bound forbidden after parenthesized type-id");
9612 inform (token->location,
9613 "try removing the parentheses around the type-id");
9614 cp_parser_direct_new_declarator (parser);
9615 }
9616 }
9617 /* Otherwise, there must be a new-type-id. */
9618 else
9619 type = cp_parser_new_type_id (parser, &nelts);
9620
9621 /* If the next token is a `(' or '{', then we have a new-initializer. */
9622 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
9623 if (token->type == CPP_OPEN_PAREN
9624 || token->type == CPP_OPEN_BRACE)
9625 initializer = cp_parser_new_initializer (parser);
9626 else
9627 initializer = NULL;
9628
9629 /* A new-expression may not appear in an integral constant
9630 expression. */
9631 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_NEW))
9632 ret = error_mark_node;
9633 /* 5.3.4/2: "If the auto type-specifier appears in the type-specifier-seq
9634 of a new-type-id or type-id of a new-expression, the new-expression shall
9635 contain a new-initializer of the form ( assignment-expression )".
9636 Additionally, consistently with the spirit of DR 1467, we want to accept
9637 'new auto { 2 }' too. */
9638 else if ((ret = type_uses_auto (type))
9639 && !CLASS_PLACEHOLDER_TEMPLATE (ret)
9640 && (vec_safe_length (v: initializer) != 1
9641 || (BRACE_ENCLOSED_INITIALIZER_P ((*initializer)[0])
9642 && CONSTRUCTOR_NELTS ((*initializer)[0]) != 1)))
9643 {
9644 error_at (token->location,
9645 "initialization of new-expression for type %<auto%> "
9646 "requires exactly one element");
9647 ret = error_mark_node;
9648 }
9649 else
9650 {
9651 /* Construct a location e.g.:
9652 ptr = new int[100]
9653 ^~~~~~~~~~~~
9654 with caret == start at the start of the "new" token, and the end
9655 at the end of the final token we consumed. */
9656 location_t combined_loc = make_location (caret: start_loc, start: start_loc,
9657 lexer: parser->lexer);
9658 /* Create a representation of the new-expression. */
9659 ret = build_new (combined_loc, &placement, type, nelts, &initializer,
9660 global_scope_p, tf_warning_or_error);
9661 }
9662
9663 if (placement != NULL)
9664 release_tree_vector (placement);
9665 if (initializer != NULL)
9666 release_tree_vector (initializer);
9667
9668 return ret;
9669}
9670
9671/* Parse a new-placement.
9672
9673 new-placement:
9674 ( expression-list )
9675
9676 Returns the same representation as for an expression-list. */
9677
9678static vec<tree, va_gc> *
9679cp_parser_new_placement (cp_parser* parser)
9680{
9681 vec<tree, va_gc> *expression_list;
9682
9683 /* Parse the expression-list. */
9684 expression_list = (cp_parser_parenthesized_expression_list
9685 (parser, is_attribute_list: non_attr, /*cast_p=*/false,
9686 /*allow_expansion_p=*/true,
9687 /*non_constant_p=*/NULL));
9688
9689 if (expression_list && expression_list->is_empty ())
9690 error ("expected expression-list or type-id");
9691
9692 return expression_list;
9693}
9694
9695/* Parse a new-type-id.
9696
9697 new-type-id:
9698 type-specifier-seq new-declarator [opt]
9699
9700 Returns the TYPE allocated. If the new-type-id indicates an array
9701 type, *NELTS is set to the number of elements in the last array
9702 bound; the TYPE will not include the last array bound. */
9703
9704static tree
9705cp_parser_new_type_id (cp_parser* parser, tree *nelts)
9706{
9707 cp_decl_specifier_seq type_specifier_seq;
9708 cp_declarator *new_declarator;
9709 cp_declarator *declarator;
9710 cp_declarator *outer_declarator;
9711 const char *saved_message;
9712
9713 /* The type-specifier sequence must not contain type definitions.
9714 (It cannot contain declarations of new types either, but if they
9715 are not definitions we will catch that because they are not
9716 complete.) */
9717 saved_message = parser->type_definition_forbidden_message;
9718 parser->type_definition_forbidden_message
9719 = G_("types may not be defined in a new-type-id");
9720 /* Parse the type-specifier-seq. */
9721 cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
9722 /*is_declaration=*/false,
9723 /*is_trailing_return=*/false,
9724 &type_specifier_seq);
9725 /* Restore the old message. */
9726 parser->type_definition_forbidden_message = saved_message;
9727
9728 if (type_specifier_seq.type == error_mark_node)
9729 return error_mark_node;
9730
9731 /* Parse the new-declarator. */
9732 new_declarator = cp_parser_new_declarator_opt (parser);
9733
9734 /* Determine the number of elements in the last array dimension, if
9735 any. */
9736 *nelts = NULL_TREE;
9737 /* Skip down to the last array dimension. */
9738 declarator = new_declarator;
9739 outer_declarator = NULL;
9740 while (declarator && (declarator->kind == cdk_pointer
9741 || declarator->kind == cdk_ptrmem))
9742 {
9743 outer_declarator = declarator;
9744 declarator = declarator->declarator;
9745 }
9746 while (declarator
9747 && declarator->kind == cdk_array
9748 && declarator->declarator
9749 && declarator->declarator->kind == cdk_array)
9750 {
9751 outer_declarator = declarator;
9752 declarator = declarator->declarator;
9753 }
9754
9755 if (declarator && declarator->kind == cdk_array)
9756 {
9757 *nelts = declarator->u.array.bounds;
9758 if (*nelts == error_mark_node)
9759 *nelts = integer_one_node;
9760
9761 if (*nelts == NULL_TREE)
9762 /* Leave [] in the declarator. */;
9763 else if (outer_declarator)
9764 outer_declarator->declarator = declarator->declarator;
9765 else
9766 new_declarator = NULL;
9767 }
9768
9769 return groktypename (&type_specifier_seq, new_declarator, false);
9770}
9771
9772/* Parse an (optional) new-declarator.
9773
9774 new-declarator:
9775 ptr-operator new-declarator [opt]
9776 direct-new-declarator
9777
9778 Returns the declarator. */
9779
9780static cp_declarator *
9781cp_parser_new_declarator_opt (cp_parser* parser)
9782{
9783 enum tree_code code;
9784 tree type, std_attributes = NULL_TREE;
9785 cp_cv_quals cv_quals;
9786
9787 /* We don't know if there's a ptr-operator next, or not. */
9788 cp_parser_parse_tentatively (parser);
9789 /* Look for a ptr-operator. */
9790 code = cp_parser_ptr_operator (parser, &type, &cv_quals, &std_attributes);
9791 /* If that worked, look for more new-declarators. */
9792 if (cp_parser_parse_definitely (parser))
9793 {
9794 cp_declarator *declarator;
9795
9796 /* Parse another optional declarator. */
9797 declarator = cp_parser_new_declarator_opt (parser);
9798
9799 declarator = cp_parser_make_indirect_declarator
9800 (code, class_type: type, cv_qualifiers: cv_quals, target: declarator, attributes: std_attributes);
9801
9802 return declarator;
9803 }
9804
9805 /* If the next token is a `[', there is a direct-new-declarator. */
9806 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
9807 return cp_parser_direct_new_declarator (parser);
9808
9809 return NULL;
9810}
9811
9812/* Parse a direct-new-declarator.
9813
9814 direct-new-declarator:
9815 [ expression ]
9816 direct-new-declarator [constant-expression]
9817
9818 */
9819
9820static cp_declarator *
9821cp_parser_direct_new_declarator (cp_parser* parser)
9822{
9823 cp_declarator *declarator = NULL;
9824 bool first_p = true;
9825
9826 while (true)
9827 {
9828 tree expression;
9829 cp_token *token;
9830
9831 /* Look for the opening `['. */
9832 cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
9833
9834 token = cp_lexer_peek_token (lexer: parser->lexer);
9835 if (token->type == CPP_CLOSE_SQUARE && first_p)
9836 expression = NULL_TREE;
9837 else
9838 expression = cp_parser_expression (parser);
9839 /* The standard requires that the expression have integral
9840 type. DR 74 adds enumeration types. We believe that the
9841 real intent is that these expressions be handled like the
9842 expression in a `switch' condition, which also allows
9843 classes with a single conversion to integral or
9844 enumeration type. */
9845 if (expression && !processing_template_decl)
9846 {
9847 expression
9848 = build_expr_type_conversion (WANT_INT | WANT_ENUM,
9849 expression,
9850 /*complain=*/true);
9851 if (!expression)
9852 {
9853 error_at (token->location,
9854 "expression in new-declarator must have integral "
9855 "or enumeration type");
9856 expression = error_mark_node;
9857 }
9858 }
9859
9860 /* Look for the closing `]'. */
9861 cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
9862
9863 /* Add this bound to the declarator. */
9864 declarator = make_array_declarator (element: declarator, bounds: expression);
9865
9866 /* If the next token is not a `[', then there are no more
9867 bounds. */
9868 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
9869 break;
9870 first_p = false;
9871 }
9872
9873 return declarator;
9874}
9875
9876/* Parse a new-initializer.
9877
9878 new-initializer:
9879 ( expression-list [opt] )
9880 braced-init-list
9881
9882 Returns a representation of the expression-list. */
9883
9884static vec<tree, va_gc> *
9885cp_parser_new_initializer (cp_parser* parser)
9886{
9887 vec<tree, va_gc> *expression_list;
9888
9889 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
9890 {
9891 cp_lexer_set_source_position (lexer: parser->lexer);
9892 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
9893 tree t = cp_parser_braced_list (parser);
9894 CONSTRUCTOR_IS_DIRECT_INIT (t) = true;
9895 expression_list = make_tree_vector_single (t);
9896 }
9897 else
9898 expression_list = (cp_parser_parenthesized_expression_list
9899 (parser, is_attribute_list: non_attr, /*cast_p=*/false,
9900 /*allow_expansion_p=*/true,
9901 /*non_constant_p=*/NULL));
9902
9903 return expression_list;
9904}
9905
9906/* Parse a delete-expression.
9907
9908 delete-expression:
9909 :: [opt] delete cast-expression
9910 :: [opt] delete [ ] cast-expression
9911
9912 Returns a representation of the expression. */
9913
9914static tree
9915cp_parser_delete_expression (cp_parser* parser)
9916{
9917 bool global_scope_p;
9918 bool array_p;
9919 tree expression;
9920 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
9921
9922 /* Look for the optional `::' operator. */
9923 global_scope_p
9924 = (cp_parser_global_scope_opt (parser,
9925 /*current_scope_valid_p=*/false)
9926 != NULL_TREE);
9927 /* Look for the `delete' keyword. */
9928 cp_parser_require_keyword (parser, RID_DELETE, RT_DELETE);
9929 /* See if the array syntax is in use. */
9930 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
9931 {
9932 /* Consume the `[' token. */
9933 cp_lexer_consume_token (lexer: parser->lexer);
9934 /* Look for the `]' token. */
9935 cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
9936 /* Remember that this is the `[]' construct. */
9937 array_p = true;
9938 }
9939 else
9940 array_p = false;
9941
9942 /* Parse the cast-expression. */
9943 expression = cp_parser_simple_cast_expression (parser);
9944
9945 /* A delete-expression may not appear in an integral constant
9946 expression. */
9947 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_DEL))
9948 return error_mark_node;
9949
9950 /* Construct a location e.g.:
9951 delete [ ] ptr
9952 ^~~~~~~~~~~~~~
9953 with caret == start at the start of the "delete" token, and
9954 the end at the end of the final token we consumed. */
9955 location_t combined_loc = make_location (caret: start_loc, start: start_loc,
9956 lexer: parser->lexer);
9957 expression = delete_sanity (combined_loc, expression, NULL_TREE, array_p,
9958 global_scope_p, tf_warning_or_error);
9959
9960 return expression;
9961}
9962
9963/* Returns 1 if TOKEN may start a cast-expression and isn't '++', '--',
9964 neither '[' in C++11; -1 if TOKEN is '++', '--', or '[' in C++11;
9965 0 otherwise. */
9966
9967static int
9968cp_parser_tokens_start_cast_expression (cp_parser *parser)
9969{
9970 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
9971 switch (token->type)
9972 {
9973 case CPP_COMMA:
9974 case CPP_SEMICOLON:
9975 case CPP_QUERY:
9976 case CPP_COLON:
9977 case CPP_CLOSE_SQUARE:
9978 case CPP_CLOSE_PAREN:
9979 case CPP_CLOSE_BRACE:
9980 case CPP_OPEN_BRACE:
9981 case CPP_DOT:
9982 case CPP_DOT_STAR:
9983 case CPP_DEREF:
9984 case CPP_DEREF_STAR:
9985 case CPP_DIV:
9986 case CPP_MOD:
9987 case CPP_LSHIFT:
9988 case CPP_RSHIFT:
9989 case CPP_LESS:
9990 case CPP_GREATER:
9991 case CPP_LESS_EQ:
9992 case CPP_GREATER_EQ:
9993 case CPP_EQ_EQ:
9994 case CPP_NOT_EQ:
9995 case CPP_EQ:
9996 case CPP_MULT_EQ:
9997 case CPP_DIV_EQ:
9998 case CPP_MOD_EQ:
9999 case CPP_PLUS_EQ:
10000 case CPP_MINUS_EQ:
10001 case CPP_RSHIFT_EQ:
10002 case CPP_LSHIFT_EQ:
10003 case CPP_AND_EQ:
10004 case CPP_XOR_EQ:
10005 case CPP_OR_EQ:
10006 case CPP_XOR:
10007 case CPP_OR:
10008 case CPP_OR_OR:
10009 case CPP_EOF:
10010 case CPP_ELLIPSIS:
10011 return 0;
10012
10013 case CPP_OPEN_PAREN:
10014 /* In ((type ()) () the last () isn't a valid cast-expression,
10015 so the whole must be parsed as postfix-expression. */
10016 return cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
10017 != CPP_CLOSE_PAREN;
10018
10019 case CPP_OPEN_SQUARE:
10020 /* '[' may start a primary-expression in obj-c++ and in C++11,
10021 as a lambda-expression, eg, '(void)[]{}'. */
10022 if (cxx_dialect >= cxx11)
10023 return -1;
10024 return c_dialect_objc ();
10025
10026 case CPP_PLUS_PLUS:
10027 case CPP_MINUS_MINUS:
10028 /* '++' and '--' may or may not start a cast-expression:
10029
10030 struct T { void operator++(int); };
10031 void f() { (T())++; }
10032
10033 vs
10034
10035 int a;
10036 (int)++a; */
10037 return -1;
10038
10039 default:
10040 return 1;
10041 }
10042}
10043
10044/* Try to find a legal C++-style cast to DST_TYPE for ORIG_EXPR, trying them
10045 in the order: const_cast, static_cast, reinterpret_cast.
10046
10047 Don't suggest dynamic_cast.
10048
10049 Return the first legal cast kind found, or NULL otherwise. */
10050
10051static const char *
10052get_cast_suggestion (tree dst_type, tree orig_expr)
10053{
10054 tree trial;
10055
10056 /* Reuse the parser logic by attempting to build the various kinds of
10057 cast, with "complain" disabled.
10058 Identify the first such cast that is valid. */
10059
10060 /* Don't attempt to run such logic within template processing. */
10061 if (processing_template_decl)
10062 return NULL;
10063
10064 /* First try const_cast. */
10065 trial = build_const_cast (input_location, dst_type, orig_expr, tf_none);
10066 if (trial != error_mark_node)
10067 return "const_cast";
10068
10069 /* If that fails, try static_cast. */
10070 trial = build_static_cast (input_location, dst_type, orig_expr, tf_none);
10071 if (trial != error_mark_node)
10072 return "static_cast";
10073
10074 /* Finally, try reinterpret_cast. */
10075 trial = build_reinterpret_cast (input_location, dst_type, orig_expr,
10076 tf_none);
10077 if (trial != error_mark_node)
10078 return "reinterpret_cast";
10079
10080 /* No such cast possible. */
10081 return NULL;
10082}
10083
10084/* If -Wold-style-cast is enabled, add fix-its to RICHLOC,
10085 suggesting how to convert a C-style cast of the form:
10086
10087 (DST_TYPE)ORIG_EXPR
10088
10089 to a C++-style cast.
10090
10091 The primary range of RICHLOC is asssumed to be that of the original
10092 expression. OPEN_PAREN_LOC and CLOSE_PAREN_LOC give the locations
10093 of the parens in the C-style cast. */
10094
10095static void
10096maybe_add_cast_fixit (rich_location *rich_loc, location_t open_paren_loc,
10097 location_t close_paren_loc, tree orig_expr,
10098 tree dst_type)
10099{
10100 /* This function is non-trivial, so bail out now if the warning isn't
10101 going to be emitted. */
10102 if (!warn_old_style_cast)
10103 return;
10104
10105 /* Try to find a legal C++ cast, trying them in order:
10106 const_cast, static_cast, reinterpret_cast. */
10107 const char *cast_suggestion = get_cast_suggestion (dst_type, orig_expr);
10108 if (!cast_suggestion)
10109 return;
10110
10111 /* Replace the open paren with "CAST_SUGGESTION<". */
10112 pretty_printer pp;
10113 pp_string (&pp, cast_suggestion);
10114 pp_less (&pp);
10115 rich_loc->add_fixit_replace (where: open_paren_loc, new_content: pp_formatted_text (&pp));
10116
10117 /* Replace the close paren with "> (". */
10118 rich_loc->add_fixit_replace (where: close_paren_loc, new_content: "> (");
10119
10120 /* Add a closing paren after the expr (the primary range of RICH_LOC). */
10121 rich_loc->add_fixit_insert_after (new_content: ")");
10122}
10123
10124
10125/* Parse a cast-expression.
10126
10127 cast-expression:
10128 unary-expression
10129 ( type-id ) cast-expression
10130
10131 ADDRESS_P is true iff the unary-expression is appearing as the
10132 operand of the `&' operator. CAST_P is true if this expression is
10133 the target of a cast.
10134
10135 Returns a representation of the expression. */
10136
10137static cp_expr
10138cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
10139 bool decltype_p, cp_id_kind * pidk)
10140{
10141 /* If it's a `(', then we might be looking at a cast. */
10142 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
10143 {
10144 tree type = NULL_TREE;
10145 cp_expr expr (NULL_TREE);
10146 int cast_expression = 0;
10147 const char *saved_message;
10148
10149 /* There's no way to know yet whether or not this is a cast.
10150 For example, `(int (3))' is a unary-expression, while `(int)
10151 3' is a cast. So, we resort to parsing tentatively. */
10152 cp_parser_parse_tentatively (parser);
10153 /* Types may not be defined in a cast. */
10154 saved_message = parser->type_definition_forbidden_message;
10155 parser->type_definition_forbidden_message
10156 = G_("types may not be defined in casts");
10157 /* Consume the `('. */
10158 matching_parens parens;
10159 cp_token *open_paren = parens.consume_open (parser);
10160 location_t open_paren_loc = open_paren->location;
10161 location_t close_paren_loc = UNKNOWN_LOCATION;
10162
10163 /* A very tricky bit is that `(struct S) { 3 }' is a
10164 compound-literal (which we permit in C++ as an extension).
10165 But, that construct is not a cast-expression -- it is a
10166 postfix-expression. (The reason is that `(struct S) { 3 }.i'
10167 is legal; if the compound-literal were a cast-expression,
10168 you'd need an extra set of parentheses.) But, if we parse
10169 the type-id, and it happens to be a class-specifier, then we
10170 will commit to the parse at that point, because we cannot
10171 undo the action that is done when creating a new class. So,
10172 then we cannot back up and do a postfix-expression.
10173
10174 Another tricky case is the following (c++/29234):
10175
10176 struct S { void operator () (); };
10177
10178 void foo ()
10179 {
10180 ( S()() );
10181 }
10182
10183 As a type-id we parse the parenthesized S()() as a function
10184 returning a function, groktypename complains and we cannot
10185 back up in this case either.
10186
10187 Therefore, we scan ahead to the closing `)', and check to see
10188 if the tokens after the `)' can start a cast-expression. Otherwise
10189 we are dealing with an unary-expression, a postfix-expression
10190 or something else.
10191
10192 Yet another tricky case, in C++11, is the following (c++/54891):
10193
10194 (void)[]{};
10195
10196 The issue is that usually, besides the case of lambda-expressions,
10197 the parenthesized type-id cannot be followed by '[', and, eg, we
10198 want to parse '(C ())[2];' in parse/pr26997.C as unary-expression.
10199 Thus, if cp_parser_tokens_start_cast_expression returns -1, below
10200 we don't commit, we try a cast-expression, then an unary-expression.
10201
10202 Save tokens so that we can put them back. */
10203 cp_lexer_save_tokens (lexer: parser->lexer);
10204
10205 /* We may be looking at a cast-expression. */
10206 if (cp_parser_skip_to_closing_parenthesis (parser, recovering: false, or_comma: false,
10207 /*consume_paren=*/true))
10208 cast_expression
10209 = cp_parser_tokens_start_cast_expression (parser);
10210
10211 /* Roll back the tokens we skipped. */
10212 cp_lexer_rollback_tokens (lexer: parser->lexer);
10213 /* If we aren't looking at a cast-expression, simulate an error so
10214 that the call to cp_parser_error_occurred below returns true. */
10215 if (!cast_expression)
10216 cp_parser_simulate_error (parser);
10217 else
10218 {
10219 bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
10220 parser->in_type_id_in_expr_p = true;
10221 /* Look for the type-id. */
10222 type = cp_parser_type_id (parser);
10223 /* Look for the closing `)'. */
10224 cp_token *close_paren = parens.require_close (parser);
10225 if (close_paren)
10226 close_paren_loc = close_paren->location;
10227 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
10228 }
10229
10230 /* Restore the saved message. */
10231 parser->type_definition_forbidden_message = saved_message;
10232
10233 /* At this point this can only be either a cast or a
10234 parenthesized ctor such as `(T ())' that looks like a cast to
10235 function returning T. */
10236 if (!cp_parser_error_occurred (parser))
10237 {
10238 /* Only commit if the cast-expression doesn't start with
10239 '++', '--', or '[' in C++11. */
10240 if (cast_expression > 0)
10241 cp_parser_commit_to_topmost_tentative_parse (parser);
10242
10243 expr = cp_parser_cast_expression (parser,
10244 /*address_p=*/false,
10245 /*cast_p=*/true,
10246 /*decltype_p=*/false,
10247 pidk);
10248
10249 if (cp_parser_parse_definitely (parser))
10250 {
10251 /* Warn about old-style casts, if so requested. */
10252 if (warn_old_style_cast
10253 && !in_system_header_at (loc: input_location)
10254 && !VOID_TYPE_P (type)
10255 && current_lang_name != lang_name_c)
10256 {
10257 gcc_rich_location rich_loc (input_location);
10258 maybe_add_cast_fixit (rich_loc: &rich_loc, open_paren_loc, close_paren_loc,
10259 orig_expr: expr, dst_type: type);
10260 warning_at (&rich_loc, OPT_Wold_style_cast,
10261 "use of old-style cast to %q#T", type);
10262 }
10263
10264 /* Only type conversions to integral or enumeration types
10265 can be used in constant-expressions. */
10266 if (!cast_valid_in_integral_constant_expression_p (type)
10267 && cp_parser_non_integral_constant_expression (parser,
10268 thing: NIC_CAST))
10269 return error_mark_node;
10270
10271 /* Perform the cast. */
10272 /* Make a location:
10273 (TYPE) EXPR
10274 ^~~~~~~~~~~
10275 with start==caret at the open paren, extending to the
10276 end of "expr". */
10277 location_t cast_loc = make_location (caret: open_paren_loc,
10278 start: open_paren_loc,
10279 finish: expr.get_finish ());
10280 expr = build_c_cast (loc: cast_loc, type, expr);
10281 return expr;
10282 }
10283 }
10284 else
10285 cp_parser_abort_tentative_parse (parser);
10286 }
10287
10288 /* If we get here, then it's not a cast, so it must be a
10289 unary-expression. */
10290 return cp_parser_unary_expression (parser, pidk, address_p,
10291 cast_p, decltype_p);
10292}
10293
10294/* Parse a binary expression of the general form:
10295
10296 pm-expression:
10297 cast-expression
10298 pm-expression .* cast-expression
10299 pm-expression ->* cast-expression
10300
10301 multiplicative-expression:
10302 pm-expression
10303 multiplicative-expression * pm-expression
10304 multiplicative-expression / pm-expression
10305 multiplicative-expression % pm-expression
10306
10307 additive-expression:
10308 multiplicative-expression
10309 additive-expression + multiplicative-expression
10310 additive-expression - multiplicative-expression
10311
10312 shift-expression:
10313 additive-expression
10314 shift-expression << additive-expression
10315 shift-expression >> additive-expression
10316
10317 relational-expression:
10318 shift-expression
10319 relational-expression < shift-expression
10320 relational-expression > shift-expression
10321 relational-expression <= shift-expression
10322 relational-expression >= shift-expression
10323
10324 GNU Extension:
10325
10326 relational-expression:
10327 relational-expression <? shift-expression
10328 relational-expression >? shift-expression
10329
10330 equality-expression:
10331 relational-expression
10332 equality-expression == relational-expression
10333 equality-expression != relational-expression
10334
10335 and-expression:
10336 equality-expression
10337 and-expression & equality-expression
10338
10339 exclusive-or-expression:
10340 and-expression
10341 exclusive-or-expression ^ and-expression
10342
10343 inclusive-or-expression:
10344 exclusive-or-expression
10345 inclusive-or-expression | exclusive-or-expression
10346
10347 logical-and-expression:
10348 inclusive-or-expression
10349 logical-and-expression && inclusive-or-expression
10350
10351 logical-or-expression:
10352 logical-and-expression
10353 logical-or-expression || logical-and-expression
10354
10355 All these are implemented with a single function like:
10356
10357 binary-expression:
10358 simple-cast-expression
10359 binary-expression <token> binary-expression
10360
10361 CAST_P is true if this expression is the target of a cast.
10362
10363 The binops_by_token map is used to get the tree codes for each <token> type.
10364 binary-expressions are associated according to a precedence table. */
10365
10366#define TOKEN_PRECEDENCE(token) \
10367(((token->type == CPP_GREATER \
10368 || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)) \
10369 && !parser->greater_than_is_operator_p) \
10370 ? PREC_NOT_OPERATOR \
10371 : binops_by_token[token->type].prec)
10372
10373static cp_expr
10374cp_parser_binary_expression (cp_parser* parser, bool cast_p,
10375 bool no_toplevel_fold_p,
10376 bool decltype_p,
10377 enum cp_parser_prec prec,
10378 cp_id_kind * pidk)
10379{
10380 cp_parser_expression_stack stack;
10381 cp_parser_expression_stack_entry *sp = &stack[0];
10382 cp_parser_expression_stack_entry *disable_warnings_sp = NULL;
10383 cp_parser_expression_stack_entry current;
10384 cp_expr rhs;
10385 cp_token *token;
10386 enum tree_code rhs_type;
10387 enum cp_parser_prec new_prec, lookahead_prec;
10388 tree overload;
10389
10390 /* Parse the first expression. */
10391 current.lhs_type = (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NOT)
10392 ? TRUTH_NOT_EXPR : ERROR_MARK);
10393 current.lhs = cp_parser_cast_expression (parser, /*address_p=*/false,
10394 cast_p, decltype_p, pidk);
10395 current.prec = prec;
10396
10397 if (cp_parser_error_occurred (parser))
10398 return error_mark_node;
10399
10400 for (;;)
10401 {
10402 /* Get an operator token. */
10403 token = cp_lexer_peek_token (lexer: parser->lexer);
10404
10405 if (warn_cxx11_compat
10406 && token->type == CPP_RSHIFT
10407 && !parser->greater_than_is_operator_p)
10408 {
10409 if (warning_at (token->location, OPT_Wc__11_compat,
10410 "%<>>%> operator is treated"
10411 " as two right angle brackets in C++11"))
10412 inform (token->location,
10413 "suggest parentheses around %<>>%> expression");
10414 }
10415
10416 new_prec = TOKEN_PRECEDENCE (token);
10417 if (new_prec != PREC_NOT_OPERATOR
10418 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_ELLIPSIS))
10419 /* This is a fold-expression; handle it later. */
10420 new_prec = PREC_NOT_OPERATOR;
10421
10422 /* Popping an entry off the stack means we completed a subexpression:
10423 - either we found a token which is not an operator (`>' where it is not
10424 an operator, or prec == PREC_NOT_OPERATOR), in which case popping
10425 will happen repeatedly;
10426 - or, we found an operator which has lower priority. This is the case
10427 where the recursive descent *ascends*, as in `3 * 4 + 5' after
10428 parsing `3 * 4'. */
10429 if (new_prec <= current.prec)
10430 {
10431 if (sp == stack)
10432 break;
10433 else
10434 goto pop;
10435 }
10436
10437 get_rhs:
10438 current.tree_type = binops_by_token[token->type].tree_type;
10439 current.loc = token->location;
10440 current.flags = token->flags;
10441
10442 /* We used the operator token. */
10443 cp_lexer_consume_token (lexer: parser->lexer);
10444
10445 /* For "false && x" or "true || x", x will never be executed;
10446 disable warnings while evaluating it. */
10447 if ((current.tree_type == TRUTH_ANDIF_EXPR
10448 && cp_fully_fold (current.lhs) == truthvalue_false_node)
10449 || (current.tree_type == TRUTH_ORIF_EXPR
10450 && cp_fully_fold (current.lhs) == truthvalue_true_node))
10451 {
10452 disable_warnings_sp = sp;
10453 ++c_inhibit_evaluation_warnings;
10454 }
10455
10456 /* Extract another operand. It may be the RHS of this expression
10457 or the LHS of a new, higher priority expression. */
10458 rhs_type = (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NOT)
10459 ? TRUTH_NOT_EXPR : ERROR_MARK);
10460 rhs = cp_parser_simple_cast_expression (parser);
10461
10462 /* Get another operator token. Look up its precedence to avoid
10463 building a useless (immediately popped) stack entry for common
10464 cases such as 3 + 4 + 5 or 3 * 4 + 5. */
10465 token = cp_lexer_peek_token (lexer: parser->lexer);
10466 lookahead_prec = TOKEN_PRECEDENCE (token);
10467 if (lookahead_prec != PREC_NOT_OPERATOR
10468 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_ELLIPSIS))
10469 lookahead_prec = PREC_NOT_OPERATOR;
10470 if (lookahead_prec > new_prec)
10471 {
10472 /* ... and prepare to parse the RHS of the new, higher priority
10473 expression. Since precedence levels on the stack are
10474 monotonically increasing, we do not have to care about
10475 stack overflows. */
10476 *sp = current;
10477 ++sp;
10478 current.lhs = rhs;
10479 current.lhs_type = rhs_type;
10480 current.prec = new_prec;
10481 new_prec = lookahead_prec;
10482 goto get_rhs;
10483
10484 pop:
10485 lookahead_prec = new_prec;
10486 /* If the stack is not empty, we have parsed into LHS the right side
10487 (`4' in the example above) of an expression we had suspended.
10488 We can use the information on the stack to recover the LHS (`3')
10489 from the stack together with the tree code (`MULT_EXPR'), and
10490 the precedence of the higher level subexpression
10491 (`PREC_ADDITIVE_EXPRESSION'). TOKEN is the CPP_PLUS token,
10492 which will be used to actually build the additive expression. */
10493 rhs = current.lhs;
10494 rhs_type = current.lhs_type;
10495 --sp;
10496 current = *sp;
10497 }
10498
10499 /* Undo the disabling of warnings done above. */
10500 if (sp == disable_warnings_sp)
10501 {
10502 disable_warnings_sp = NULL;
10503 --c_inhibit_evaluation_warnings;
10504 }
10505
10506 if (warn_logical_not_paren
10507 && TREE_CODE_CLASS (current.tree_type) == tcc_comparison
10508 && current.lhs_type == TRUTH_NOT_EXPR
10509 /* Avoid warning for !!x == y. */
10510 && (TREE_CODE (current.lhs) != NE_EXPR
10511 || !integer_zerop (TREE_OPERAND (current.lhs, 1)))
10512 && (TREE_CODE (current.lhs) != TRUTH_NOT_EXPR
10513 || (TREE_CODE (TREE_OPERAND (current.lhs, 0)) != TRUTH_NOT_EXPR
10514 /* Avoid warning for !b == y where b is boolean. */
10515 && (TREE_TYPE (TREE_OPERAND (current.lhs, 0)) == NULL_TREE
10516 || (TREE_CODE (TREE_TYPE (TREE_OPERAND (current.lhs, 0)))
10517 != BOOLEAN_TYPE))))
10518 /* Avoid warning for !!b == y where b is boolean. */
10519 && (!(DECL_P (tree_strip_any_location_wrapper (current.lhs))
10520 || (TREE_CODE (current.lhs) == NON_LVALUE_EXPR
10521 && DECL_P (tree_strip_any_location_wrapper
10522 (TREE_OPERAND (current.lhs, 0)))))
10523 || TREE_TYPE (current.lhs) == NULL_TREE
10524 || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))
10525 warn_logical_not_parentheses (current.loc, current.tree_type,
10526 current.lhs, maybe_constant_value (rhs));
10527
10528 if (warn_xor_used_as_pow
10529 && current.tree_type == BIT_XOR_EXPR
10530 /* Don't warn for named "xor" (as opposed to '^'). */
10531 && !(current.flags & NAMED_OP)
10532 && current.lhs.decimal_p ()
10533 && rhs.decimal_p ())
10534 check_for_xor_used_as_pow
10535 (lhs_loc: current.lhs.get_location (),
10536 lhs_val: tree_strip_any_location_wrapper (exp: current.lhs),
10537 operator_loc: current.loc,
10538 rhs_loc: rhs.get_location (),
10539 rhs_val: tree_strip_any_location_wrapper (exp: rhs));
10540
10541 overload = NULL;
10542
10543 location_t combined_loc = make_location (caret: current.loc,
10544 start: current.lhs.get_start (),
10545 finish: rhs.get_finish ());
10546
10547 /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
10548 ERROR_MARK for everything that is not a binary expression.
10549 This makes warn_about_parentheses miss some warnings that
10550 involve unary operators. For unary expressions we should
10551 pass the correct tree_code unless the unary expression was
10552 surrounded by parentheses.
10553 */
10554 if (no_toplevel_fold_p
10555 && lookahead_prec <= current.prec
10556 && sp == stack)
10557 {
10558 if (current.lhs == error_mark_node || rhs == error_mark_node)
10559 current.lhs = error_mark_node;
10560 else
10561 {
10562 current.lhs.maybe_add_location_wrapper ();
10563 rhs.maybe_add_location_wrapper ();
10564 current.lhs
10565 = build_min (current.tree_type,
10566 TREE_CODE_CLASS (current.tree_type)
10567 == tcc_comparison
10568 ? boolean_type_node : TREE_TYPE (current.lhs),
10569 current.lhs.get_value (), rhs.get_value ());
10570 SET_EXPR_LOCATION (current.lhs, combined_loc);
10571 }
10572 }
10573 else
10574 {
10575 op_location_t op_loc (current.loc, combined_loc);
10576 current.lhs = build_x_binary_op (op_loc, current.tree_type,
10577 current.lhs, current.lhs_type,
10578 rhs, rhs_type, NULL_TREE, &overload,
10579 complain_flags (decltype_p));
10580 /* TODO: build_x_binary_op doesn't always honor the location. */
10581 current.lhs.set_location (combined_loc);
10582 }
10583 current.lhs_type = current.tree_type;
10584
10585 /* If the binary operator required the use of an overloaded operator,
10586 then this expression cannot be an integral constant-expression.
10587 An overloaded operator can be used even if both operands are
10588 otherwise permissible in an integral constant-expression if at
10589 least one of the operands is of enumeration type. */
10590
10591 if (overload
10592 && cp_parser_non_integral_constant_expression (parser,
10593 thing: NIC_OVERLOADED))
10594 return error_mark_node;
10595 }
10596
10597 return current.lhs;
10598}
10599
10600static cp_expr
10601cp_parser_binary_expression (cp_parser* parser, bool cast_p,
10602 bool no_toplevel_fold_p,
10603 enum cp_parser_prec prec,
10604 cp_id_kind * pidk)
10605{
10606 return cp_parser_binary_expression (parser, cast_p, no_toplevel_fold_p,
10607 /*decltype*/decltype_p: false, prec, pidk);
10608}
10609
10610/* Parse the `? expression : assignment-expression' part of a
10611 conditional-expression. The LOGICAL_OR_EXPR is the
10612 logical-or-expression that started the conditional-expression.
10613 Returns a representation of the entire conditional-expression.
10614
10615 This routine is used by cp_parser_assignment_expression
10616 and cp_parser_conditional_expression.
10617
10618 ? expression : assignment-expression
10619
10620 GNU Extensions:
10621
10622 ? : assignment-expression */
10623
10624static tree
10625cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
10626{
10627 tree expr, folded_logical_or_expr = cp_fully_fold (logical_or_expr);
10628 cp_expr assignment_expr;
10629 struct cp_token *token;
10630 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
10631
10632 /* Consume the `?' token. */
10633 cp_lexer_consume_token (lexer: parser->lexer);
10634 token = cp_lexer_peek_token (lexer: parser->lexer);
10635 if (cp_parser_allow_gnu_extensions_p (parser)
10636 && token->type == CPP_COLON)
10637 {
10638 pedwarn (token->location, OPT_Wpedantic,
10639 "ISO C++ does not allow %<?:%> with omitted middle operand");
10640 /* Implicit true clause. */
10641 expr = NULL_TREE;
10642 c_inhibit_evaluation_warnings +=
10643 folded_logical_or_expr == truthvalue_true_node;
10644 warn_for_omitted_condop (token->location, logical_or_expr);
10645 }
10646 else
10647 {
10648 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
10649 parser->colon_corrects_to_scope_p = false;
10650 /* Parse the expression. */
10651 c_inhibit_evaluation_warnings +=
10652 folded_logical_or_expr == truthvalue_false_node;
10653 expr = cp_parser_expression (parser);
10654 c_inhibit_evaluation_warnings +=
10655 ((folded_logical_or_expr == truthvalue_true_node)
10656 - (folded_logical_or_expr == truthvalue_false_node));
10657 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
10658 }
10659
10660 /* The next token should be a `:'. */
10661 cp_parser_require (parser, CPP_COLON, RT_COLON);
10662 /* Parse the assignment-expression. */
10663 assignment_expr = cp_parser_assignment_expression (parser);
10664 c_inhibit_evaluation_warnings -=
10665 folded_logical_or_expr == truthvalue_true_node;
10666
10667 /* Make a location:
10668 LOGICAL_OR_EXPR ? EXPR : ASSIGNMENT_EXPR
10669 ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
10670 with the caret at the "?", ranging from the start of
10671 the logical_or_expr to the end of the assignment_expr. */
10672 loc = make_location (caret: loc,
10673 start: logical_or_expr.get_start (),
10674 finish: assignment_expr.get_finish ());
10675
10676 /* Build the conditional-expression. */
10677 return build_x_conditional_expr (loc, logical_or_expr,
10678 expr,
10679 assignment_expr,
10680 tf_warning_or_error);
10681}
10682
10683/* Parse a conditional-expression.
10684
10685 conditional-expression:
10686 logical-or-expression
10687 logical-or-expression ? expression : assignment-expression
10688
10689 GNU Extensions:
10690
10691 logical-or-expression ? : assignment-expression */
10692
10693static cp_expr
10694cp_parser_conditional_expression (cp_parser *parser)
10695{
10696 cp_expr expr = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: false, decltype_p: false,
10697 prec: PREC_NOT_OPERATOR, NULL);
10698 /* If the next token is a `?' then we're actually looking at
10699 a conditional-expression; otherwise we're done. */
10700 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_QUERY))
10701 return cp_parser_question_colon_clause (parser, logical_or_expr: expr);
10702 return expr;
10703}
10704
10705/* Parse an assignment-expression.
10706
10707 assignment-expression:
10708 conditional-expression
10709 logical-or-expression assignment-operator assignment_expression
10710 throw-expression
10711 yield-expression
10712
10713 CAST_P is true if this expression is the target of a cast.
10714 DECLTYPE_P is true if this expression is the operand of decltype.
10715
10716 Returns a representation for the expression. */
10717
10718static cp_expr
10719cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
10720 bool cast_p, bool decltype_p)
10721{
10722 cp_expr expr;
10723
10724 /* If the next token is the `throw' keyword, then we're looking at
10725 a throw-expression. */
10726 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_THROW))
10727 expr = cp_parser_throw_expression (parser);
10728 /* If the next token is the `co_yield' keyword, then we're looking at
10729 a yield-expression. */
10730 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_CO_YIELD))
10731 expr = cp_parser_yield_expression (parser);
10732 /* Otherwise, it must be that we are looking at a
10733 logical-or-expression. */
10734 else
10735 {
10736 /* Parse the binary expressions (logical-or-expression). */
10737 expr = cp_parser_binary_expression (parser, cast_p, no_toplevel_fold_p: false,
10738 decltype_p,
10739 prec: PREC_NOT_OPERATOR, pidk);
10740 /* If the next token is a `?' then we're actually looking at a
10741 conditional-expression. */
10742 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_QUERY))
10743 return cp_parser_question_colon_clause (parser, logical_or_expr: expr);
10744 else
10745 {
10746 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
10747
10748 /* If it's an assignment-operator, we're using the second
10749 production. */
10750 enum tree_code assignment_operator
10751 = cp_parser_assignment_operator_opt (parser);
10752 if (assignment_operator != ERROR_MARK)
10753 {
10754 /* Parse the right-hand side of the assignment. */
10755 cp_expr rhs = cp_parser_initializer_clause (parser);
10756
10757 if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
10758 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
10759
10760 /* An assignment may not appear in a
10761 constant-expression. */
10762 if (cp_parser_non_integral_constant_expression (parser,
10763 thing: NIC_ASSIGNMENT))
10764 return error_mark_node;
10765 /* Build the assignment expression. Its default
10766 location:
10767 LHS = RHS
10768 ~~~~^~~~~
10769 is the location of the '=' token as the
10770 caret, ranging from the start of the lhs to the
10771 end of the rhs. */
10772 loc = make_location (caret: loc,
10773 start: expr.get_start (),
10774 finish: rhs.get_finish ());
10775 expr = build_x_modify_expr (loc, expr,
10776 assignment_operator,
10777 rhs, NULL_TREE,
10778 complain_flags (decltype_p));
10779 /* TODO: build_x_modify_expr doesn't honor the location,
10780 so we must set it here. */
10781 expr.set_location (loc);
10782 }
10783 }
10784 }
10785
10786 return expr;
10787}
10788
10789/* Parse an (optional) assignment-operator.
10790
10791 assignment-operator: one of
10792 = *= /= %= += -= >>= <<= &= ^= |=
10793
10794 GNU Extension:
10795
10796 assignment-operator: one of
10797 <?= >?=
10798
10799 If the next token is an assignment operator, the corresponding tree
10800 code is returned, and the token is consumed. For example, for
10801 `+=', PLUS_EXPR is returned. For `=' itself, the code returned is
10802 NOP_EXPR. For `/', TRUNC_DIV_EXPR is returned; for `%',
10803 TRUNC_MOD_EXPR is returned. If TOKEN is not an assignment
10804 operator, ERROR_MARK is returned. */
10805
10806static enum tree_code
10807cp_parser_assignment_operator_opt (cp_parser* parser)
10808{
10809 enum tree_code op;
10810 cp_token *token;
10811
10812 /* Peek at the next token. */
10813 token = cp_lexer_peek_token (lexer: parser->lexer);
10814
10815 switch (token->type)
10816 {
10817 case CPP_EQ:
10818 op = NOP_EXPR;
10819 break;
10820
10821 case CPP_MULT_EQ:
10822 op = MULT_EXPR;
10823 break;
10824
10825 case CPP_DIV_EQ:
10826 op = TRUNC_DIV_EXPR;
10827 break;
10828
10829 case CPP_MOD_EQ:
10830 op = TRUNC_MOD_EXPR;
10831 break;
10832
10833 case CPP_PLUS_EQ:
10834 op = PLUS_EXPR;
10835 break;
10836
10837 case CPP_MINUS_EQ:
10838 op = MINUS_EXPR;
10839 break;
10840
10841 case CPP_RSHIFT_EQ:
10842 op = RSHIFT_EXPR;
10843 break;
10844
10845 case CPP_LSHIFT_EQ:
10846 op = LSHIFT_EXPR;
10847 break;
10848
10849 case CPP_AND_EQ:
10850 op = BIT_AND_EXPR;
10851 break;
10852
10853 case CPP_XOR_EQ:
10854 op = BIT_XOR_EXPR;
10855 break;
10856
10857 case CPP_OR_EQ:
10858 op = BIT_IOR_EXPR;
10859 break;
10860
10861 default:
10862 /* Nothing else is an assignment operator. */
10863 op = ERROR_MARK;
10864 }
10865
10866 /* An operator followed by ... is a fold-expression, handled elsewhere. */
10867 if (op != ERROR_MARK
10868 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_ELLIPSIS))
10869 op = ERROR_MARK;
10870
10871 /* If it was an assignment operator, consume it. */
10872 if (op != ERROR_MARK)
10873 cp_lexer_consume_token (lexer: parser->lexer);
10874
10875 return op;
10876}
10877
10878/* Parse an expression.
10879
10880 expression:
10881 assignment-expression
10882 expression , assignment-expression
10883
10884 CAST_P is true if this expression is the target of a cast.
10885 DECLTYPE_P is true if this expression is the immediate operand of decltype,
10886 except possibly parenthesized or on the RHS of a comma (N3276).
10887 WARN_COMMA_P is true if a comma should be diagnosed.
10888
10889 Returns a representation of the expression. */
10890
10891static cp_expr
10892cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
10893 bool cast_p, bool decltype_p, bool warn_comma_p)
10894{
10895 cp_expr expression = NULL_TREE;
10896 location_t loc = UNKNOWN_LOCATION;
10897
10898 while (true)
10899 {
10900 cp_expr assignment_expression;
10901
10902 /* Parse the next assignment-expression. */
10903 assignment_expression
10904 = cp_parser_assignment_expression (parser, pidk, cast_p, decltype_p);
10905
10906 /* We don't create a temporary for a call that is the immediate operand
10907 of decltype or on the RHS of a comma. But when we see a comma, we
10908 need to create a temporary for a call on the LHS. */
10909 if (decltype_p && !processing_template_decl
10910 && TREE_CODE (assignment_expression) == CALL_EXPR
10911 && CLASS_TYPE_P (TREE_TYPE (assignment_expression))
10912 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
10913 assignment_expression
10914 = build_cplus_new (TREE_TYPE (assignment_expression),
10915 assignment_expression, tf_warning_or_error);
10916
10917 /* If this is the first assignment-expression, we can just
10918 save it away. */
10919 if (!expression)
10920 expression = assignment_expression;
10921 else
10922 {
10923 /* Create a location with caret at the comma, ranging
10924 from the start of the LHS to the end of the RHS. */
10925 loc = make_location (caret: loc,
10926 start: expression.get_start (),
10927 finish: assignment_expression.get_finish ());
10928 expression = build_x_compound_expr (loc, expression,
10929 assignment_expression, NULL_TREE,
10930 complain_flags (decltype_p));
10931 expression.set_location (loc);
10932 }
10933 /* If the next token is not a comma, or we're in a fold-expression, then
10934 we are done with the expression. */
10935 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA)
10936 || cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_ELLIPSIS))
10937 break;
10938 /* Consume the `,'. */
10939 loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
10940 if (warn_comma_p)
10941 {
10942 /* [depr.comma.subscript]: A comma expression appearing as
10943 the expr-or-braced-init-list of a subscripting expression
10944 is deprecated. A parenthesized comma expression is not
10945 deprecated. */
10946 warning_at (loc, OPT_Wcomma_subscript,
10947 "top-level comma expression in array subscript "
10948 "is deprecated");
10949 warn_comma_p = false;
10950 }
10951 cp_lexer_consume_token (lexer: parser->lexer);
10952 /* A comma operator cannot appear in a constant-expression. */
10953 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_COMMA))
10954 expression = error_mark_node;
10955 }
10956
10957 return expression;
10958}
10959
10960/* Parse a constant-expression.
10961
10962 constant-expression:
10963 conditional-expression
10964
10965 If ALLOW_NON_CONSTANT_P a non-constant expression is silently
10966 accepted. If ALLOW_NON_CONSTANT_P is true and the expression is not
10967 constant, *NON_CONSTANT_P is set to TRUE. If ALLOW_NON_CONSTANT_P
10968 is false, NON_CONSTANT_P should be NULL. If ALLOW_NON_CONSTANT_P is
10969 greater than 1, this isn't really a constant-expression, only a
10970 potentially constant-evaluated expression. If STRICT_P is true,
10971 only parse a conditional-expression, otherwise parse an
10972 assignment-expression. See below for rationale. */
10973
10974static cp_expr
10975cp_parser_constant_expression (cp_parser* parser,
10976 int allow_non_constant_p /* = 0 */,
10977 bool *non_constant_p /* = NULL */,
10978 bool strict_p /* = false */)
10979{
10980 /* It might seem that we could simply parse the
10981 conditional-expression, and then check to see if it were
10982 TREE_CONSTANT. However, an expression that is TREE_CONSTANT is
10983 one that the compiler can figure out is constant, possibly after
10984 doing some simplifications or optimizations. The standard has a
10985 precise definition of constant-expression, and we must honor
10986 that, even though it is somewhat more restrictive.
10987
10988 For example:
10989
10990 int i[(2, 3)];
10991
10992 is not a legal declaration, because `(2, 3)' is not a
10993 constant-expression. The `,' operator is forbidden in a
10994 constant-expression. However, GCC's constant-folding machinery
10995 will fold this operation to an INTEGER_CST for `3'. */
10996
10997 /* Save the old settings. */
10998 bool saved_integral_constant_expression_p
10999 = parser->integral_constant_expression_p;
11000 bool saved_allow_non_integral_constant_expression_p
11001 = parser->allow_non_integral_constant_expression_p;
11002 bool saved_non_integral_constant_expression_p
11003 = parser->non_integral_constant_expression_p;
11004 /* We are now parsing a constant-expression. */
11005 parser->integral_constant_expression_p = true;
11006 parser->allow_non_integral_constant_expression_p
11007 = (allow_non_constant_p || cxx_dialect >= cxx11);
11008 parser->non_integral_constant_expression_p = false;
11009
11010 /* A manifestly constant-evaluated expression is evaluated even in an
11011 unevaluated operand. */
11012 cp_evaluated ev (/*reset if*/allow_non_constant_p <= 1);
11013
11014 /* Although the grammar says "conditional-expression", when not STRICT_P,
11015 we parse an "assignment-expression", which also permits
11016 "throw-expression" and the use of assignment operators. In the case
11017 that ALLOW_NON_CONSTANT_P is false, we get better errors than we would
11018 otherwise. In the case that ALLOW_NON_CONSTANT_P is true, it is
11019 actually essential that we look for an assignment-expression.
11020 For example, cp_parser_initializer_clauses uses this function to
11021 determine whether a particular assignment-expression is in fact
11022 constant. */
11023 cp_expr expression;
11024 if (strict_p)
11025 expression = cp_parser_conditional_expression (parser);
11026 else
11027 expression = cp_parser_assignment_expression (parser);
11028 /* Restore the old settings. */
11029 parser->integral_constant_expression_p
11030 = saved_integral_constant_expression_p;
11031 parser->allow_non_integral_constant_expression_p
11032 = saved_allow_non_integral_constant_expression_p;
11033 if (cxx_dialect >= cxx11
11034 && (!allow_non_constant_p || non_constant_p))
11035 {
11036 /* Require an rvalue constant expression here; that's what our
11037 callers expect. Reference constant expressions are handled
11038 separately in e.g. cp_parser_template_argument. */
11039 tree decay = expression;
11040 if (TREE_TYPE (expression)
11041 && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE)
11042 decay = build_address (expression);
11043 bool is_const = is_rvalue_constant_expression (decay);
11044 parser->non_integral_constant_expression_p = !is_const;
11045 if (!is_const && !allow_non_constant_p)
11046 require_rvalue_constant_expression (decay);
11047 }
11048 if (allow_non_constant_p && non_constant_p)
11049 *non_constant_p = parser->non_integral_constant_expression_p;
11050 parser->non_integral_constant_expression_p
11051 = saved_non_integral_constant_expression_p;
11052
11053 return expression;
11054}
11055
11056/* Parse __builtin_offsetof.
11057
11058 offsetof-expression:
11059 "__builtin_offsetof" "(" type-id "," offsetof-member-designator ")"
11060
11061 offsetof-member-designator:
11062 id-expression
11063 | offsetof-member-designator "." id-expression
11064 | offsetof-member-designator "[" expression "]"
11065 | offsetof-member-designator "->" id-expression */
11066
11067static cp_expr
11068cp_parser_builtin_offsetof (cp_parser *parser)
11069{
11070 int save_ice_p, save_non_ice_p;
11071 tree type;
11072 cp_expr expr;
11073 cp_id_kind dummy;
11074 cp_token *token;
11075 location_t finish_loc;
11076
11077 /* We're about to accept non-integral-constant things, but will
11078 definitely yield an integral constant expression. Save and
11079 restore these values around our local parsing. */
11080 save_ice_p = parser->integral_constant_expression_p;
11081 save_non_ice_p = parser->non_integral_constant_expression_p;
11082
11083 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11084
11085 /* Consume the "__builtin_offsetof" token. */
11086 cp_lexer_consume_token (lexer: parser->lexer);
11087 /* Consume the opening `('. */
11088 matching_parens parens;
11089 parens.require_open (parser);
11090 /* Parse the type-id. */
11091 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11092 {
11093 const char *saved_message = parser->type_definition_forbidden_message;
11094 parser->type_definition_forbidden_message
11095 = G_("types may not be defined within %<__builtin_offsetof%>");
11096 type = cp_parser_type_id (parser);
11097 parser->type_definition_forbidden_message = saved_message;
11098 }
11099 /* Look for the `,'. */
11100 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
11101 token = cp_lexer_peek_token (lexer: parser->lexer);
11102
11103 /* Build the (type *)null that begins the traditional offsetof macro. */
11104 tree object_ptr
11105 = build_static_cast (input_location, build_pointer_type (type),
11106 null_pointer_node, tf_warning_or_error);
11107
11108 /* Parse the offsetof-member-designator. We begin as if we saw "expr->". */
11109 expr = cp_parser_postfix_dot_deref_expression (parser, token_type: CPP_DEREF, postfix_expression: object_ptr,
11110 for_offsetof: true, idk: &dummy, location: token->location);
11111 while (true)
11112 {
11113 token = cp_lexer_peek_token (lexer: parser->lexer);
11114 switch (token->type)
11115 {
11116 case CPP_OPEN_SQUARE:
11117 /* offsetof-member-designator "[" expression "]" */
11118 expr = cp_parser_postfix_open_square_expression (parser, postfix_expression: expr,
11119 for_offsetof: true, decltype_p: false);
11120 break;
11121
11122 case CPP_DEREF:
11123 /* offsetof-member-designator "->" identifier */
11124 expr = grok_array_decl (token->location, expr, integer_zero_node,
11125 NULL, tf_warning_or_error);
11126 /* FALLTHRU */
11127
11128 case CPP_DOT:
11129 /* offsetof-member-designator "." identifier */
11130 cp_lexer_consume_token (lexer: parser->lexer);
11131 expr = cp_parser_postfix_dot_deref_expression (parser, token_type: CPP_DOT,
11132 postfix_expression: expr, for_offsetof: true, idk: &dummy,
11133 location: token->location);
11134 break;
11135
11136 case CPP_CLOSE_PAREN:
11137 /* Consume the ")" token. */
11138 finish_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11139 cp_lexer_consume_token (lexer: parser->lexer);
11140 goto success;
11141
11142 default:
11143 /* Error. We know the following require will fail, but
11144 that gives the proper error message. */
11145 parens.require_close (parser);
11146 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false, consume_paren: true);
11147 expr = error_mark_node;
11148 goto failure;
11149 }
11150 }
11151
11152 success:
11153 /* Make a location of the form:
11154 __builtin_offsetof (struct s, f)
11155 ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
11156 with caret at the type-id, ranging from the start of the
11157 "_builtin_offsetof" token to the close paren. */
11158 loc = make_location (caret: loc, start: start_loc, finish: finish_loc);
11159 /* The result will be an INTEGER_CST, so we need to explicitly
11160 preserve the location. */
11161 expr = cp_expr (finish_offsetof (object_ptr, expr, loc), loc);
11162
11163 failure:
11164 parser->integral_constant_expression_p = save_ice_p;
11165 parser->non_integral_constant_expression_p = save_non_ice_p;
11166
11167 expr = expr.maybe_add_location_wrapper ();
11168 return expr;
11169}
11170
11171/* Parse a builtin trait expression or type. */
11172
11173static cp_expr
11174cp_parser_trait (cp_parser* parser, const cp_trait* trait)
11175{
11176 const cp_trait_kind kind = trait->kind;
11177 tree type1, type2 = NULL_TREE;
11178 const bool binary = (trait->arity == 2);
11179 const bool variadic = (trait->arity == -1);
11180 const bool type = trait->type;
11181
11182 /* Get location of initial token. */
11183 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11184
11185 /* Consume the token. */
11186 cp_lexer_consume_token (lexer: parser->lexer);
11187
11188 matching_parens parens;
11189 if (kind == CPTK_TYPE_PACK_ELEMENT)
11190 cp_parser_require (parser, CPP_LESS, RT_LESS);
11191 else
11192 parens.require_open (parser);
11193
11194 if (kind == CPTK_IS_DEDUCIBLE)
11195 {
11196 const cp_token* token = cp_lexer_peek_token (lexer: parser->lexer);
11197 type1 = cp_parser_id_expression (parser,
11198 /*template_keyword_p=*/false,
11199 /*check_dependency_p=*/true,
11200 template_p: nullptr,
11201 /*declarator_p=*/false,
11202 /*optional_p=*/false);
11203 type1 = cp_parser_lookup_name_simple (parser, type1, token->location);
11204 }
11205 else if (kind == CPTK_TYPE_PACK_ELEMENT)
11206 /* __type_pack_element takes an expression as its first argument and uses
11207 template-id syntax instead of function call syntax (for consistency
11208 with Clang). We special case these properties of __type_pack_element
11209 here and elsewhere. */
11210 type1 = cp_parser_constant_expression (parser);
11211 else
11212 {
11213 type_id_in_expr_sentinel s (parser);
11214 type1 = cp_parser_type_id (parser);
11215 }
11216
11217 if (type1 == error_mark_node)
11218 return error_mark_node;
11219
11220 if (kind == CPTK_TYPE_PACK_ELEMENT)
11221 {
11222 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
11223 tree trailing = cp_parser_enclosed_template_argument_list (parser);
11224 for (tree elt : tree_vec_range (trailing))
11225 {
11226 if (!TYPE_P (elt))
11227 {
11228 error_at (cp_expr_loc_or_input_loc (t: elt),
11229 "trailing argument to %<__type_pack_element%> "
11230 "is not a type");
11231 return error_mark_node;
11232 }
11233 }
11234 type2 = trailing;
11235 }
11236 else if (binary)
11237 {
11238 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
11239
11240 {
11241 type_id_in_expr_sentinel s (parser);
11242 type2 = cp_parser_type_id (parser);
11243 }
11244
11245 if (type2 == error_mark_node)
11246 return error_mark_node;
11247 }
11248 else if (variadic)
11249 {
11250 auto_vec<tree, 4> trailing;
11251 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
11252 {
11253 cp_lexer_consume_token (lexer: parser->lexer);
11254 tree elt = cp_parser_type_id (parser);
11255 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
11256 {
11257 cp_lexer_consume_token (lexer: parser->lexer);
11258 elt = make_pack_expansion (elt);
11259 }
11260 if (elt == error_mark_node)
11261 return error_mark_node;
11262 trailing.safe_push (obj: elt);
11263 }
11264 type2 = make_tree_vec (trailing.length ());
11265 for (int i = 0; i < TREE_VEC_LENGTH (type2); ++i)
11266 TREE_VEC_ELT (type2, i) = trailing[i];
11267 }
11268
11269 location_t finish_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11270 if (kind == CPTK_TYPE_PACK_ELEMENT)
11271 /* cp_parser_enclosed_template_argument_list above already took care
11272 of parsing the closing '>'. */;
11273 else
11274 parens.require_close (parser);
11275
11276 /* Construct a location of the form:
11277 __is_trivially_copyable(_Tp)
11278 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
11279 with start == caret, finishing at the close-paren. */
11280 location_t trait_loc = make_location (caret: start_loc, start: start_loc, finish: finish_loc);
11281
11282 /* Complete the trait expression, which may mean either processing
11283 the trait expr now or saving it for template instantiation. */
11284 switch (kind)
11285 {
11286 case CPTK_BASES:
11287 return cp_expr (finish_bases (type1, false), trait_loc);
11288 case CPTK_DIRECT_BASES:
11289 return cp_expr (finish_bases (type1, true), trait_loc);
11290 default:
11291 if (type)
11292 return finish_trait_type (kind, type1, type2, tf_warning_or_error);
11293 else
11294 return finish_trait_expr (trait_loc, kind, type1, type2);
11295 }
11296}
11297
11298/* Parse a lambda expression.
11299
11300 lambda-expression:
11301 lambda-introducer lambda-declarator [opt] compound-statement
11302 lambda-introducer < template-parameter-list > requires-clause [opt]
11303 lambda-declarator [opt] compound-statement
11304
11305 Returns a representation of the expression. */
11306
11307static cp_expr
11308cp_parser_lambda_expression (cp_parser* parser)
11309{
11310 tree lambda_expr = build_lambda_expr ();
11311 tree type;
11312 bool ok = true;
11313 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
11314 cp_token_position start = 0;
11315
11316 LAMBDA_EXPR_LOCATION (lambda_expr) = token->location;
11317
11318 if (cxx_dialect >= cxx20)
11319 {
11320 /* C++20 allows lambdas in unevaluated context, but one in the type of a
11321 non-type parameter is nonsensical.
11322
11323 Distinguish a lambda in the parameter type from a lambda in the
11324 default argument by looking at local_variables_forbidden_p, which is
11325 only set in default arguments. */
11326 if (processing_template_parmlist && !parser->local_variables_forbidden_p)
11327 {
11328 error_at (token->location,
11329 "lambda-expression in template parameter type");
11330 token->error_reported = true;
11331 ok = false;
11332 }
11333 }
11334 else if (cp_unevaluated_operand)
11335 {
11336 if (!token->error_reported)
11337 {
11338 error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
11339 "lambda-expression in unevaluated context"
11340 " only available with %<-std=c++20%> or %<-std=gnu++20%>");
11341 token->error_reported = true;
11342 }
11343 ok = false;
11344 }
11345 else if (parser->in_template_argument_list_p || processing_template_parmlist)
11346 {
11347 if (!token->error_reported)
11348 {
11349 error_at (token->location, "lambda-expression in template-argument"
11350 " only available with %<-std=c++20%> or %<-std=gnu++20%>");
11351 token->error_reported = true;
11352 }
11353 ok = false;
11354 }
11355
11356 /* We may be in the middle of deferred access check. Disable
11357 it now. */
11358 push_deferring_access_checks (dk_no_deferred);
11359
11360 cp_parser_lambda_introducer (parser, lambda_expr);
11361 if (cp_parser_error_occurred (parser))
11362 return error_mark_node;
11363
11364 type = begin_lambda_type (lambda_expr);
11365 if (type == error_mark_node)
11366 return error_mark_node;
11367
11368 record_lambda_scope (lambda: lambda_expr);
11369 record_lambda_scope_discriminator (lambda: lambda_expr);
11370
11371 /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set. */
11372 determine_visibility (TYPE_NAME (type));
11373
11374 /* Now that we've started the type, add the capture fields for any
11375 explicit captures. */
11376 register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
11377
11378 {
11379 /* Inside the class, surrounding template-parameter-lists do not apply. */
11380 unsigned int saved_num_template_parameter_lists
11381 = parser->num_template_parameter_lists;
11382 unsigned char in_statement = parser->in_statement;
11383 bool in_switch_statement_p = parser->in_switch_statement_p;
11384 bool fully_implicit_function_template_p
11385 = parser->fully_implicit_function_template_p;
11386 tree implicit_template_parms = parser->implicit_template_parms;
11387 cp_binding_level* implicit_template_scope = parser->implicit_template_scope;
11388 bool auto_is_implicit_function_template_parm_p
11389 = parser->auto_is_implicit_function_template_parm_p;
11390 bool saved_omp_array_section_p = parser->omp_array_section_p;
11391
11392 parser->num_template_parameter_lists = 0;
11393 parser->in_statement = 0;
11394 parser->in_switch_statement_p = false;
11395 parser->fully_implicit_function_template_p = false;
11396 parser->implicit_template_parms = 0;
11397 parser->implicit_template_scope = 0;
11398 parser->auto_is_implicit_function_template_parm_p = false;
11399 parser->omp_array_section_p = false;
11400
11401 /* The body of a lambda in a discarded statement is not discarded. */
11402 bool discarded = in_discarded_stmt;
11403 in_discarded_stmt = 0;
11404
11405 /* Similarly the body of a lambda in immediate function context is not
11406 in immediate function context. */
11407 bool save_in_consteval_if_p = in_consteval_if_p;
11408 in_consteval_if_p = false;
11409
11410 /* By virtue of defining a local class, a lambda expression has access to
11411 the private variables of enclosing classes. */
11412
11413 if (cp_parser_start_tentative_firewall (parser))
11414 start = token;
11415
11416 ok &= cp_parser_lambda_declarator_opt (parser, lambda_expr);
11417
11418 if (ok && cp_parser_error_occurred (parser))
11419 ok = false;
11420
11421 if (ok)
11422 cp_parser_lambda_body (parser, lambda_expr);
11423 else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
11424 {
11425 if (cp_parser_skip_to_closing_brace (parser))
11426 cp_lexer_consume_token (lexer: parser->lexer);
11427 }
11428
11429 /* The capture list was built up in reverse order; fix that now. */
11430 LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)
11431 = nreverse (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
11432
11433 if (ok)
11434 maybe_add_lambda_conv_op (type);
11435
11436 finish_struct (type, /*attributes=*/NULL_TREE);
11437
11438 in_consteval_if_p = save_in_consteval_if_p;
11439 in_discarded_stmt = discarded;
11440
11441 parser->num_template_parameter_lists = saved_num_template_parameter_lists;
11442 parser->in_statement = in_statement;
11443 parser->in_switch_statement_p = in_switch_statement_p;
11444 parser->fully_implicit_function_template_p
11445 = fully_implicit_function_template_p;
11446 parser->implicit_template_parms = implicit_template_parms;
11447 parser->implicit_template_scope = implicit_template_scope;
11448 parser->auto_is_implicit_function_template_parm_p
11449 = auto_is_implicit_function_template_parm_p;
11450 parser->omp_array_section_p = saved_omp_array_section_p;
11451 }
11452
11453 /* This field is only used during parsing of the lambda. */
11454 LAMBDA_EXPR_THIS_CAPTURE (lambda_expr) = NULL_TREE;
11455
11456 /* This lambda shouldn't have any proxies left at this point. */
11457 gcc_assert (LAMBDA_EXPR_PENDING_PROXIES (lambda_expr) == NULL);
11458 /* And now that we're done, push proxies for an enclosing lambda. */
11459 insert_pending_capture_proxies ();
11460
11461 /* Update the lambda expression to a range. */
11462 LAMBDA_EXPR_LOCATION (lambda_expr) = make_location (caret: token->location,
11463 start: token->location,
11464 lexer: parser->lexer);
11465
11466 if (ok)
11467 lambda_expr = build_lambda_object (lambda_expr);
11468 else
11469 lambda_expr = error_mark_node;
11470
11471 cp_parser_end_tentative_firewall (parser, start, expr: lambda_expr);
11472
11473 pop_deferring_access_checks ();
11474
11475 return lambda_expr;
11476}
11477
11478/* Parse the beginning of a lambda expression.
11479
11480 lambda-introducer:
11481 [ lambda-capture [opt] ]
11482
11483 LAMBDA_EXPR is the current representation of the lambda expression. */
11484
11485static void
11486cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
11487{
11488 /* Need commas after the first capture. */
11489 bool first = true;
11490
11491 /* Eat the leading `['. */
11492 cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
11493
11494 /* Record default capture mode. "[&" "[=" "[&," "[=," */
11495 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_AND)
11496 && !cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_ELLIPSIS)
11497 && !cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME)
11498 && !cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_THIS))
11499 LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE;
11500 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
11501 LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY;
11502
11503 if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE)
11504 {
11505 cp_lexer_consume_token (lexer: parser->lexer);
11506 first = false;
11507
11508 if (!(at_function_scope_p () || parsing_nsdmi ()))
11509 error ("non-local lambda expression cannot have a capture-default");
11510 }
11511
11512 hash_set<tree, true> ids;
11513 tree first_capture_id = NULL_TREE;
11514 unsigned name_independent_cnt = 0;
11515 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_SQUARE))
11516 {
11517 cp_token* capture_token;
11518 tree capture_id;
11519 tree capture_init_expr;
11520 cp_id_kind idk = CP_ID_KIND_NONE;
11521 bool explicit_init_p = false;
11522
11523 enum capture_kind_type
11524 {
11525 BY_COPY,
11526 BY_REFERENCE
11527 };
11528 enum capture_kind_type capture_kind = BY_COPY;
11529
11530 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EOF))
11531 {
11532 error ("expected end of capture-list");
11533 return;
11534 }
11535
11536 if (first)
11537 first = false;
11538 else
11539 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
11540
11541 /* Possibly capture `this'. */
11542 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_THIS))
11543 {
11544 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11545 if (cxx_dialect < cxx20 && pedantic
11546 && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY)
11547 pedwarn (loc, OPT_Wc__20_extensions,
11548 "explicit by-copy capture of %<this%> "
11549 "with by-copy capture default only available with "
11550 "%<-std=c++20%> or %<-std=gnu++20%>");
11551 cp_lexer_consume_token (lexer: parser->lexer);
11552 if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
11553 pedwarn (input_location, 0,
11554 "already captured %qD in lambda expression",
11555 this_identifier);
11556 else
11557 add_capture (lambda_expr, /*id=*/this_identifier,
11558 /*initializer=*/finish_this_expr (),
11559 /*by_reference_p=*/true, explicit_init_p, NULL);
11560 continue;
11561 }
11562
11563 /* Possibly capture `*this'. */
11564 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MULT)
11565 && cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_THIS))
11566 {
11567 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11568 if (cxx_dialect < cxx17)
11569 pedwarn (loc, OPT_Wc__17_extensions,
11570 "%<*this%> capture only available with "
11571 "%<-std=c++17%> or %<-std=gnu++17%>");
11572 cp_lexer_consume_token (lexer: parser->lexer);
11573 cp_lexer_consume_token (lexer: parser->lexer);
11574 if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
11575 pedwarn (input_location, 0,
11576 "already captured %qD in lambda expression",
11577 this_identifier);
11578 else
11579 add_capture (lambda_expr, /*id=*/this_identifier,
11580 /*initializer=*/finish_this_expr (),
11581 /*by_reference_p=*/false, explicit_init_p, NULL);
11582 continue;
11583 }
11584
11585 /* But reject `&this'. */
11586 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_AND)
11587 && cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_THIS))
11588 {
11589 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
11590 "%<this%> cannot be captured by reference");
11591 cp_lexer_consume_token (lexer: parser->lexer);
11592 cp_lexer_consume_token (lexer: parser->lexer);
11593 continue;
11594 }
11595
11596 /* Remember whether we want to capture as a reference or not. */
11597 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_AND))
11598 {
11599 capture_kind = BY_REFERENCE;
11600 cp_lexer_consume_token (lexer: parser->lexer);
11601 }
11602
11603 bool init_pack_expansion = false;
11604 location_t ellipsis_loc = UNKNOWN_LOCATION;
11605 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
11606 {
11607 ellipsis_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11608 if (cxx_dialect < cxx20)
11609 pedwarn (ellipsis_loc, OPT_Wc__20_extensions,
11610 "pack init-capture only available with "
11611 "%<-std=c++20%> or %<-std=gnu++20%>");
11612 cp_lexer_consume_token (lexer: parser->lexer);
11613 init_pack_expansion = true;
11614 }
11615
11616 /* Early C++20 drafts had ...& instead of &...; be forgiving. */
11617 if (init_pack_expansion && capture_kind != BY_REFERENCE
11618 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_AND))
11619 {
11620 pedwarn (cp_lexer_peek_token (lexer: parser->lexer)->location,
11621 0, "%<&%> should come before %<...%>");
11622 capture_kind = BY_REFERENCE;
11623 cp_lexer_consume_token (lexer: parser->lexer);
11624 }
11625
11626 /* Get the identifier. */
11627 capture_token = cp_lexer_peek_token (lexer: parser->lexer);
11628 capture_id = cp_parser_identifier (parser);
11629
11630 if (capture_id == error_mark_node)
11631 /* Would be nice to have a cp_parser_skip_to_closing_x for general
11632 delimiters, but I modified this to stop on unnested ']' as well. It
11633 was already changed to stop on unnested '}', so the
11634 "closing_parenthesis" name is no more misleading with my change. */
11635 {
11636 cp_parser_skip_to_closing_parenthesis (parser,
11637 /*recovering=*/true,
11638 /*or_comma=*/true,
11639 /*consume_paren=*/true);
11640 break;
11641 }
11642
11643 /* Find the initializer for this capture. */
11644 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ)
11645 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN)
11646 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
11647 {
11648 /* An explicit initializer exists. */
11649 if (cxx_dialect < cxx14)
11650 pedwarn (input_location, OPT_Wc__14_extensions,
11651 "lambda capture initializers "
11652 "only available with %<-std=c++14%> or %<-std=gnu++14%>");
11653 capture_init_expr = cp_parser_initializer (parser,
11654 /*direct_init=*/nullptr,
11655 /*non_constant=*/nullptr,
11656 /*subexpression_p=*/true);
11657 explicit_init_p = true;
11658 if (capture_init_expr == NULL_TREE)
11659 {
11660 error ("empty initializer for lambda init-capture");
11661 capture_init_expr = error_mark_node;
11662 }
11663 if (init_pack_expansion)
11664 capture_init_expr = make_pack_expansion (capture_init_expr);
11665 }
11666 else
11667 {
11668 const char* error_msg;
11669
11670 /* Turn the identifier into an id-expression. */
11671 capture_init_expr
11672 = cp_parser_lookup_name_simple (parser, capture_id,
11673 capture_token->location);
11674
11675 if (capture_init_expr == error_mark_node)
11676 {
11677 unqualified_name_lookup_error (capture_id);
11678 continue;
11679 }
11680 else if (!VAR_P (capture_init_expr)
11681 && TREE_CODE (capture_init_expr) != PARM_DECL)
11682 {
11683 error_at (capture_token->location,
11684 "capture of non-variable %qE",
11685 capture_init_expr);
11686 if (DECL_P (capture_init_expr))
11687 inform (DECL_SOURCE_LOCATION (capture_init_expr),
11688 "%q#D declared here", capture_init_expr);
11689 continue;
11690 }
11691 if (VAR_P (capture_init_expr)
11692 && decl_storage_duration (capture_init_expr) != dk_auto)
11693 {
11694 if (pedwarn (capture_token->location, 0, "capture of variable "
11695 "%qD with non-automatic storage duration",
11696 capture_init_expr))
11697 inform (DECL_SOURCE_LOCATION (capture_init_expr),
11698 "%q#D declared here", capture_init_expr);
11699 continue;
11700 }
11701
11702 capture_init_expr
11703 = finish_id_expression
11704 (capture_id,
11705 capture_init_expr,
11706 parser->scope,
11707 &idk,
11708 /*integral_constant_expression_p=*/false,
11709 /*allow_non_integral_constant_expression_p=*/false,
11710 /*non_integral_constant_expression_p=*/NULL,
11711 /*template_p=*/false,
11712 /*done=*/true,
11713 /*address_p=*/false,
11714 /*template_arg_p=*/false,
11715 &error_msg,
11716 capture_token->location);
11717
11718 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
11719 {
11720 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11721 cp_lexer_consume_token (lexer: parser->lexer);
11722 capture_init_expr = make_pack_expansion (capture_init_expr);
11723 if (init_pack_expansion)
11724 {
11725 /* If what follows is an initializer, the second '...' is
11726 invalid. But for cases like [...xs...], the first one
11727 is invalid. */
11728 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ)
11729 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN)
11730 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
11731 ellipsis_loc = loc;
11732 error_at (ellipsis_loc, "too many %<...%> in lambda capture");
11733 continue;
11734 }
11735 }
11736 }
11737
11738 if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
11739 && !explicit_init_p)
11740 {
11741 if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY
11742 && capture_kind == BY_COPY)
11743 pedwarn (capture_token->location, 0, "explicit by-copy capture "
11744 "of %qD redundant with by-copy capture default",
11745 capture_id);
11746 if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_REFERENCE
11747 && capture_kind == BY_REFERENCE)
11748 pedwarn (capture_token->location, 0, "explicit by-reference "
11749 "capture of %qD redundant with by-reference capture "
11750 "default", capture_id);
11751 }
11752
11753 /* Check for duplicates.
11754 Optimize for the zero or one explicit captures cases and only create
11755 the hash_set after adding second capture. */
11756 bool found = false;
11757 if (!ids.is_empty ())
11758 found = ids.add (k: capture_id);
11759 else if (first_capture_id == NULL_TREE)
11760 first_capture_id = capture_id;
11761 else if (capture_id == first_capture_id)
11762 found = true;
11763 else
11764 {
11765 ids.add (k: first_capture_id);
11766 ids.add (k: capture_id);
11767 }
11768 if (found && explicit_init_p && id_equal (id: capture_id, str: "_"))
11769 found = false;
11770 if (found)
11771 pedwarn (input_location, 0,
11772 "already captured %qD in lambda expression", capture_id);
11773 else
11774 add_capture (lambda_expr, capture_id, capture_init_expr,
11775 /*by_reference_p=*/capture_kind == BY_REFERENCE,
11776 explicit_init_p, &name_independent_cnt);
11777
11778 /* If there is any qualification still in effect, clear it
11779 now; we will be starting fresh with the next capture. */
11780 parser->scope = NULL_TREE;
11781 parser->qualifying_scope = NULL_TREE;
11782 parser->object_scope = NULL_TREE;
11783 }
11784
11785 cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
11786}
11787
11788/* Parse the (optional) middle of a lambda expression.
11789
11790 lambda-declarator:
11791 ( parameter-declaration-clause ) lambda-specifiers requires-clause [opt]
11792 lambda-specifiers (C++23)
11793
11794 lambda-specifiers:
11795 decl-specifier-seq [opt] noexcept-specifier [opt]
11796 attribute-specifier-seq [opt] trailing-return-type [opt]
11797
11798 LAMBDA_EXPR is the current representation of the lambda expression. */
11799
11800static bool
11801cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
11802{
11803 /* 5.1.1.4 of the standard says:
11804 If a lambda-expression does not include a lambda-declarator, it is as if
11805 the lambda-declarator were ().
11806 This means an empty parameter list, no attributes, and no exception
11807 specification. */
11808 tree param_list = void_list_node;
11809 tree std_attrs = NULL_TREE;
11810 tree gnu_attrs = NULL_TREE;
11811 tree exception_spec = NULL_TREE;
11812 tree template_param_list = NULL_TREE;
11813 tree tx_qual = NULL_TREE;
11814 tree return_type = NULL_TREE;
11815 tree trailing_requires_clause = NULL_TREE;
11816 bool has_param_list = false;
11817 location_t omitted_parms_loc = UNKNOWN_LOCATION;
11818 cp_decl_specifier_seq lambda_specs;
11819 clear_decl_specs (decl_specs: &lambda_specs);
11820 /* A lambda op() is const unless explicitly 'mutable'. */
11821 cp_cv_quals quals = TYPE_QUAL_CONST;
11822
11823 /* The template-parameter-list is optional, but must begin with
11824 an opening angle if present. */
11825 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_LESS))
11826 {
11827 if (cxx_dialect < cxx20
11828 && (pedantic || cxx_dialect < cxx14))
11829 pedwarn (parser->lexer->next_token->location, OPT_Wc__20_extensions,
11830 "lambda templates are only available with "
11831 "%<-std=c++20%> or %<-std=gnu++20%>");
11832
11833 cp_lexer_consume_token (lexer: parser->lexer);
11834
11835 template_param_list = cp_parser_template_parameter_list (parser);
11836 cp_parser_require_end_of_template_parameter_list (parser);
11837
11838 /* We may have a constrained generic lambda; parse the requires-clause
11839 immediately after the template-parameter-list and combine with any
11840 shorthand constraints present. */
11841 tree dreqs = cp_parser_requires_clause_opt (parser, true);
11842 if (flag_concepts)
11843 {
11844 tree reqs = get_shorthand_constraints (current_template_parms);
11845 if (dreqs)
11846 reqs = combine_constraint_expressions (reqs, dreqs);
11847 TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
11848 }
11849
11850 /* We just processed one more parameter list. */
11851 ++parser->num_template_parameter_lists;
11852 }
11853
11854 /* Committee discussion supports allowing attributes here. */
11855 lambda_specs.attributes = cp_parser_attributes_opt (parser);
11856
11857 /* The parameter-declaration-clause is optional (unless
11858 template-parameter-list was given), but must begin with an
11859 opening parenthesis if present. */
11860 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
11861 {
11862 matching_parens parens;
11863 parens.consume_open (parser);
11864
11865 begin_scope (sk_function_parms, /*entity=*/NULL_TREE);
11866
11867 /* Parse parameters. */
11868 param_list
11869 = cp_parser_parameter_declaration_clause
11870 (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL);
11871
11872 /* Default arguments shall not be specified in the
11873 parameter-declaration-clause of a lambda-declarator. */
11874 if (pedantic && cxx_dialect < cxx14)
11875 for (tree t = param_list; t; t = TREE_CHAIN (t))
11876 if (TREE_PURPOSE (t) && DECL_P (TREE_VALUE (t)))
11877 pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)),
11878 OPT_Wc__14_extensions,
11879 "default argument specified for lambda parameter");
11880
11881 parens.require_close (parser);
11882 has_param_list = true;
11883 }
11884 else if (cxx_dialect < cxx23)
11885 omitted_parms_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
11886
11887 /* [expr.prim.lambda.general]
11888 lambda-specifier:
11889 consteval, constexpr, mutable, static
11890 [4] A lambda-specifier-seq shall contain at most one of each
11891 lambda-specifier and shall not contain both constexpr and consteval.
11892 The lambda-specifier-seq shall not contain both mutable and static. */
11893 int declares_class_or_enum;
11894 if (cp_lexer_next_token_is_decl_specifier_keyword (lexer: parser->lexer))
11895 cp_parser_decl_specifier_seq (parser,
11896 CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR,
11897 &lambda_specs, &declares_class_or_enum);
11898
11899 if (omitted_parms_loc && lambda_specs.any_specifiers_p)
11900 {
11901 pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
11902 "parameter declaration before lambda declaration "
11903 "specifiers only optional with %<-std=c++2b%> or "
11904 "%<-std=gnu++2b%>");
11905 omitted_parms_loc = UNKNOWN_LOCATION;
11906 }
11907 /* Peek at the params, see if we have an xobj parameter. */
11908 if (param_list && TREE_PURPOSE (param_list) == this_identifier)
11909 {
11910 quals = TYPE_UNQUALIFIED;
11911 /* We still need grokdeclarator to see that this is an xobj function
11912 and finish the rest of the work, don't mutate it. */
11913 tree const xobj_param = TREE_VALUE (param_list);
11914 tree const param_type = TREE_TYPE (xobj_param);
11915 /* [expr.prim.lambda.closure-5]
11916 Given a lambda with a lambda-capture, the type of the explicit object
11917 parameter, if any, of the lambda's function call operator (possibly
11918 instantiated from a function call operator template) shall be either:
11919 -- the closure type,
11920 -- a class type derived from the closure type, or
11921 -- a reference to a possibly cv-qualified such type. */
11922 bool const unrelated_with_captures
11923 = (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
11924 || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr))
11925 /* Since a lambda's type is anonymous, we can assume an xobj
11926 parameter is unrelated to the closure if it is non-dependent.
11927 If it is dependent we handle it at instantiation time. */
11928 && !WILDCARD_TYPE_P (non_reference (param_type));
11929 if (unrelated_with_captures)
11930 {
11931 error_at (DECL_SOURCE_LOCATION (xobj_param),
11932 "a lambda with captures may not have an explicit object "
11933 "parameter of an unrelated type");
11934 LAMBDA_EXPR_CAPTURE_LIST (lambda_expr) = NULL_TREE;
11935 }
11936
11937 /* [expr.prim.lambda.general-4]
11938 If the lambda-declarator contains an explicit object parameter
11939 ([dcl.fct]), then no lambda-specifier in the lambda-specifier-seq
11940 shall be mutable or static. */
11941 if (lambda_specs.storage_class == sc_mutable)
11942 {
11943 auto_diagnostic_group d;
11944 error_at (lambda_specs.locations[ds_storage_class],
11945 "%<mutable%> lambda specifier "
11946 "with explicit object parameter");
11947 /* Tell the user how to do what they probably meant, maybe fixits
11948 would be appropriate later? */
11949 if (unrelated_with_captures)
11950 /* The following hints don't make sense when we already have an
11951 unrelated type with captures, don't emit them. */;
11952 else if (!TYPE_REF_P (param_type))
11953 inform (DECL_SOURCE_LOCATION (xobj_param),
11954 "the passed in closure object will not be mutated because "
11955 "it is taken by value");
11956 else if (TYPE_READONLY (TREE_TYPE (param_type)))
11957 inform (DECL_SOURCE_LOCATION (xobj_param),
11958 "declare the explicit object parameter as non-const "
11959 "reference instead");
11960 else
11961 inform (DECL_SOURCE_LOCATION (xobj_param),
11962 "explicit object parameter is already a mutable "
11963 "reference");
11964 }
11965 else if (lambda_specs.storage_class == sc_static)
11966 {
11967 auto_diagnostic_group d;
11968 error_at (lambda_specs.locations[ds_storage_class],
11969 "%<static%> lambda specifier "
11970 "with explicit object parameter");
11971 inform (DECL_SOURCE_LOCATION (xobj_param),
11972 "explicit object parameter declared here");
11973 }
11974 }
11975 else if (lambda_specs.storage_class == sc_mutable)
11976 {
11977 quals = TYPE_UNQUALIFIED;
11978 }
11979 else if (lambda_specs.storage_class == sc_static)
11980 {
11981 /* [expr.prim.lambda.general-4]
11982 If the lambda-specifier-seq contains static, there shall be no
11983 lambda-capture. */
11984 if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
11985 || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr))
11986 error_at (lambda_specs.locations[ds_storage_class],
11987 "%<static%> lambda specifier with lambda capture");
11988 else
11989 {
11990 LAMBDA_EXPR_STATIC_P (lambda_expr) = 1;
11991 quals = TYPE_UNQUALIFIED;
11992 }
11993 }
11994
11995 tx_qual = cp_parser_tx_qualifier_opt (parser);
11996 if (omitted_parms_loc && tx_qual)
11997 {
11998 pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
11999 "parameter declaration before lambda transaction "
12000 "qualifier only optional with %<-std=c++2b%> or "
12001 "%<-std=gnu++2b%>");
12002 omitted_parms_loc = UNKNOWN_LOCATION;
12003 }
12004
12005 /* Parse optional exception specification. */
12006 exception_spec
12007 = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE);
12008
12009 if (omitted_parms_loc && exception_spec)
12010 {
12011 pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
12012 "parameter declaration before lambda exception "
12013 "specification only optional with %<-std=c++2b%> or "
12014 "%<-std=gnu++2b%>");
12015 omitted_parms_loc = UNKNOWN_LOCATION;
12016 }
12017
12018 /* GCC 8 accepted attributes here, and this is the place for standard C++11
12019 attributes that appertain to the function type. */
12020 if (cp_next_tokens_can_be_gnu_attribute_p (parser))
12021 gnu_attrs = cp_parser_gnu_attributes_opt (parser);
12022 else
12023 std_attrs = cp_parser_std_attribute_spec_seq (parser);
12024
12025 /* Parse optional trailing return type. */
12026 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DEREF))
12027 {
12028 if (omitted_parms_loc)
12029 pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
12030 "parameter declaration before lambda trailing "
12031 "return type only optional with %<-std=c++2b%> or "
12032 "%<-std=gnu++2b%>");
12033 cp_lexer_consume_token (lexer: parser->lexer);
12034 return_type = cp_parser_trailing_type_id (parser);
12035 }
12036
12037 /* Also allow GNU attributes at the very end of the declaration, the usual
12038 place for GNU attributes. */
12039 if (cp_next_tokens_can_be_gnu_attribute_p (parser))
12040 gnu_attrs = chainon (gnu_attrs, cp_parser_gnu_attributes_opt (parser));
12041
12042 if (has_param_list)
12043 {
12044 /* Parse optional trailing requires clause. */
12045 trailing_requires_clause = cp_parser_requires_clause_opt (parser, false);
12046
12047 /* The function parameters must be in scope all the way until after the
12048 trailing-return-type in case of decltype. */
12049 pop_bindings_and_leave_scope ();
12050 }
12051
12052 /* Create the function call operator.
12053
12054 Messing with declarators like this is no uglier than building up the
12055 FUNCTION_DECL by hand, and this is less likely to get out of sync with
12056 other code. */
12057 {
12058 cp_decl_specifier_seq return_type_specs;
12059 cp_declarator* declarator;
12060 tree fco;
12061 void *p;
12062
12063 clear_decl_specs (decl_specs: &return_type_specs);
12064 return_type_specs.type = make_auto ();
12065
12066 if (lambda_specs.locations[ds_constexpr])
12067 {
12068 if (cxx_dialect >= cxx17)
12069 return_type_specs.locations[ds_constexpr]
12070 = lambda_specs.locations[ds_constexpr];
12071 else
12072 error_at (lambda_specs.locations[ds_constexpr], "%<constexpr%> "
12073 "lambda only available with %<-std=c++17%> or "
12074 "%<-std=gnu++17%>");
12075 }
12076 if (lambda_specs.locations[ds_consteval])
12077 return_type_specs.locations[ds_consteval]
12078 = lambda_specs.locations[ds_consteval];
12079 if (LAMBDA_EXPR_STATIC_P (lambda_expr))
12080 {
12081 return_type_specs.storage_class = sc_static;
12082 return_type_specs.locations[ds_storage_class]
12083 = lambda_specs.locations[ds_storage_class];
12084 }
12085
12086 p = obstack_alloc (&declarator_obstack, 0);
12087
12088 declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk: sfk_none,
12089 LAMBDA_EXPR_LOCATION (lambda_expr));
12090
12091 declarator = make_call_declarator (target: declarator, parms: param_list, cv_qualifiers: quals,
12092 virt_specifiers: VIRT_SPEC_UNSPECIFIED,
12093 ref_qualifier: REF_QUAL_NONE,
12094 tx_qualifier: tx_qual,
12095 exception_specification: exception_spec,
12096 late_return_type: return_type,
12097 requires_clause: trailing_requires_clause,
12098 std_attrs,
12099 UNKNOWN_LOCATION);
12100
12101 fco = grokmethod (&return_type_specs,
12102 declarator,
12103 chainon (gnu_attrs, lambda_specs.attributes));
12104 if (fco != error_mark_node)
12105 {
12106 DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
12107 DECL_ARTIFICIAL (fco) = 1;
12108 if (DECL_IOBJ_MEMBER_FUNCTION_P (fco))
12109 /* Give the object parameter a different name. */
12110 DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier;
12111 DECL_SET_LAMBDA_FUNCTION (fco, true);
12112 }
12113 if (template_param_list)
12114 {
12115 fco = finish_member_template_decl (fco);
12116 finish_template_decl (template_param_list);
12117 --parser->num_template_parameter_lists;
12118 }
12119 else if (parser->fully_implicit_function_template_p)
12120 fco = finish_fully_implicit_template (parser, fco);
12121
12122 finish_member_declaration (fco);
12123 record_lambda_scope_sig_discriminator (lambda: lambda_expr, fn: fco);
12124
12125 obstack_free (&declarator_obstack, p);
12126
12127 return (fco != error_mark_node);
12128 }
12129}
12130
12131/* Parse the body of a lambda expression, which is simply
12132
12133 compound-statement
12134
12135 but which requires special handling.
12136 LAMBDA_EXPR is the current representation of the lambda expression. */
12137
12138static void
12139cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
12140{
12141 bool nested = (current_function_decl != NULL_TREE);
12142 unsigned char local_variables_forbidden_p
12143 = parser->local_variables_forbidden_p;
12144 bool in_function_body = parser->in_function_body;
12145
12146 /* The body of a lambda-expression is not a subexpression of the enclosing
12147 expression. */
12148 cp_evaluated ev;
12149
12150 if (nested)
12151 push_function_context ();
12152 else
12153 /* Still increment function_depth so that we don't GC in the
12154 middle of an expression. */
12155 ++function_depth;
12156
12157 auto odsd = make_temp_override (var&: parser->omp_declare_simd, NULL);
12158 auto ord = make_temp_override (var&: parser->oacc_routine, NULL);
12159 auto oafp = make_temp_override (var&: parser->omp_attrs_forbidden_p, overrider: false);
12160 vec<tree> omp_privatization_save;
12161 save_omp_privatization_clauses (omp_privatization_save);
12162 /* Clear this in case we're in the middle of a default argument. */
12163 parser->local_variables_forbidden_p = 0;
12164 parser->in_function_body = true;
12165
12166 {
12167 local_specialization_stack s (lss_copy);
12168 tree fco = lambda_function (lambda_expr);
12169 tree body = start_lambda_function (fn: fco, lambda_expr);
12170
12171 /* Originally C++11 required us to peek for 'return expr'; and
12172 process it specially here to deduce the return type. N3638
12173 removed the need for that. */
12174 cp_parser_function_body (parser, false);
12175
12176 finish_lambda_function (body);
12177 }
12178
12179 restore_omp_privatization_clauses (omp_privatization_save);
12180 parser->local_variables_forbidden_p = local_variables_forbidden_p;
12181 parser->in_function_body = in_function_body;
12182 if (nested)
12183 pop_function_context();
12184 else
12185 --function_depth;
12186}
12187
12188/* Statements [gram.stmt.stmt] */
12189
12190/* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */
12191
12192static void
12193add_debug_begin_stmt (location_t loc)
12194{
12195 if (!MAY_HAVE_DEBUG_MARKER_STMTS)
12196 return;
12197 if (DECL_DECLARED_CONCEPT_P (current_function_decl))
12198 /* A concept is never expanded normally. */
12199 return;
12200
12201 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
12202 SET_EXPR_LOCATION (stmt, loc);
12203 add_stmt (stmt);
12204}
12205
12206struct cp_omp_attribute_data
12207{
12208 cp_token_cache *tokens;
12209 const c_omp_directive *dir;
12210 c_omp_directive_kind kind;
12211};
12212
12213/* Handle omp::directive and omp::sequence attributes in ATTRS
12214 (if any) at the start of a statement or in attribute-declaration. */
12215
12216static tree
12217cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs)
12218{
12219 if (!flag_openmp && !flag_openmp_simd)
12220 return attrs;
12221
12222 auto_vec<cp_omp_attribute_data, 16> vec;
12223 int cnt = 0;
12224 int tokens = 0;
12225 bool bad = false;
12226 for (tree *pa = &attrs; *pa; )
12227 if (get_attribute_namespace (*pa) == omp_identifier
12228 && is_attribute_p (attr_name: "directive", ident: get_attribute_name (*pa)))
12229 {
12230 cnt++;
12231 for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
12232 {
12233 tree d = TREE_VALUE (a);
12234 gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
12235 cp_token *first = DEFPARSE_TOKENS (d)->first;
12236 cp_token *last = DEFPARSE_TOKENS (d)->last;
12237 if (parser->omp_attrs_forbidden_p)
12238 {
12239 error_at (first->location,
12240 "mixing OpenMP directives with attribute and pragma "
12241 "syntax on the same statement");
12242 parser->omp_attrs_forbidden_p = false;
12243 bad = true;
12244 }
12245 else if (TREE_PUBLIC (d))
12246 {
12247 error_at (first->location,
12248 "OpenMP %<omp::decl%> attribute on a statement");
12249 bad = true;
12250 }
12251 const char *directive[3] = {};
12252 for (int i = 0; i < 3; i++)
12253 {
12254 tree id = NULL_TREE;
12255 if (first + i == last)
12256 break;
12257 if (first[i].type == CPP_NAME)
12258 id = first[i].u.value;
12259 else if (first[i].type == CPP_KEYWORD)
12260 id = ridpointers[(int) first[i].keyword];
12261 else
12262 break;
12263 directive[i] = IDENTIFIER_POINTER (id);
12264 }
12265 const c_omp_directive *dir = NULL;
12266 if (directive[0])
12267 dir = c_omp_categorize_directive (directive[0], directive[1],
12268 directive[2]);
12269 if (dir == NULL)
12270 {
12271 error_at (first->location,
12272 "unknown OpenMP directive name in %qs attribute "
12273 "argument",
12274 TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
12275 continue;
12276 }
12277 c_omp_directive_kind kind = dir->kind;
12278 if (dir->id == PRAGMA_OMP_ORDERED)
12279 {
12280 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
12281 depend/doacross clause. */
12282 if (directive[1]
12283 && (strcmp (s1: directive[1], s2: "depend") == 0
12284 || strcmp (s1: directive[1], s2: "doacross") == 0))
12285 kind = C_OMP_DIR_STANDALONE;
12286 else if (first + 2 < last
12287 && first[1].type == CPP_COMMA
12288 && first[2].type == CPP_NAME
12289 && (strcmp (IDENTIFIER_POINTER (first[2].u.value),
12290 s2: "depend") == 0
12291 || strcmp (IDENTIFIER_POINTER (first[2].u.value),
12292 s2: "doacross") == 0))
12293 kind = C_OMP_DIR_STANDALONE;
12294 }
12295 else if (dir->id == PRAGMA_OMP_ERROR)
12296 {
12297 /* error with at(execution) clause is C_OMP_DIR_STANDALONE. */
12298 int paren_depth = 0;
12299 for (int i = 1; first + i < last; i++)
12300 if (first[i].type == CPP_OPEN_PAREN)
12301 paren_depth++;
12302 else if (first[i].type == CPP_CLOSE_PAREN)
12303 paren_depth--;
12304 else if (paren_depth == 0
12305 && first + i + 2 < last
12306 && first[i].type == CPP_NAME
12307 && first[i + 1].type == CPP_OPEN_PAREN
12308 && first[i + 2].type == CPP_NAME
12309 && !strcmp (IDENTIFIER_POINTER (first[i].u.value),
12310 s2: "at")
12311 && !strcmp (IDENTIFIER_POINTER (first[i
12312 + 2].u.value),
12313 s2: "execution"))
12314 {
12315 kind = C_OMP_DIR_STANDALONE;
12316 break;
12317 }
12318 }
12319 cp_omp_attribute_data v = { DEFPARSE_TOKENS (d), .dir: dir, .kind: kind };
12320 vec.safe_push (obj: v);
12321 if (flag_openmp || dir->simd)
12322 tokens += (last - first) + 1;
12323 }
12324 cp_omp_attribute_data v = {};
12325 vec.safe_push (obj: v);
12326 *pa = TREE_CHAIN (*pa);
12327 }
12328 else
12329 pa = &TREE_CHAIN (*pa);
12330
12331 if (bad)
12332 return attrs;
12333
12334 unsigned int i;
12335 cp_omp_attribute_data *v;
12336 cp_omp_attribute_data *construct_seen = nullptr;
12337 cp_omp_attribute_data *standalone_seen = nullptr;
12338 cp_omp_attribute_data *prev_standalone_seen = nullptr;
12339 FOR_EACH_VEC_ELT (vec, i, v)
12340 if (v->tokens)
12341 {
12342 if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
12343 construct_seen = v;
12344 else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
12345 standalone_seen = v;
12346 }
12347 else
12348 {
12349 if (standalone_seen && !prev_standalone_seen)
12350 {
12351 prev_standalone_seen = standalone_seen;
12352 standalone_seen = nullptr;
12353 }
12354 }
12355
12356 if (cnt > 1 && construct_seen)
12357 {
12358 error_at (construct_seen->tokens->first->location,
12359 "OpenMP construct among %<omp::directive%> attributes"
12360 " requires all %<omp::directive%> attributes on the"
12361 " same statement to be in the same %<omp::sequence%>");
12362 return attrs;
12363 }
12364 if (cnt > 1 && standalone_seen && prev_standalone_seen)
12365 {
12366 error_at (standalone_seen->tokens->first->location,
12367 "multiple OpenMP standalone directives among"
12368 " %<omp::directive%> attributes must be all within the"
12369 " same %<omp::sequence%>");
12370 return attrs;
12371 }
12372
12373 if (prev_standalone_seen)
12374 standalone_seen = prev_standalone_seen;
12375 if (standalone_seen
12376 && !cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
12377 {
12378 error_at (standalone_seen->tokens->first->location,
12379 "standalone OpenMP directives in %<omp::directive%> attribute"
12380 " can only appear on an empty statement");
12381 return attrs;
12382 }
12383 if (cnt && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_PRAGMA))
12384 {
12385 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
12386 enum pragma_kind kind = cp_parser_pragma_kind (token);
12387 if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
12388 {
12389 error_at (token->location,
12390 "mixing OpenMP directives with attribute and pragma "
12391 "syntax on the same statement");
12392 return attrs;
12393 }
12394 }
12395
12396 if (!tokens)
12397 return attrs;
12398 tokens++;
12399 cp_lexer *lexer = cp_lexer_alloc ();
12400 lexer->debugging_p = parser->lexer->debugging_p;
12401 vec_safe_reserve (v&: lexer->buffer, nelems: tokens, exact: true);
12402 FOR_EACH_VEC_ELT (vec, i, v)
12403 {
12404 if (!v->tokens)
12405 continue;
12406 if (!flag_openmp && !v->dir->simd)
12407 continue;
12408 cp_token *first = v->tokens->first;
12409 cp_token *last = v->tokens->last;
12410 cp_token tok = {};
12411 tok.type = CPP_PRAGMA;
12412 tok.keyword = RID_MAX;
12413 tok.u.value = build_int_cst (NULL, v->dir->id);
12414 tok.location = first->location;
12415 lexer->buffer->quick_push (obj: tok);
12416 while (++first < last)
12417 lexer->buffer->quick_push (obj: *first);
12418 tok = {};
12419 tok.type = CPP_PRAGMA_EOL;
12420 tok.keyword = RID_MAX;
12421 tok.location = last->location;
12422 lexer->buffer->quick_push (obj: tok);
12423 }
12424 cp_token tok = {};
12425 tok.type = CPP_EOF;
12426 tok.keyword = RID_MAX;
12427 tok.location = lexer->buffer->last ().location;
12428 lexer->buffer->quick_push (obj: tok);
12429 lexer->next = parser->lexer;
12430 lexer->next_token = lexer->buffer->address ();
12431 lexer->last_token = lexer->next_token
12432 + lexer->buffer->length ()
12433 - 1;
12434 lexer->in_omp_attribute_pragma = true;
12435 parser->lexer = lexer;
12436 /* Move the current source position to that of the first token in the
12437 new lexer. */
12438 cp_lexer_set_source_position_from_token (token: lexer->next_token);
12439 return attrs;
12440}
12441
12442/* True if and only if the name is one of the contract types. */
12443
12444static bool
12445contract_attribute_p (const_tree id)
12446{
12447 return is_attribute_p (attr_name: "assert", ident: id)
12448 || is_attribute_p (attr_name: "pre", ident: id)
12449 || is_attribute_p (attr_name: "post", ident: id);
12450}
12451
12452/* Handle omp::directive and omp::sequence attributes in *PATTRS
12453 (if any) at the start or after declaration-id of a declaration. */
12454
12455static void
12456cp_parser_handle_directive_omp_attributes (cp_parser *parser, tree *pattrs,
12457 cp_omp_declare_simd_data *data,
12458 bool start)
12459{
12460 if (!flag_openmp && !flag_openmp_simd)
12461 return;
12462
12463 int cnt = 0;
12464 bool bad = false;
12465 bool variant_p = false;
12466 location_t loc = UNKNOWN_LOCATION;
12467 for (tree pa = *pattrs; pa; pa = TREE_CHAIN (pa))
12468 if (get_attribute_namespace (pa) == omp_identifier
12469 && is_attribute_p (attr_name: "directive", ident: get_attribute_name (pa)))
12470 {
12471 for (tree a = TREE_VALUE (pa); a; a = TREE_CHAIN (a))
12472 {
12473 tree d = TREE_VALUE (a);
12474 gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
12475 cp_token *first = DEFPARSE_TOKENS (d)->first;
12476 cp_token *last = DEFPARSE_TOKENS (d)->last;
12477 const char *directive[3] = {};
12478 for (int i = 0; i < 3; i++)
12479 {
12480 tree id = NULL_TREE;
12481 if (first + i == last)
12482 break;
12483 if (first[i].type == CPP_NAME)
12484 id = first[i].u.value;
12485 else if (first[i].type == CPP_KEYWORD)
12486 id = ridpointers[(int) first[i].keyword];
12487 else
12488 break;
12489 directive[i] = IDENTIFIER_POINTER (id);
12490 }
12491 const c_omp_directive *dir = NULL;
12492 if (directive[0])
12493 dir = c_omp_categorize_directive (directive[0], directive[1],
12494 directive[2]);
12495 if (dir == NULL)
12496 continue;
12497 if (dir->id == PRAGMA_OMP_DECLARE
12498 && (strcmp (s1: directive[1], s2: "simd") == 0
12499 || strcmp (s1: directive[1], s2: "variant") == 0))
12500 {
12501 if (cnt++ == 0)
12502 {
12503 variant_p = strcmp (s1: directive[1], s2: "variant") == 0;
12504 loc = first->location;
12505 }
12506 if (start && parser->omp_declare_simd && !bad)
12507 {
12508 error_at (first->location,
12509 "mixing OpenMP directives with attribute and "
12510 "pragma syntax on the same declaration");
12511 bad = true;
12512 }
12513 }
12514 }
12515 }
12516
12517 if (bad)
12518 {
12519 for (tree *pa = pattrs; *pa; )
12520 if (get_attribute_namespace (*pa) == omp_identifier
12521 && is_attribute_p (attr_name: "directive", ident: get_attribute_name (*pa)))
12522 *pa = TREE_CHAIN (*pa);
12523 else
12524 pa = &TREE_CHAIN (*pa);
12525 return;
12526 }
12527 if (cnt == 0)
12528 return;
12529
12530 if (parser->omp_declare_simd == NULL)
12531 {
12532 data->error_seen = false;
12533 data->fndecl_seen = false;
12534 data->variant_p = variant_p;
12535 data->loc = loc;
12536 data->tokens = vNULL;
12537 data->attribs[0] = NULL;
12538 data->attribs[1] = NULL;
12539 parser->omp_declare_simd = data;
12540 }
12541 parser->omp_declare_simd->attribs[!start] = pattrs;
12542}
12543
12544/* Parse a statement.
12545
12546 statement:
12547 labeled-statement
12548 expression-statement
12549 compound-statement
12550 selection-statement
12551 iteration-statement
12552 jump-statement
12553 declaration-statement
12554 try-block
12555
12556 C++11:
12557
12558 statement:
12559 labeled-statement
12560 attribute-specifier-seq (opt) expression-statement
12561 attribute-specifier-seq (opt) compound-statement
12562 attribute-specifier-seq (opt) selection-statement
12563 attribute-specifier-seq (opt) iteration-statement
12564 attribute-specifier-seq (opt) jump-statement
12565 declaration-statement
12566 attribute-specifier-seq (opt) try-block
12567
12568 init-statement:
12569 expression-statement
12570 simple-declaration
12571 alias-declaration
12572
12573 TM Extension:
12574
12575 statement:
12576 atomic-statement
12577
12578 IN_COMPOUND is true when the statement is nested inside a
12579 cp_parser_compound_statement.
12580
12581 If IF_P is not NULL, *IF_P is set to indicate whether the statement
12582 is a (possibly labeled) if statement which is not enclosed in braces
12583 and has an else clause. This is used to implement -Wparentheses.
12584
12585 CHAIN is a vector of if-else-if conditions.
12586
12587 Note that this version of parsing restricts assertions to be attached to
12588 empty statements. */
12589
12590static void
12591cp_parser_statement (cp_parser* parser, tree in_statement_expr,
12592 const bool in_compound, bool *if_p, vec<tree> *chain,
12593 location_t *loc_after_labels)
12594{
12595 tree statement, std_attrs = NULL_TREE;
12596 cp_token *token;
12597 location_t statement_location, attrs_loc;
12598 bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
12599 bool has_std_attrs;
12600 /* A copy of IN_COMPOUND which is set to false after seeing a label.
12601 This matters for certain pragmas. */
12602 bool in_compound_for_pragma = in_compound;
12603
12604 restart:
12605 if (if_p != NULL)
12606 *if_p = false;
12607 /* There is no statement yet. */
12608 statement = NULL_TREE;
12609
12610 saved_token_sentinel saved_tokens (parser->lexer);
12611 token = cp_lexer_peek_token (lexer: parser->lexer);
12612 attrs_loc = token->location;
12613 if (c_dialect_objc ())
12614 /* In obj-c++, seeing '[[' might be the either the beginning of
12615 c++11 attributes, or a nested objc-message-expression. So
12616 let's parse the c++11 attributes tentatively. */
12617 cp_parser_parse_tentatively (parser);
12618 std_attrs = cp_parser_std_attribute_spec_seq (parser);
12619 if (std_attrs)
12620 attrs_loc = make_location (caret: attrs_loc, start: attrs_loc, lexer: parser->lexer);
12621 if (c_dialect_objc ())
12622 {
12623 if (!cp_parser_parse_definitely (parser))
12624 std_attrs = NULL_TREE;
12625 }
12626 has_std_attrs = cp_lexer_peek_token (lexer: parser->lexer) != token;
12627
12628 /* Peek at the next token. */
12629 token = cp_lexer_peek_token (lexer: parser->lexer);
12630
12631 /* If we have contracts, check that they're valid in this context. */
12632 if (std_attrs != error_mark_node)
12633 {
12634 if (tree pre = lookup_attribute (attr_name: "pre", list: std_attrs))
12635 error_at (EXPR_LOCATION (TREE_VALUE (pre)),
12636 "preconditions cannot be statements");
12637 else if (tree post = lookup_attribute (attr_name: "post", list: std_attrs))
12638 error_at (EXPR_LOCATION (TREE_VALUE (post)),
12639 "postconditions cannot be statements");
12640
12641 /* Check that assertions are null statements. */
12642 if (cp_contract_assertion_p (std_attrs))
12643 if (token->type != CPP_SEMICOLON)
12644 error_at (token->location, "assertions must be followed by %<;%>");
12645 }
12646
12647 bool omp_attrs_forbidden_p;
12648 omp_attrs_forbidden_p = parser->omp_attrs_forbidden_p;
12649
12650 if (std_attrs && (flag_openmp || flag_openmp_simd))
12651 {
12652 bool handle_omp_attribs = false;
12653 if (token->type == CPP_KEYWORD)
12654 switch (token->keyword)
12655 {
12656 case RID_IF:
12657 case RID_SWITCH:
12658 case RID_WHILE:
12659 case RID_DO:
12660 case RID_FOR:
12661 case RID_BREAK:
12662 case RID_CONTINUE:
12663 case RID_RETURN:
12664 case RID_CO_RETURN:
12665 case RID_GOTO:
12666 case RID_AT_TRY:
12667 case RID_AT_CATCH:
12668 case RID_AT_FINALLY:
12669 case RID_AT_SYNCHRONIZED:
12670 case RID_AT_THROW:
12671 case RID_TRY:
12672 case RID_TRANSACTION_ATOMIC:
12673 case RID_TRANSACTION_RELAXED:
12674 case RID_SYNCHRONIZED:
12675 case RID_ATOMIC_NOEXCEPT:
12676 case RID_ATOMIC_CANCEL:
12677 case RID_TRANSACTION_CANCEL:
12678 handle_omp_attribs = true;
12679 break;
12680 default:
12681 break;
12682 }
12683 else if (token->type == CPP_SEMICOLON
12684 || token->type == CPP_OPEN_BRACE
12685 || token->type == CPP_PRAGMA)
12686 handle_omp_attribs = true;
12687 if (handle_omp_attribs)
12688 {
12689 std_attrs = cp_parser_handle_statement_omp_attributes (parser,
12690 attrs: std_attrs);
12691 token = cp_lexer_peek_token (lexer: parser->lexer);
12692 }
12693 }
12694 parser->omp_attrs_forbidden_p = false;
12695
12696 /* Remember the location of the first token in the statement. */
12697 cp_token *statement_token = token;
12698 statement_location = token->location;
12699 add_debug_begin_stmt (loc: statement_location);
12700 /* If this is a keyword, then that will often determine what kind of
12701 statement we have. */
12702 if (token->type == CPP_KEYWORD)
12703 {
12704 enum rid keyword = token->keyword;
12705
12706 switch (keyword)
12707 {
12708 case RID_CASE:
12709 case RID_DEFAULT:
12710 /* Looks like a labeled-statement with a case label.
12711 Parse the label, and then use tail recursion to parse
12712 the statement. */
12713 cp_parser_label_for_labeled_statement (parser, std_attrs);
12714 in_compound_for_pragma = false;
12715 in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
12716 goto restart;
12717
12718 case RID_IF:
12719 case RID_SWITCH:
12720 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12721 statement = cp_parser_selection_statement (parser, if_p, chain);
12722 break;
12723
12724 case RID_WHILE:
12725 case RID_DO:
12726 case RID_FOR:
12727 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12728 statement = cp_parser_iteration_statement (parser, if_p, false,
12729 NULL_TREE, false);
12730 break;
12731
12732 case RID_BREAK:
12733 case RID_CONTINUE:
12734 case RID_RETURN:
12735 case RID_CO_RETURN:
12736 case RID_GOTO:
12737 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12738 statement = cp_parser_jump_statement (parser);
12739 break;
12740
12741 /* Objective-C++ exception-handling constructs. */
12742 case RID_AT_TRY:
12743 case RID_AT_CATCH:
12744 case RID_AT_FINALLY:
12745 case RID_AT_SYNCHRONIZED:
12746 case RID_AT_THROW:
12747 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12748 statement = cp_parser_objc_statement (parser);
12749 break;
12750
12751 case RID_TRY:
12752 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12753 statement = cp_parser_try_block (parser);
12754 break;
12755
12756 case RID_NAMESPACE:
12757 /* This must be a namespace alias definition. */
12758 if (has_std_attrs)
12759 {
12760 /* Attributes should be parsed as part of the
12761 declaration, so let's un-parse them. */
12762 saved_tokens.rollback();
12763 std_attrs = NULL_TREE;
12764 }
12765 cp_parser_declaration_statement (parser);
12766 return;
12767
12768 case RID_TRANSACTION_ATOMIC:
12769 case RID_TRANSACTION_RELAXED:
12770 case RID_SYNCHRONIZED:
12771 case RID_ATOMIC_NOEXCEPT:
12772 case RID_ATOMIC_CANCEL:
12773 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12774 statement = cp_parser_transaction (parser, token);
12775 break;
12776 case RID_TRANSACTION_CANCEL:
12777 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12778 statement = cp_parser_transaction_cancel (parser);
12779 break;
12780
12781 default:
12782 /* It might be a keyword like `int' that can start a
12783 declaration-statement. */
12784 break;
12785 }
12786 }
12787 else if (token->type == CPP_NAME)
12788 {
12789 /* If the next token is a `:', then we are looking at a
12790 labeled-statement. */
12791 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
12792 if (token->type == CPP_COLON)
12793 {
12794 /* Looks like a labeled-statement with an ordinary label.
12795 Parse the label, and then use tail recursion to parse
12796 the statement. */
12797
12798 cp_parser_label_for_labeled_statement (parser, std_attrs);
12799
12800 /* If there's no statement, it's not a labeled-statement, just
12801 a label. That's allowed in C++23, but only if we're at the
12802 end of a compound-statement. */
12803 if (in_compound
12804 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
12805 {
12806 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
12807 if (cxx_dialect < cxx23)
12808 pedwarn (loc, OPT_Wc__23_extensions,
12809 "label at end of compound statement only available "
12810 "with %<-std=c++2b%> or %<-std=gnu++2b%>");
12811 return;
12812 }
12813 in_compound_for_pragma = false;
12814 in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
12815 goto restart;
12816 }
12817 }
12818 /* Anything that starts with a `{' must be a compound-statement. */
12819 else if (token->type == CPP_OPEN_BRACE)
12820 {
12821 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12822 statement = cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
12823 }
12824 /* CPP_PRAGMA is a #pragma inside a function body, which constitutes
12825 a statement all its own. */
12826 else if (token->type == CPP_PRAGMA)
12827 {
12828 do_pragma:;
12829 cp_lexer *lexer = parser->lexer;
12830 bool do_restart = false;
12831 /* Only certain OpenMP pragmas are attached to statements, and thus
12832 are considered statements themselves. All others are not. In
12833 the context of a compound, accept the pragma as a "statement" and
12834 return so that we can check for a close brace. Otherwise we
12835 require a real statement and must go back and read one. */
12836 if (in_compound_for_pragma)
12837 {
12838 if (cp_parser_pragma (parser, pragma_compound, if_p)
12839 && parser->omp_for_parse_state)
12840 check_omp_intervening_code (parser);
12841 }
12842 else if (!cp_parser_pragma (parser, pragma_stmt, if_p))
12843 do_restart = true;
12844 else if (parser->omp_for_parse_state)
12845 check_omp_intervening_code (parser);
12846 if (parser->lexer != lexer
12847 && lexer->in_omp_attribute_pragma
12848 && (!in_omp_attribute_pragma || lexer->orphan_p))
12849 {
12850 if (saved_tokens.lexer == lexer)
12851 {
12852 if (saved_tokens.mode == STS_COMMIT)
12853 cp_lexer_commit_tokens (lexer);
12854 gcc_assert (lexer->saved_tokens.length () == saved_tokens.len);
12855 saved_tokens.lexer = parser->lexer;
12856 saved_tokens.mode = STS_DONOTHING;
12857 saved_tokens.len = parser->lexer->saved_tokens.length ();
12858 }
12859 cp_lexer_destroy (lexer);
12860 lexer = parser->lexer;
12861 }
12862 if (do_restart)
12863 goto restart;
12864 if (parser->lexer == lexer
12865 && lexer->in_omp_attribute_pragma
12866 && !in_omp_attribute_pragma)
12867 parser->lexer->orphan_p = true;
12868 return;
12869 }
12870 else if (token->type == CPP_EOF)
12871 {
12872 cp_parser_error (parser, gmsgid: "expected statement");
12873 return;
12874 }
12875
12876 /* Everything else must be a declaration-statement or an
12877 expression-statement. Try for the declaration-statement
12878 first, unless we are looking at a `;', in which case we know that
12879 we have an expression-statement. */
12880 if (!statement)
12881 {
12882 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
12883 {
12884 if (has_std_attrs)
12885 /* Attributes should be parsed as part of the declaration,
12886 so let's un-parse them. */
12887 saved_tokens.rollback();
12888
12889 parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p;
12890 cp_parser_parse_tentatively (parser);
12891 /* Try to parse the declaration-statement. */
12892 cp_parser_declaration_statement (parser);
12893 parser->omp_attrs_forbidden_p = false;
12894 /* If that worked, we're done. */
12895 if (cp_parser_parse_definitely (parser))
12896 return;
12897 /* It didn't work, restore the post-attribute position. */
12898 if (has_std_attrs)
12899 {
12900 cp_lexer_set_token_position (lexer: parser->lexer, pos: statement_token);
12901 if (flag_openmp || flag_openmp_simd)
12902 {
12903 size_t i = 1;
12904 bool handle_omp_attribs = true;
12905 while (cp_lexer_peek_nth_token (lexer: parser->lexer, n: i)->keyword
12906 == RID_EXTENSION)
12907 i++;
12908 switch (cp_lexer_peek_nth_token (lexer: parser->lexer, n: i)->keyword)
12909 {
12910 case RID_ASM:
12911 case RID_NAMESPACE:
12912 case RID_USING:
12913 case RID_LABEL:
12914 case RID_STATIC_ASSERT:
12915 /* Don't handle OpenMP attribs on keywords that
12916 always start a declaration statement but don't
12917 accept attribute before it and therefore
12918 the tentative cp_parser_declaration_statement
12919 fails to parse because of that. */
12920 handle_omp_attribs = false;
12921 break;
12922 default:
12923 break;
12924 }
12925
12926 if (handle_omp_attribs)
12927 {
12928 parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p;
12929 std_attrs
12930 = cp_parser_handle_statement_omp_attributes
12931 (parser, attrs: std_attrs);
12932 parser->omp_attrs_forbidden_p = false;
12933 token = cp_lexer_peek_token (lexer: parser->lexer);
12934 if (token->type == CPP_PRAGMA)
12935 goto do_pragma;
12936 }
12937 }
12938 }
12939 }
12940 /* All preceding labels have been parsed at this point. */
12941 if (loc_after_labels != NULL)
12942 *loc_after_labels = statement_location;
12943
12944 std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
12945
12946 /* Look for an expression-statement instead. */
12947 statement = cp_parser_expression_statement (parser, in_statement_expr);
12948
12949 std_attrs = process_stmt_assume_attribute (std_attrs, statement,
12950 attrs_loc);
12951
12952 /* Handle [[fallthrough]];. */
12953 if (attribute_fallthrough_p (std_attrs))
12954 {
12955 /* The next token after the fallthrough attribute is ';'. */
12956 if (statement == NULL_TREE)
12957 {
12958 /* Turn [[fallthrough]]; into FALLTHROUGH ();. */
12959 statement = build_call_expr_internal_loc (statement_location,
12960 IFN_FALLTHROUGH,
12961 void_type_node, 0);
12962 finish_expr_stmt (statement);
12963 }
12964 else
12965 warning_at (statement_location, OPT_Wattributes,
12966 "%<fallthrough%> attribute not followed by %<;%>");
12967 std_attrs = NULL_TREE;
12968 }
12969
12970 /* Handle [[assert: ...]]; */
12971 if (cp_contract_assertion_p (std_attrs))
12972 {
12973 /* Add the assertion as a statement in the current block. */
12974 gcc_assert (!statement || statement == error_mark_node);
12975 emit_assertion (std_attrs);
12976 std_attrs = NULL_TREE;
12977 }
12978 }
12979
12980 /* Set the line number for the statement. */
12981 if (statement && STATEMENT_CODE_P (TREE_CODE (statement)))
12982 SET_EXPR_LOCATION (statement, statement_location);
12983
12984 /* Allow "[[fallthrough]];" or "[[assume(cond)]];", but warn otherwise. */
12985 if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs))
12986 warning_at (attrs_loc, OPT_Wattributes,
12987 "attributes at the beginning of statement are ignored");
12988}
12989
12990/* Append ATTR to attribute list ATTRS. */
12991
12992tree
12993attr_chainon (tree attrs, tree attr)
12994{
12995 if (attrs == error_mark_node)
12996 return error_mark_node;
12997 if (attr == error_mark_node)
12998 return error_mark_node;
12999 return chainon (attrs, attr);
13000}
13001
13002/* Parse the label for a labeled-statement, i.e.
13003
13004 label:
13005 attribute-specifier-seq[opt] identifier :
13006 attribute-specifier-seq[opt] case constant-expression :
13007 attribute-specifier-seq[opt] default :
13008
13009 labeled-statement:
13010 label statement
13011
13012 GNU Extension:
13013 case constant-expression ... constant-expression : statement
13014
13015 When a label is parsed without errors, the label is added to the
13016 parse tree by the finish_* functions, so this function doesn't
13017 have to return the label. */
13018
13019static void
13020cp_parser_label_for_labeled_statement (cp_parser* parser, tree attributes)
13021{
13022 cp_token *token;
13023 tree label = NULL_TREE;
13024 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
13025
13026 /* The next token should be an identifier. */
13027 token = cp_lexer_peek_token (lexer: parser->lexer);
13028 if (token->type != CPP_NAME
13029 && token->type != CPP_KEYWORD)
13030 {
13031 cp_parser_error (parser, gmsgid: "expected labeled-statement");
13032 return;
13033 }
13034
13035 /* Remember whether this case or a user-defined label is allowed to fall
13036 through to. */
13037 bool fallthrough_p = token->flags & PREV_FALLTHROUGH;
13038
13039 parser->colon_corrects_to_scope_p = false;
13040 switch (token->keyword)
13041 {
13042 case RID_CASE:
13043 {
13044 tree expr, expr_hi;
13045 cp_token *ellipsis;
13046
13047 /* Consume the `case' token. */
13048 cp_lexer_consume_token (lexer: parser->lexer);
13049 /* Parse the constant-expression. */
13050 expr = cp_parser_constant_expression (parser);
13051 if (check_for_bare_parameter_packs (expr))
13052 expr = error_mark_node;
13053
13054 ellipsis = cp_lexer_peek_token (lexer: parser->lexer);
13055 if (ellipsis->type == CPP_ELLIPSIS)
13056 {
13057 /* Consume the `...' token. */
13058 cp_lexer_consume_token (lexer: parser->lexer);
13059 expr_hi = cp_parser_constant_expression (parser);
13060 if (check_for_bare_parameter_packs (expr_hi))
13061 expr_hi = error_mark_node;
13062
13063 /* We don't need to emit warnings here, as the common code
13064 will do this for us. */
13065 }
13066 else
13067 expr_hi = NULL_TREE;
13068
13069 if (parser->in_switch_statement_p)
13070 {
13071 tree l = finish_case_label (token->location, expr, expr_hi);
13072 if (l && TREE_CODE (l) == CASE_LABEL_EXPR)
13073 {
13074 label = CASE_LABEL (l);
13075 FALLTHROUGH_LABEL_P (label) = fallthrough_p;
13076 }
13077 }
13078 else
13079 error_at (token->location,
13080 "case label %qE not within a switch statement",
13081 expr);
13082 }
13083 break;
13084
13085 case RID_DEFAULT:
13086 /* Consume the `default' token. */
13087 cp_lexer_consume_token (lexer: parser->lexer);
13088
13089 if (parser->in_switch_statement_p)
13090 {
13091 tree l = finish_case_label (token->location, NULL_TREE, NULL_TREE);
13092 if (l && TREE_CODE (l) == CASE_LABEL_EXPR)
13093 {
13094 label = CASE_LABEL (l);
13095 FALLTHROUGH_LABEL_P (label) = fallthrough_p;
13096 }
13097 }
13098 else
13099 error_at (token->location, "case label not within a switch statement");
13100 break;
13101
13102 default:
13103 /* Anything else must be an ordinary label. */
13104 label = finish_label_stmt (cp_parser_identifier (parser));
13105 if (label && TREE_CODE (label) == LABEL_DECL)
13106 FALLTHROUGH_LABEL_P (label) = fallthrough_p;
13107 break;
13108 }
13109
13110 /* Require the `:' token. */
13111 cp_parser_require (parser, CPP_COLON, RT_COLON);
13112
13113 /* An ordinary label may optionally be followed by attributes.
13114 However, this is only permitted if the attributes are then
13115 followed by a semicolon. This is because, for backward
13116 compatibility, when parsing
13117 lab: __attribute__ ((unused)) int i;
13118 we want the attribute to attach to "i", not "lab". */
13119 if (label != NULL_TREE
13120 && cp_next_tokens_can_be_gnu_attribute_p (parser))
13121 {
13122 tree attrs;
13123 cp_parser_parse_tentatively (parser);
13124 attrs = cp_parser_gnu_attributes_opt (parser);
13125 if (attrs == NULL_TREE
13126 /* And fallthrough always binds to the expression-statement. */
13127 || attribute_fallthrough_p (attrs)
13128 || cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
13129 cp_parser_abort_tentative_parse (parser);
13130 else if (!cp_parser_parse_definitely (parser))
13131 ;
13132 else
13133 attributes = attr_chainon (attrs: attributes, attr: attrs);
13134 }
13135
13136 if (attributes != NULL_TREE)
13137 cplus_decl_attributes (&label, attributes, 0);
13138
13139 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
13140}
13141
13142/* Parse an expression-statement.
13143
13144 expression-statement:
13145 expression [opt] ;
13146
13147 Returns the new EXPR_STMT -- or NULL_TREE if the expression
13148 statement consists of nothing more than an `;'. IN_STATEMENT_EXPR_P
13149 indicates whether this expression-statement is part of an
13150 expression statement. */
13151
13152static tree
13153cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
13154{
13155 tree statement = NULL_TREE;
13156 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
13157 location_t loc = token->location;
13158
13159 /* There might be attribute fallthrough. */
13160 tree attr = cp_parser_gnu_attributes_opt (parser);
13161
13162 /* If the next token is a ';', then there is no expression
13163 statement. */
13164 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
13165 {
13166 statement = cp_parser_expression (parser);
13167 if (statement == error_mark_node
13168 && !cp_parser_uncommitted_to_tentative_parse_p (parser))
13169 {
13170 /* If we ran into a problem, make sure we complained. */
13171 gcc_assert (seen_error ());
13172
13173 cp_parser_skip_to_end_of_block_or_statement (parser);
13174 return error_mark_node;
13175 }
13176 }
13177
13178 attr = process_stmt_assume_attribute (attr, statement, loc);
13179
13180 /* Handle [[fallthrough]];. */
13181 if (attribute_fallthrough_p (attr))
13182 {
13183 /* The next token after the fallthrough attribute is ';'. */
13184 if (statement == NULL_TREE)
13185 /* Turn [[fallthrough]]; into FALLTHROUGH ();. */
13186 statement = build_call_expr_internal_loc (loc, IFN_FALLTHROUGH,
13187 void_type_node, 0);
13188 else
13189 warning_at (loc, OPT_Wattributes,
13190 "%<fallthrough%> attribute not followed by %<;%>");
13191 attr = NULL_TREE;
13192 }
13193
13194 /* Allow "[[fallthrough]];", but warn otherwise. */
13195 if (attr != NULL_TREE && any_nonignored_attribute_p (attr))
13196 warning_at (loc, OPT_Wattributes,
13197 "attributes at the beginning of statement are ignored");
13198
13199 /* Give a helpful message for "A<T>::type t;" and the like. */
13200 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON)
13201 && !cp_parser_uncommitted_to_tentative_parse_p (parser))
13202 {
13203 if (TREE_CODE (statement) == SCOPE_REF)
13204 error_at (token->location, "need %<typename%> before %qE because "
13205 "%qT is a dependent scope",
13206 statement, TREE_OPERAND (statement, 0));
13207 else if (is_overloaded_fn (statement)
13208 && DECL_CONSTRUCTOR_P (get_first_fn (statement)))
13209 {
13210 /* A::A a; */
13211 tree fn = get_first_fn (statement);
13212 error_at (token->location,
13213 "%<%T::%D%> names the constructor, not the type",
13214 DECL_CONTEXT (fn), DECL_NAME (fn));
13215 }
13216 }
13217
13218 /* Consume the final `;'. */
13219 cp_parser_consume_semicolon_at_end_of_statement (parser);
13220
13221 if (in_statement_expr
13222 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
13223 /* This is the final expression statement of a statement
13224 expression. */
13225 statement = finish_stmt_expr_expr (statement, in_statement_expr);
13226 else if (statement)
13227 statement = finish_expr_stmt (statement);
13228
13229 return statement;
13230}
13231
13232/* Parse a compound-statement.
13233
13234 compound-statement:
13235 { statement-seq [opt] label-seq [opt] }
13236
13237 label-seq:
13238 label
13239 label-seq label
13240
13241 GNU extension:
13242
13243 compound-statement:
13244 { label-declaration-seq [opt] statement-seq [opt] }
13245
13246 label-declaration-seq:
13247 label-declaration
13248 label-declaration-seq label-declaration
13249
13250 Returns a tree representing the statement. */
13251
13252static tree
13253cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
13254 int bcs_flags, bool function_body)
13255{
13256 tree compound_stmt;
13257 matching_braces braces;
13258
13259 /* Consume the `{'. */
13260 if (!braces.require_open (parser))
13261 return error_mark_node;
13262 if (DECL_DECLARED_CONSTEXPR_P (current_function_decl)
13263 && !function_body && cxx_dialect < cxx14)
13264 pedwarn (input_location, OPT_Wpedantic,
13265 "compound-statement in %<constexpr%> function");
13266 /* Begin the compound-statement. */
13267 compound_stmt = begin_compound_stmt (bcs_flags);
13268 /* If the next keyword is `__label__' we have a label declaration. */
13269 while (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_LABEL))
13270 cp_parser_label_declaration (parser);
13271 /* Parse an (optional) statement-seq. */
13272 cp_parser_statement_seq_opt (parser, in_statement_expr);
13273
13274 /* Consume the `}'. */
13275 braces.require_close (parser);
13276
13277 /* Finish the compound-statement. */
13278 finish_compound_stmt (compound_stmt);
13279
13280 return compound_stmt;
13281}
13282
13283/* Diagnose errors related to imperfectly nested loops in an OMP
13284 loop construct. This function is called when such code is seen.
13285 Only issue one such diagnostic no matter how much invalid
13286 intervening code there is in the loop.
13287 FIXME: maybe the location associated with the diagnostic should
13288 be the current parser token instead of the location of the outer loop
13289 nest. */
13290
13291static void
13292check_omp_intervening_code (cp_parser *parser)
13293{
13294 struct omp_for_parse_data *omp_for_parse_state
13295 = parser->omp_for_parse_state;
13296 gcc_assert (omp_for_parse_state);
13297
13298 if (!omp_for_parse_state->in_intervening_code)
13299 return;
13300 omp_for_parse_state->saw_intervening_code = true;
13301
13302 /* Only diagnose errors related to perfect nesting once. */
13303 if (!omp_for_parse_state->perfect_nesting_fail)
13304 {
13305 if (omp_for_parse_state->code == OACC_LOOP)
13306 {
13307 error_at (omp_for_parse_state->for_loc,
13308 "inner loops must be perfectly nested in "
13309 "%<#pragma acc loop%>");
13310 omp_for_parse_state->perfect_nesting_fail = true;
13311 }
13312 else if (omp_for_parse_state->ordered)
13313 {
13314 error_at (omp_for_parse_state->for_loc,
13315 "inner loops must be perfectly nested with "
13316 "%<ordered%> clause");
13317 omp_for_parse_state->perfect_nesting_fail = true;
13318 }
13319 else if (omp_for_parse_state->inscan)
13320 {
13321 error_at (omp_for_parse_state->for_loc,
13322 "inner loops must be perfectly nested with "
13323 "%<reduction%> %<inscan%> clause");
13324 omp_for_parse_state->perfect_nesting_fail = true;
13325 }
13326 /* TODO: Also reject loops with TILE directive. */
13327 if (omp_for_parse_state->perfect_nesting_fail)
13328 omp_for_parse_state->fail = true;
13329 }
13330}
13331
13332/* Parse an (optional) statement-seq.
13333
13334 statement-seq:
13335 statement
13336 statement-seq [opt] statement */
13337
13338static void
13339cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
13340{
13341 struct omp_for_parse_data *omp_for_parse_state
13342 = parser->omp_for_parse_state;
13343 bool in_omp_loop_block
13344 = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
13345
13346 /* Scan statements until there aren't any more. */
13347 while (true)
13348 {
13349 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
13350
13351 /* If we are looking at a `}', then we have run out of
13352 statements; the same is true if we have reached the end
13353 of file, or have stumbled upon a stray '@end'. */
13354 if (token->type == CPP_CLOSE_BRACE
13355 || token->type == CPP_EOF
13356 || token->type == CPP_PRAGMA_EOL
13357 || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END))
13358 break;
13359
13360 /* If we are in a compound statement and find 'else' then
13361 something went wrong. */
13362 else if (token->type == CPP_KEYWORD && token->keyword == RID_ELSE)
13363 {
13364 if (parser->in_statement & IN_IF_STMT)
13365 break;
13366 else
13367 {
13368 token = cp_lexer_consume_token (lexer: parser->lexer);
13369 error_at (token->location, "%<else%> without a previous %<if%>");
13370 }
13371 }
13372
13373 /* Handle special cases for OMP FOR canonical loop syntax. */
13374 else if (in_omp_loop_block)
13375 {
13376 bool want_nested_loop = omp_for_parse_state->want_nested_loop;
13377 if (want_nested_loop
13378 && token->type == CPP_KEYWORD && token->keyword == RID_FOR)
13379 {
13380 /* Found the nested loop. */
13381 omp_for_parse_state->depth++;
13382 add_stmt (cp_parser_omp_loop_nest (parser, NULL));
13383 omp_for_parse_state->depth--;
13384 }
13385 else if (token->type == CPP_SEMICOLON)
13386 {
13387 /* Prior to implementing the OpenMP 5.1 syntax for canonical
13388 loop form, GCC used to accept an empty statements as not
13389 being intervening code. Continue to do that, as an
13390 extension. */
13391 /* FIXME: Maybe issue a warning or something here? */
13392 cp_lexer_consume_token (lexer: parser->lexer);
13393 }
13394 else if (want_nested_loop && token->type == CPP_OPEN_BRACE)
13395 /* The nested compound statement may contain the next loop, or
13396 it might just be intervening code. */
13397 {
13398 cp_parser_statement (parser, in_statement_expr, in_compound: true, NULL);
13399 if (omp_for_parse_state->want_nested_loop)
13400 check_omp_intervening_code (parser);
13401 }
13402 else
13403 {
13404 /* This must be intervening code. */
13405 omp_for_parse_state->want_nested_loop = false;
13406 /* Defer calling check_omp_intervening_code on pragmas until
13407 cp_parser_statement, because we can't know until we parse
13408 it whether or not the pragma is a statement. */
13409 if (token->type != CPP_PRAGMA)
13410 check_omp_intervening_code (parser);
13411 cp_parser_statement (parser, in_statement_expr, in_compound: true, NULL);
13412 omp_for_parse_state->want_nested_loop = want_nested_loop;
13413 }
13414 continue;
13415 }
13416
13417 /* Parse the statement. */
13418 cp_parser_statement (parser, in_statement_expr, in_compound: true, NULL);
13419 }
13420}
13421
13422/* Return true if this is the C++20 version of range-based-for with
13423 init-statement. */
13424
13425static bool
13426cp_parser_range_based_for_with_init_p (cp_parser *parser)
13427{
13428 bool r = false;
13429
13430 /* Save tokens so that we can put them back. */
13431 cp_lexer_save_tokens (lexer: parser->lexer);
13432
13433 /* There has to be an unnested ; followed by an unnested :. */
13434 if (cp_parser_skip_to_closing_parenthesis_1 (parser,
13435 /*recovering=*/false,
13436 or_ttype: CPP_SEMICOLON,
13437 /*consume_paren=*/false) != -1)
13438 goto out;
13439
13440 /* We found the semicolon, eat it now. */
13441 cp_lexer_consume_token (lexer: parser->lexer);
13442
13443 /* Now look for ':' that is not nested in () or {}. */
13444 r = (cp_parser_skip_to_closing_parenthesis_1 (parser,
13445 /*recovering=*/false,
13446 or_ttype: CPP_COLON,
13447 /*consume_paren=*/false) == -1);
13448
13449out:
13450 /* Roll back the tokens we skipped. */
13451 cp_lexer_rollback_tokens (lexer: parser->lexer);
13452
13453 return r;
13454}
13455
13456/* Return true if we're looking at (init; cond), false otherwise. */
13457
13458static bool
13459cp_parser_init_statement_p (cp_parser *parser)
13460{
13461 /* Save tokens so that we can put them back. */
13462 cp_lexer_save_tokens (lexer: parser->lexer);
13463
13464 /* Look for ';' that is not nested in () or {}. */
13465 int ret = cp_parser_skip_to_closing_parenthesis_1 (parser,
13466 /*recovering=*/false,
13467 or_ttype: CPP_SEMICOLON,
13468 /*consume_paren=*/false);
13469
13470 /* Roll back the tokens we skipped. */
13471 cp_lexer_rollback_tokens (lexer: parser->lexer);
13472
13473 return ret == -1;
13474}
13475
13476/* Parse a selection-statement.
13477
13478 selection-statement:
13479 if ( init-statement [opt] condition ) statement
13480 if ( init-statement [opt] condition ) statement else statement
13481 switch ( init-statement [opt] condition ) statement
13482
13483 Returns the new IF_STMT or SWITCH_STMT.
13484
13485 If IF_P is not NULL, *IF_P is set to indicate whether the statement
13486 is a (possibly labeled) if statement which is not enclosed in
13487 braces and has an else clause. This is used to implement
13488 -Wparentheses.
13489
13490 CHAIN is a vector of if-else-if conditions. This is used to implement
13491 -Wduplicated-cond. */
13492
13493static tree
13494cp_parser_selection_statement (cp_parser* parser, bool *if_p,
13495 vec<tree> *chain)
13496{
13497 cp_token *token;
13498 enum rid keyword;
13499 token_indent_info guard_tinfo;
13500
13501 if (if_p != NULL)
13502 *if_p = false;
13503
13504 /* Peek at the next token. */
13505 token = cp_parser_require (parser, CPP_KEYWORD, RT_SELECT);
13506 guard_tinfo = get_token_indent_info (token);
13507
13508 /* See what kind of keyword it is. */
13509 keyword = token->keyword;
13510 switch (keyword)
13511 {
13512 case RID_IF:
13513 case RID_SWITCH:
13514 {
13515 tree statement;
13516 tree condition;
13517
13518 bool cx = false;
13519 if (keyword == RID_IF
13520 && cp_lexer_next_token_is_keyword (lexer: parser->lexer,
13521 keyword: RID_CONSTEXPR))
13522 {
13523 cx = true;
13524 cp_token *tok = cp_lexer_consume_token (lexer: parser->lexer);
13525 if (cxx_dialect < cxx17)
13526 pedwarn (tok->location, OPT_Wc__17_extensions,
13527 "%<if constexpr%> only available with "
13528 "%<-std=c++17%> or %<-std=gnu++17%>");
13529 }
13530 int ce = 0;
13531 if (keyword == RID_IF && !cx)
13532 {
13533 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer,
13534 keyword: RID_CONSTEVAL))
13535 ce = 1;
13536 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NOT)
13537 && cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2,
13538 keyword: RID_CONSTEVAL))
13539 {
13540 ce = -1;
13541 cp_lexer_consume_token (lexer: parser->lexer);
13542 }
13543 }
13544 if (ce)
13545 {
13546 cp_token *tok = cp_lexer_consume_token (lexer: parser->lexer);
13547 if (cxx_dialect < cxx23)
13548 pedwarn (tok->location, OPT_Wc__23_extensions,
13549 "%<if consteval%> only available with "
13550 "%<-std=c++2b%> or %<-std=gnu++2b%>");
13551
13552 bool save_in_consteval_if_p = in_consteval_if_p;
13553 statement = begin_if_stmt ();
13554 IF_STMT_CONSTEVAL_P (statement) = true;
13555 condition = finish_if_stmt_cond (boolean_false_node, statement);
13556
13557 gcc_rich_location richloc (tok->location);
13558 bool non_compound_stmt_p = false;
13559 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_BRACE))
13560 {
13561 non_compound_stmt_p = true;
13562 richloc.add_fixit_insert_after (where: tok->location, new_content: "{");
13563 }
13564
13565 in_consteval_if_p |= ce > 0;
13566 cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);
13567
13568 if (non_compound_stmt_p)
13569 {
13570 location_t before_loc
13571 = cp_lexer_peek_token (lexer: parser->lexer)->location;
13572 richloc.add_fixit_insert_before (where: before_loc, new_content: "}");
13573 error_at (&richloc,
13574 "%<if consteval%> requires compound statement");
13575 non_compound_stmt_p = false;
13576 }
13577
13578 finish_then_clause (statement);
13579
13580 /* If the next token is `else', parse the else-clause. */
13581 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer,
13582 keyword: RID_ELSE))
13583 {
13584 cp_token *else_tok = cp_lexer_peek_token (lexer: parser->lexer);
13585 gcc_rich_location else_richloc (else_tok->location);
13586 guard_tinfo = get_token_indent_info (token: else_tok);
13587 /* Consume the `else' keyword. */
13588 cp_lexer_consume_token (lexer: parser->lexer);
13589
13590 begin_else_clause (statement);
13591
13592 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_BRACE))
13593 {
13594 non_compound_stmt_p = true;
13595 else_richloc.add_fixit_insert_after (where: else_tok->location,
13596 new_content: "{");
13597 }
13598
13599 in_consteval_if_p = save_in_consteval_if_p | (ce < 0);
13600 cp_parser_implicitly_scoped_statement (parser, NULL,
13601 guard_tinfo);
13602
13603 if (non_compound_stmt_p)
13604 {
13605 location_t before_loc
13606 = cp_lexer_peek_token (lexer: parser->lexer)->location;
13607 else_richloc.add_fixit_insert_before (where: before_loc, new_content: "}");
13608 error_at (&else_richloc,
13609 "%<if consteval%> requires compound statement");
13610 }
13611
13612 finish_else_clause (statement);
13613 }
13614
13615 in_consteval_if_p = save_in_consteval_if_p;
13616 if (ce < 0)
13617 {
13618 std::swap (THEN_CLAUSE (statement), ELSE_CLAUSE (statement));
13619 if (THEN_CLAUSE (statement) == NULL_TREE)
13620 THEN_CLAUSE (statement) = build_empty_stmt (tok->location);
13621 }
13622
13623 finish_if_stmt (statement);
13624 return statement;
13625 }
13626
13627 /* Look for the `('. */
13628 matching_parens parens;
13629 if (!parens.require_open (parser))
13630 {
13631 cp_parser_skip_to_end_of_statement (parser);
13632 return error_mark_node;
13633 }
13634
13635 /* Begin the selection-statement. */
13636 if (keyword == RID_IF)
13637 {
13638 statement = begin_if_stmt ();
13639 IF_STMT_CONSTEXPR_P (statement) = cx;
13640 }
13641 else
13642 statement = begin_switch_stmt ();
13643
13644 /* Parse the optional init-statement. */
13645 if (cp_parser_init_statement_p (parser))
13646 {
13647 tree decl;
13648 if (cxx_dialect < cxx17)
13649 pedwarn (cp_lexer_peek_token (lexer: parser->lexer)->location,
13650 OPT_Wc__17_extensions,
13651 "init-statement in selection statements only available "
13652 "with %<-std=c++17%> or %<-std=gnu++17%>");
13653 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
13654 /* A non-empty init-statement can have arbitrary side
13655 effects. */
13656 vec_free (v&: chain);
13657 cp_parser_init_statement (parser, decl: &decl);
13658 }
13659
13660 /* Parse the condition. */
13661 condition = cp_parser_condition (parser);
13662 /* Look for the `)'. */
13663 if (!parens.require_close (parser))
13664 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false,
13665 /*consume_paren=*/true);
13666
13667 if (keyword == RID_IF)
13668 {
13669 bool nested_if;
13670 unsigned char in_statement;
13671
13672 /* Add the condition. */
13673 condition = finish_if_stmt_cond (condition, statement);
13674
13675 if (warn_duplicated_cond)
13676 warn_duplicated_cond_add_or_warn (token->location, condition,
13677 &chain);
13678
13679 /* Parse the then-clause. */
13680 in_statement = parser->in_statement;
13681 parser->in_statement |= IN_IF_STMT;
13682
13683 /* Outside a template, the non-selected branch of a constexpr
13684 if is a 'discarded statement', i.e. unevaluated. */
13685 bool was_discarded = in_discarded_stmt;
13686 bool discard_then = (cx && !processing_template_decl
13687 && integer_zerop (condition));
13688 if (discard_then)
13689 {
13690 in_discarded_stmt = true;
13691 ++c_inhibit_evaluation_warnings;
13692 }
13693
13694 cp_parser_implicitly_scoped_statement (parser, &nested_if,
13695 guard_tinfo);
13696
13697 parser->in_statement = in_statement;
13698
13699 finish_then_clause (statement);
13700
13701 if (discard_then)
13702 {
13703 THEN_CLAUSE (statement) = NULL_TREE;
13704 in_discarded_stmt = was_discarded;
13705 --c_inhibit_evaluation_warnings;
13706 }
13707
13708 /* If the next token is `else', parse the else-clause. */
13709 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer,
13710 keyword: RID_ELSE))
13711 {
13712 bool discard_else = (cx && !processing_template_decl
13713 && integer_nonzerop (condition));
13714 if (discard_else)
13715 {
13716 in_discarded_stmt = true;
13717 ++c_inhibit_evaluation_warnings;
13718 }
13719
13720 guard_tinfo
13721 = get_token_indent_info (token: cp_lexer_peek_token (lexer: parser->lexer));
13722 /* Consume the `else' keyword. */
13723 cp_lexer_consume_token (lexer: parser->lexer);
13724 if (warn_duplicated_cond)
13725 {
13726 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer,
13727 keyword: RID_IF)
13728 && chain == NULL)
13729 {
13730 /* We've got "if (COND) else if (COND2)". Start
13731 the condition chain and add COND as the first
13732 element. */
13733 chain = new vec<tree> ();
13734 if (!CONSTANT_CLASS_P (condition)
13735 && !TREE_SIDE_EFFECTS (condition))
13736 {
13737 /* Wrap it in a NOP_EXPR so that we can set the
13738 location of the condition. */
13739 tree e = build1 (NOP_EXPR, TREE_TYPE (condition),
13740 condition);
13741 SET_EXPR_LOCATION (e, token->location);
13742 chain->safe_push (obj: e);
13743 }
13744 }
13745 else if (!cp_lexer_next_token_is_keyword (lexer: parser->lexer,
13746 keyword: RID_IF))
13747 /* This is if-else without subsequent if. Zap the
13748 condition chain; we would have already warned at
13749 this point. */
13750 vec_free (v&: chain);
13751 }
13752 begin_else_clause (statement);
13753 /* Parse the else-clause. */
13754 cp_parser_implicitly_scoped_statement (parser, NULL,
13755 guard_tinfo, chain);
13756
13757 finish_else_clause (statement);
13758
13759 /* If we are currently parsing a then-clause, then
13760 IF_P will not be NULL. We set it to true to
13761 indicate that this if statement has an else clause.
13762 This may trigger the Wparentheses warning below
13763 when we get back up to the parent if statement. */
13764 if (if_p != NULL)
13765 *if_p = true;
13766
13767 if (discard_else)
13768 {
13769 ELSE_CLAUSE (statement) = NULL_TREE;
13770 in_discarded_stmt = was_discarded;
13771 --c_inhibit_evaluation_warnings;
13772 }
13773 }
13774 else
13775 {
13776 /* This if statement does not have an else clause. If
13777 NESTED_IF is true, then the then-clause has an if
13778 statement which does have an else clause. We warn
13779 about the potential ambiguity. */
13780 if (nested_if)
13781 warning_at (EXPR_LOCATION (statement), OPT_Wdangling_else,
13782 "suggest explicit braces to avoid ambiguous"
13783 " %<else%>");
13784 if (warn_duplicated_cond)
13785 /* We don't need the condition chain anymore. */
13786 vec_free (v&: chain);
13787 }
13788
13789 /* Now we're all done with the if-statement. */
13790 finish_if_stmt (statement);
13791 }
13792 else
13793 {
13794 bool in_switch_statement_p;
13795 unsigned char in_statement;
13796
13797 /* Add the condition. */
13798 finish_switch_cond (condition, statement);
13799
13800 /* Parse the body of the switch-statement. */
13801 in_switch_statement_p = parser->in_switch_statement_p;
13802 in_statement = parser->in_statement;
13803 parser->in_switch_statement_p = true;
13804 parser->in_statement |= IN_SWITCH_STMT;
13805 cp_parser_implicitly_scoped_statement (parser, if_p,
13806 guard_tinfo);
13807 parser->in_switch_statement_p = in_switch_statement_p;
13808 parser->in_statement = in_statement;
13809
13810 /* Now we're all done with the switch-statement. */
13811 finish_switch_stmt (statement);
13812 }
13813
13814 return statement;
13815 }
13816 break;
13817
13818 default:
13819 cp_parser_error (parser, gmsgid: "expected selection-statement");
13820 return error_mark_node;
13821 }
13822}
13823
13824/* Helper function for cp_parser_condition and cp_parser_simple_declaration.
13825 If we have seen at least one decl-specifier, and the next token is not
13826 a parenthesis (after "int (" we might be looking at a functional cast)
13827 neither we are dealing with a concept-check expression then we must be
13828 looking at a declaration. */
13829
13830static void
13831cp_parser_maybe_commit_to_declaration (cp_parser* parser,
13832 cp_decl_specifier_seq *decl_specs)
13833{
13834 if (decl_specs->any_specifiers_p
13835 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_PAREN)
13836 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_BRACE)
13837 && !cp_parser_error_occurred (parser)
13838 && !(decl_specs->type
13839 && TREE_CODE (decl_specs->type) == TYPE_DECL
13840 && is_constrained_auto (TREE_TYPE (decl_specs->type))))
13841 cp_parser_commit_to_tentative_parse (parser);
13842}
13843
13844/* Helper function for cp_parser_condition. Enforces [stmt.stmt]/2:
13845 The declarator shall not specify a function or an array. Returns
13846 TRUE if the declarator is valid, FALSE otherwise. */
13847
13848static bool
13849cp_parser_check_condition_declarator (cp_parser* parser,
13850 cp_declarator *declarator,
13851 location_t loc)
13852{
13853 if (declarator == cp_error_declarator
13854 || function_declarator_p (declarator)
13855 || declarator->kind == cdk_array)
13856 {
13857 if (declarator == cp_error_declarator)
13858 /* Already complained. */;
13859 else if (declarator->kind == cdk_array)
13860 error_at (loc, "condition declares an array");
13861 else
13862 error_at (loc, "condition declares a function");
13863 if (parser->fully_implicit_function_template_p)
13864 abort_fully_implicit_template (parser);
13865 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
13866 /*or_comma=*/false,
13867 /*consume_paren=*/false);
13868 return false;
13869 }
13870 else
13871 return true;
13872}
13873
13874/* Parse a condition.
13875
13876 condition:
13877 expression
13878 type-specifier-seq declarator = initializer-clause
13879 type-specifier-seq declarator braced-init-list
13880
13881 GNU Extension:
13882
13883 condition:
13884 type-specifier-seq declarator asm-specification [opt]
13885 attributes [opt] = assignment-expression
13886
13887 Returns the expression that should be tested. */
13888
13889static tree
13890cp_parser_condition (cp_parser* parser)
13891{
13892 cp_decl_specifier_seq type_specifiers;
13893 const char *saved_message;
13894 int declares_class_or_enum;
13895
13896 /* Try the declaration first. */
13897 cp_parser_parse_tentatively (parser);
13898 /* New types are not allowed in the type-specifier-seq for a
13899 condition. */
13900 saved_message = parser->type_definition_forbidden_message;
13901 parser->type_definition_forbidden_message
13902 = G_("types may not be defined in conditions");
13903 /* Parse the type-specifier-seq. */
13904 cp_parser_decl_specifier_seq (parser,
13905 CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR,
13906 &type_specifiers,
13907 &declares_class_or_enum);
13908 /* Restore the saved message. */
13909 parser->type_definition_forbidden_message = saved_message;
13910
13911 /* Gather the attributes that were provided with the
13912 decl-specifiers. */
13913 tree prefix_attributes = type_specifiers.attributes;
13914
13915 cp_parser_maybe_commit_to_declaration (parser, decl_specs: &type_specifiers);
13916
13917 /* If all is well, we might be looking at a declaration. */
13918 if (!cp_parser_error_occurred (parser))
13919 {
13920 tree decl;
13921 tree asm_specification;
13922 tree attributes;
13923 cp_declarator *declarator;
13924 tree initializer = NULL_TREE;
13925 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
13926
13927 /* Parse the declarator. */
13928 declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
13929 CP_PARSER_FLAGS_NONE,
13930 /*ctor_dtor_or_conv_p=*/NULL,
13931 /*parenthesized_p=*/NULL,
13932 /*member_p=*/false,
13933 /*friend_p=*/false,
13934 /*static_p=*/false);
13935 /* Parse the attributes. */
13936 attributes = cp_parser_attributes_opt (parser);
13937 /* Parse the asm-specification. */
13938 asm_specification = cp_parser_asm_specification_opt (parser);
13939 /* If the next token is not an `=' or '{', then we might still be
13940 looking at an expression. For example:
13941
13942 if (A(a).x)
13943
13944 looks like a decl-specifier-seq and a declarator -- but then
13945 there is no `=', so this is an expression. */
13946 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_EQ)
13947 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_BRACE))
13948 cp_parser_simulate_error (parser);
13949
13950 /* If we did see an `=' or '{', then we are looking at a declaration
13951 for sure. */
13952 if (cp_parser_parse_definitely (parser))
13953 {
13954 tree pushed_scope;
13955 bool non_constant_p = false;
13956 int flags = LOOKUP_ONLYCONVERTING;
13957
13958 if (!cp_parser_check_condition_declarator (parser, declarator, loc))
13959 return error_mark_node;
13960
13961 /* Create the declaration. */
13962 decl = start_decl (declarator, &type_specifiers,
13963 /*initialized_p=*/true,
13964 attributes, prefix_attributes,
13965 &pushed_scope);
13966
13967 declarator->init_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
13968 /* Parse the initializer. */
13969 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
13970 {
13971 initializer = cp_parser_braced_list (parser, &non_constant_p);
13972 CONSTRUCTOR_IS_DIRECT_INIT (initializer) = 1;
13973 flags = 0;
13974 }
13975 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
13976 {
13977 /* Consume the `='. */
13978 cp_lexer_consume_token (lexer: parser->lexer);
13979 initializer = cp_parser_initializer_clause (parser,
13980 &non_constant_p);
13981 }
13982 else
13983 {
13984 cp_parser_error (parser, gmsgid: "expected initializer");
13985 initializer = error_mark_node;
13986 }
13987 if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
13988 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
13989
13990 /* Process the initializer. */
13991 cp_finish_decl (decl,
13992 initializer, !non_constant_p,
13993 asm_specification,
13994 flags);
13995
13996 if (pushed_scope)
13997 pop_scope (pushed_scope);
13998
13999 return convert_from_reference (decl);
14000 }
14001 }
14002 /* If we didn't even get past the declarator successfully, we are
14003 definitely not looking at a declaration. */
14004 else
14005 cp_parser_abort_tentative_parse (parser);
14006
14007 /* Otherwise, we are looking at an expression. */
14008 return cp_parser_expression (parser);
14009}
14010
14011/* Parses a for-statement or range-for-statement until the closing ')',
14012 not included. */
14013
14014static tree
14015cp_parser_for (cp_parser *parser, bool ivdep, tree unroll, bool novector)
14016{
14017 tree init, scope, decl;
14018 bool is_range_for;
14019
14020 /* Begin the for-statement. */
14021 scope = begin_for_scope (&init);
14022
14023 /* Maybe parse the optional init-statement in a range-based for loop. */
14024 if (cp_parser_range_based_for_with_init_p (parser)
14025 /* Checked for diagnostic purposes only. */
14026 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
14027 {
14028 tree dummy;
14029 cp_parser_init_statement (parser, decl: &dummy);
14030 if (cxx_dialect < cxx20)
14031 {
14032 pedwarn (cp_lexer_peek_token (lexer: parser->lexer)->location,
14033 OPT_Wc__20_extensions,
14034 "range-based %<for%> loops with initializer only "
14035 "available with %<-std=c++20%> or %<-std=gnu++20%>");
14036 decl = error_mark_node;
14037 }
14038 }
14039
14040 /* Parse the initialization. */
14041 is_range_for = cp_parser_init_statement (parser, decl: &decl);
14042
14043 if (is_range_for)
14044 return cp_parser_range_for (parser, scope, init, decl, ivdep, unroll,
14045 novector, false);
14046 else
14047 return cp_parser_c_for (parser, scope, init, ivdep, unroll, novector);
14048}
14049
14050static tree
14051cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep,
14052 tree unroll, bool novector)
14053{
14054 /* Normal for loop */
14055 tree condition = NULL_TREE;
14056 tree expression = NULL_TREE;
14057 tree stmt;
14058
14059 stmt = begin_for_stmt (scope, init);
14060 /* The init-statement has already been parsed in
14061 cp_parser_init_statement, so no work is needed here. */
14062 finish_init_stmt (stmt);
14063
14064 /* If there's a condition, process it. */
14065 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
14066 condition = cp_parser_condition (parser);
14067 else if (ivdep)
14068 {
14069 cp_parser_error (parser, gmsgid: "missing loop condition in loop with "
14070 "%<GCC ivdep%> pragma");
14071 condition = error_mark_node;
14072 }
14073 else if (unroll)
14074 {
14075 cp_parser_error (parser, gmsgid: "missing loop condition in loop with "
14076 "%<GCC unroll%> pragma");
14077 condition = error_mark_node;
14078 }
14079 finish_for_cond (condition, stmt, ivdep, unroll, novector);
14080 /* Look for the `;'. */
14081 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
14082
14083 /* If there's an expression, process it. */
14084 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
14085 expression = cp_parser_expression (parser);
14086 finish_for_expr (expression, stmt);
14087
14088 return stmt;
14089}
14090
14091/* Tries to parse a range-based for-statement:
14092
14093 range-based-for:
14094 decl-specifier-seq declarator : expression
14095
14096 The decl-specifier-seq declarator and the `:' are already parsed by
14097 cp_parser_init_statement. If processing_template_decl it returns a
14098 newly created RANGE_FOR_STMT; if not, it is converted to a
14099 regular FOR_STMT. */
14100
14101static tree
14102cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
14103 bool ivdep, tree unroll, bool novector, bool is_omp)
14104{
14105 tree stmt, range_expr;
14106 auto_vec <cxx_binding *, 16> bindings;
14107 auto_vec <tree, 16> names;
14108 cp_decomp decomp_d, *decomp = NULL;
14109
14110 /* Get the range declaration momentarily out of the way so that
14111 the range expression doesn't clash with it. */
14112 if (range_decl != error_mark_node)
14113 {
14114 if (DECL_HAS_VALUE_EXPR_P (range_decl))
14115 {
14116 tree v = DECL_VALUE_EXPR (range_decl);
14117 /* For decomposition declaration get all of the corresponding
14118 declarations out of the way. */
14119 if (TREE_CODE (v) == ARRAY_REF
14120 && VAR_P (TREE_OPERAND (v, 0))
14121 && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
14122 {
14123 tree d = range_decl;
14124 range_decl = TREE_OPERAND (v, 0);
14125 decomp = &decomp_d;
14126 decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
14127 decomp->decl = d;
14128 for (unsigned int i = 0; i < decomp->count;
14129 i++, d = DECL_CHAIN (d))
14130 {
14131 tree name = DECL_NAME (d);
14132 names.safe_push (obj: name);
14133 bindings.safe_push (IDENTIFIER_BINDING (name));
14134 IDENTIFIER_BINDING (name)
14135 = IDENTIFIER_BINDING (name)->previous;
14136 }
14137 }
14138 }
14139 if (names.is_empty ())
14140 {
14141 tree name = DECL_NAME (range_decl);
14142 names.safe_push (obj: name);
14143 bindings.safe_push (IDENTIFIER_BINDING (name));
14144 IDENTIFIER_BINDING (name) = IDENTIFIER_BINDING (name)->previous;
14145 }
14146 }
14147
14148 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
14149 range_expr = cp_parser_braced_list (parser);
14150 else
14151 range_expr = cp_parser_expression (parser);
14152
14153 /* Put the range declaration(s) back into scope. */
14154 for (unsigned int i = 0; i < names.length (); i++)
14155 {
14156 cxx_binding *binding = bindings[i];
14157 binding->previous = IDENTIFIER_BINDING (names[i]);
14158 IDENTIFIER_BINDING (names[i]) = binding;
14159 }
14160
14161 /* finish_omp_for has its own code for the following, so just
14162 return the range_expr instead. */
14163 if (is_omp)
14164 return range_expr;
14165
14166 /* If in template, STMT is converted to a normal for-statement
14167 at instantiation. If not, it is done just ahead. */
14168 if (processing_template_decl)
14169 {
14170 if (check_for_bare_parameter_packs (range_expr))
14171 range_expr = error_mark_node;
14172 stmt = begin_range_for_stmt (scope, init);
14173 if (ivdep)
14174 RANGE_FOR_IVDEP (stmt) = 1;
14175 if (unroll)
14176 RANGE_FOR_UNROLL (stmt) = unroll;
14177 if (novector)
14178 RANGE_FOR_NOVECTOR (stmt) = 1;
14179 finish_range_for_decl (stmt, range_decl, range_expr);
14180 if (!type_dependent_expression_p (range_expr)
14181 /* do_auto_deduction doesn't mess with template init-lists. */
14182 && !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
14183 do_range_for_auto_deduction (range_decl, range_expr, decomp);
14184 }
14185 else
14186 {
14187 stmt = begin_for_stmt (scope, init);
14188 stmt = cp_convert_range_for (stmt, range_decl, range_expr, decomp,
14189 ivdep, unroll, novector);
14190 }
14191 return stmt;
14192}
14193
14194/* Subroutine of cp_convert_range_for: given the initializer expression,
14195 builds up the range temporary. */
14196
14197static tree
14198build_range_temp (tree range_expr)
14199{
14200 /* Find out the type deduced by the declaration
14201 `auto &&__range = range_expr'. */
14202 tree auto_node = make_auto ();
14203 tree range_type = cp_build_reference_type (auto_node, true);
14204 range_type = do_auto_deduction (range_type, range_expr, auto_node);
14205
14206 /* Create the __range variable. */
14207 tree range_temp = build_decl (input_location, VAR_DECL,
14208 for_range__identifier, range_type);
14209 TREE_USED (range_temp) = 1;
14210 DECL_ARTIFICIAL (range_temp) = 1;
14211
14212 return range_temp;
14213}
14214
14215/* Used by cp_parser_range_for in template context: we aren't going to
14216 do a full conversion yet, but we still need to resolve auto in the
14217 type of the for-range-declaration if present. This is basically
14218 a shortcut version of cp_convert_range_for. */
14219
14220static void
14221do_range_for_auto_deduction (tree decl, tree range_expr, cp_decomp *decomp)
14222{
14223 tree auto_node = type_uses_auto (TREE_TYPE (decl));
14224 if (auto_node)
14225 {
14226 tree begin_dummy, end_dummy, range_temp, iter_type, iter_decl;
14227 range_temp = convert_from_reference (build_range_temp (range_expr));
14228 iter_type = (cp_parser_perform_range_for_lookup
14229 (range_temp, &begin_dummy, &end_dummy));
14230 if (iter_type)
14231 {
14232 iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE,
14233 iter_type);
14234 iter_decl = build_x_indirect_ref (input_location, iter_decl,
14235 RO_UNARY_STAR, NULL_TREE,
14236 tf_warning_or_error);
14237 TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
14238 iter_decl, auto_node,
14239 tf_warning_or_error,
14240 adc_variable_type);
14241 if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
14242 cp_finish_decomp (decl, decomp);
14243 }
14244 }
14245}
14246
14247/* Warns when the loop variable should be changed to a reference type to
14248 avoid unnecessary copying. I.e., from
14249
14250 for (const auto x : range)
14251
14252 where range returns a reference, to
14253
14254 for (const auto &x : range)
14255
14256 if this version doesn't make a copy.
14257
14258 This function also warns when the loop variable is initialized with
14259 a value of a different type resulting in a copy:
14260
14261 int arr[10];
14262 for (const double &x : arr)
14263
14264 DECL is the RANGE_DECL; EXPR is the *__for_begin expression.
14265 This function is never called when processing_template_decl is on. */
14266
14267static void
14268warn_for_range_copy (tree decl, tree expr)
14269{
14270 if (!warn_range_loop_construct
14271 || decl == error_mark_node)
14272 return;
14273
14274 location_t loc = DECL_SOURCE_LOCATION (decl);
14275 tree type = TREE_TYPE (decl);
14276
14277 if (from_macro_expansion_at (loc))
14278 return;
14279
14280 if (TYPE_REF_P (type))
14281 {
14282 if (glvalue_p (expr)
14283 && ref_conv_binds_to_temporary (type, expr).is_true ())
14284 {
14285 auto_diagnostic_group d;
14286 if (warning_at (loc, OPT_Wrange_loop_construct,
14287 "loop variable %qD of type %qT binds to a temporary "
14288 "constructed from type %qT", decl, type,
14289 TREE_TYPE (expr)))
14290 {
14291 tree ref = cp_build_qualified_type (TREE_TYPE (expr),
14292 TYPE_QUAL_CONST);
14293 ref = cp_build_reference_type (ref, /*rval*/false);
14294 inform (loc, "use non-reference type %qT to make the copy "
14295 "explicit or %qT to prevent copying",
14296 non_reference (type), ref);
14297 }
14298 }
14299 return;
14300 }
14301 else if (!CP_TYPE_CONST_P (type))
14302 return;
14303
14304 /* Since small trivially copyable types are cheap to copy, we suppress the
14305 warning for them. 64B is a common size of a cache line. */
14306 if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
14307 || (tree_to_uhwi (TYPE_SIZE_UNIT (type)) <= 64
14308 && trivially_copyable_p (type)))
14309 return;
14310
14311 /* If we can initialize a reference directly, suggest that to avoid the
14312 copy. */
14313 tree rtype = cp_build_reference_type (type, /*rval*/false);
14314 if (ref_conv_binds_to_temporary (rtype, expr).is_false ())
14315 {
14316 auto_diagnostic_group d;
14317 if (warning_at (loc, OPT_Wrange_loop_construct,
14318 "loop variable %qD creates a copy from type %qT",
14319 decl, type))
14320 {
14321 gcc_rich_location richloc (loc);
14322 richloc.add_fixit_insert_before (new_content: "&");
14323 inform (&richloc, "use reference type to prevent copying");
14324 }
14325 }
14326}
14327
14328/* Converts a range-based for-statement into a normal
14329 for-statement, as per the definition.
14330
14331 for (RANGE_DECL : RANGE_EXPR)
14332 BLOCK
14333
14334 should be equivalent to:
14335
14336 {
14337 auto &&__range = RANGE_EXPR;
14338 for (auto __begin = BEGIN_EXPR, __end = END_EXPR;
14339 __begin != __end;
14340 ++__begin)
14341 {
14342 RANGE_DECL = *__begin;
14343 BLOCK
14344 }
14345 }
14346
14347 If RANGE_EXPR is an array:
14348 BEGIN_EXPR = __range
14349 END_EXPR = __range + ARRAY_SIZE(__range)
14350 Else if RANGE_EXPR has a member 'begin' or 'end':
14351 BEGIN_EXPR = __range.begin()
14352 END_EXPR = __range.end()
14353 Else:
14354 BEGIN_EXPR = begin(__range)
14355 END_EXPR = end(__range);
14356
14357 If __range has a member 'begin' but not 'end', or vice versa, we must
14358 still use the second alternative (it will surely fail, however).
14359 When calling begin()/end() in the third alternative we must use
14360 argument dependent lookup, but always considering 'std' as an associated
14361 namespace. */
14362
14363tree
14364cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
14365 cp_decomp *decomp, bool ivdep, tree unroll,
14366 bool novector)
14367{
14368 tree begin, end;
14369 tree iter_type, begin_expr, end_expr;
14370 tree condition, expression;
14371
14372 range_expr = mark_lvalue_use (range_expr);
14373
14374 if (range_decl == error_mark_node || range_expr == error_mark_node)
14375 /* If an error happened previously do nothing or else a lot of
14376 unhelpful errors would be issued. */
14377 begin_expr = end_expr = iter_type = error_mark_node;
14378 else
14379 {
14380 tree range_temp;
14381
14382 if (VAR_P (range_expr)
14383 && array_of_runtime_bound_p (TREE_TYPE (range_expr)))
14384 /* Can't bind a reference to an array of runtime bound. */
14385 range_temp = range_expr;
14386 else
14387 {
14388 range_temp = build_range_temp (range_expr);
14389 pushdecl (range_temp);
14390 cp_finish_decl (range_temp, range_expr,
14391 /*is_constant_init*/false, NULL_TREE,
14392 LOOKUP_ONLYCONVERTING);
14393 range_temp = convert_from_reference (range_temp);
14394 }
14395 iter_type = cp_parser_perform_range_for_lookup (range_temp,
14396 &begin_expr, &end_expr);
14397 }
14398
14399 /* The new for initialization statement. */
14400 begin = build_decl (input_location, VAR_DECL, for_begin__identifier,
14401 iter_type);
14402 TREE_USED (begin) = 1;
14403 DECL_ARTIFICIAL (begin) = 1;
14404 pushdecl (begin);
14405 cp_finish_decl (begin, begin_expr,
14406 /*is_constant_init*/false, NULL_TREE,
14407 LOOKUP_ONLYCONVERTING);
14408
14409 if (cxx_dialect >= cxx17)
14410 iter_type = cv_unqualified (TREE_TYPE (end_expr));
14411 end = build_decl (input_location, VAR_DECL, for_end__identifier, iter_type);
14412 TREE_USED (end) = 1;
14413 DECL_ARTIFICIAL (end) = 1;
14414 pushdecl (end);
14415 cp_finish_decl (end, end_expr,
14416 /*is_constant_init*/false, NULL_TREE,
14417 LOOKUP_ONLYCONVERTING);
14418
14419 finish_init_stmt (statement);
14420
14421 /* The new for condition. */
14422 condition = build_x_binary_op (input_location, NE_EXPR,
14423 begin, ERROR_MARK,
14424 end, ERROR_MARK,
14425 NULL_TREE, NULL, tf_warning_or_error);
14426 finish_for_cond (condition, statement, ivdep, unroll, novector);
14427
14428 /* The new increment expression. */
14429 expression = finish_unary_op_expr (input_location,
14430 PREINCREMENT_EXPR, begin,
14431 tf_warning_or_error);
14432 finish_for_expr (expression, statement);
14433
14434 /* The declaration is initialized with *__begin inside the loop body. */
14435 tree deref_begin = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
14436 NULL_TREE, tf_warning_or_error);
14437 cp_finish_decl (range_decl, deref_begin,
14438 /*is_constant_init*/false, NULL_TREE,
14439 LOOKUP_ONLYCONVERTING, decomp);
14440 if (VAR_P (range_decl) && DECL_DECOMPOSITION_P (range_decl))
14441 cp_finish_decomp (range_decl, decomp);
14442
14443 warn_for_range_copy (decl: range_decl, expr: deref_begin);
14444
14445 return statement;
14446}
14447
14448/* Solves BEGIN_EXPR and END_EXPR as described in cp_convert_range_for.
14449 We need to solve both at the same time because the method used
14450 depends on the existence of members begin or end.
14451 Returns the type deduced for the iterator expression. */
14452
14453static tree
14454cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
14455{
14456 if (error_operand_p (t: range))
14457 {
14458 *begin = *end = error_mark_node;
14459 return error_mark_node;
14460 }
14461
14462 if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (range))))
14463 {
14464 error ("range-based %<for%> expression of type %qT "
14465 "has incomplete type", TREE_TYPE (range));
14466 *begin = *end = error_mark_node;
14467 return error_mark_node;
14468 }
14469 if (TREE_CODE (TREE_TYPE (range)) == ARRAY_TYPE)
14470 {
14471 /* If RANGE is an array, we will use pointer arithmetic. */
14472 *begin = decay_conversion (range, tf_warning_or_error);
14473 *end = build_binary_op (input_location, PLUS_EXPR,
14474 range,
14475 array_type_nelts_top (TREE_TYPE (range)),
14476 false);
14477 return TREE_TYPE (*begin);
14478 }
14479 else
14480 {
14481 /* If it is not an array, we must do a bit of magic. */
14482 tree id_begin, id_end;
14483 tree member_begin, member_end;
14484
14485 *begin = *end = error_mark_node;
14486
14487 id_begin = get_identifier ("begin");
14488 id_end = get_identifier ("end");
14489 member_begin = lookup_member (TREE_TYPE (range), id_begin,
14490 /*protect=*/2, /*want_type=*/false,
14491 tf_warning_or_error);
14492 member_end = lookup_member (TREE_TYPE (range), id_end,
14493 /*protect=*/2, /*want_type=*/false,
14494 tf_warning_or_error);
14495
14496 if (member_begin != NULL_TREE && member_end != NULL_TREE)
14497 {
14498 /* Use the member functions. */
14499 *begin = cp_parser_range_for_member_function (range, id_begin);
14500 *end = cp_parser_range_for_member_function (range, id_end);
14501 }
14502 else
14503 {
14504 /* Use global functions with ADL. */
14505 releasing_vec vec;
14506
14507 vec_safe_push (r&: vec, t: range);
14508
14509 member_begin = perform_koenig_lookup (id_begin, vec,
14510 tf_warning_or_error);
14511 *begin = finish_call_expr (member_begin, &vec, false, true,
14512 tf_warning_or_error);
14513 member_end = perform_koenig_lookup (id_end, vec,
14514 tf_warning_or_error);
14515 *end = finish_call_expr (member_end, &vec, false, true,
14516 tf_warning_or_error);
14517 }
14518
14519 /* Last common checks. */
14520 if (*begin == error_mark_node || *end == error_mark_node)
14521 {
14522 /* If one of the expressions is an error do no more checks. */
14523 *begin = *end = error_mark_node;
14524 return error_mark_node;
14525 }
14526 else if (type_dependent_expression_p (*begin)
14527 || type_dependent_expression_p (*end))
14528 /* Can happen, when, eg, in a template context, Koenig lookup
14529 can't resolve begin/end (c++/58503). */
14530 return NULL_TREE;
14531 else
14532 {
14533 tree iter_type = cv_unqualified (TREE_TYPE (*begin));
14534 /* The unqualified type of the __begin and __end temporaries should
14535 be the same, as required by the multiple auto declaration. */
14536 if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (*end))))
14537 {
14538 if (cxx_dialect >= cxx17
14539 && (build_x_binary_op (input_location, NE_EXPR,
14540 *begin, ERROR_MARK,
14541 *end, ERROR_MARK,
14542 NULL_TREE, NULL, tf_none)
14543 != error_mark_node))
14544 /* P0184R0 allows __begin and __end to have different types,
14545 but make sure they are comparable so we can give a better
14546 diagnostic. */;
14547 else
14548 error ("inconsistent begin/end types in range-based %<for%> "
14549 "statement: %qT and %qT",
14550 TREE_TYPE (*begin), TREE_TYPE (*end));
14551 }
14552 return iter_type;
14553 }
14554 }
14555}
14556
14557/* Helper function for cp_parser_perform_range_for_lookup.
14558 Builds a tree for RANGE.IDENTIFIER(). */
14559
14560static tree
14561cp_parser_range_for_member_function (tree range, tree identifier)
14562{
14563 tree member, res;
14564
14565 member = finish_class_member_access_expr (range, identifier,
14566 false, tf_warning_or_error);
14567 if (member == error_mark_node)
14568 return error_mark_node;
14569
14570 releasing_vec vec;
14571 res = finish_call_expr (member, &vec,
14572 /*disallow_virtual=*/false,
14573 /*koenig_p=*/false,
14574 tf_warning_or_error);
14575 return res;
14576}
14577
14578/* Parse an iteration-statement.
14579
14580 iteration-statement:
14581 while ( condition ) statement
14582 do statement while ( expression ) ;
14583 for ( init-statement condition [opt] ; expression [opt] )
14584 statement
14585
14586 Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT. */
14587
14588static tree
14589cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep,
14590 tree unroll, bool novector)
14591{
14592 cp_token *token;
14593 enum rid keyword;
14594 tree statement;
14595 unsigned char in_statement;
14596 token_indent_info guard_tinfo;
14597
14598 /* Peek at the next token. */
14599 token = cp_parser_require (parser, CPP_KEYWORD, RT_ITERATION);
14600 if (!token)
14601 return error_mark_node;
14602
14603 guard_tinfo = get_token_indent_info (token);
14604
14605 /* Remember whether or not we are already within an iteration
14606 statement. */
14607 in_statement = parser->in_statement;
14608
14609 /* Special case for OMP loop intervening code. Parsing of permitted
14610 collapsed loop nests is handled elsewhere. */
14611 if (parser->omp_for_parse_state)
14612 {
14613 error_at (token->location,
14614 "loop not permitted in intervening code in OpenMP loop body");
14615 parser->omp_for_parse_state->fail = true;
14616 }
14617
14618 /* See what kind of keyword it is. */
14619 keyword = token->keyword;
14620 switch (keyword)
14621 {
14622 case RID_WHILE:
14623 {
14624 tree condition;
14625
14626 /* Begin the while-statement. */
14627 statement = begin_while_stmt ();
14628 /* Look for the `('. */
14629 matching_parens parens;
14630 parens.require_open (parser);
14631 /* Parse the condition. */
14632 condition = cp_parser_condition (parser);
14633 finish_while_stmt_cond (condition, statement, ivdep, unroll, novector);
14634 /* Look for the `)'. */
14635 parens.require_close (parser);
14636 /* Parse the dependent statement. */
14637 parser->in_statement = IN_ITERATION_STMT;
14638 bool prev = note_iteration_stmt_body_start ();
14639 cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
14640 note_iteration_stmt_body_end (prev);
14641 parser->in_statement = in_statement;
14642 /* We're done with the while-statement. */
14643 finish_while_stmt (statement);
14644 }
14645 break;
14646
14647 case RID_DO:
14648 {
14649 tree expression;
14650
14651 /* Begin the do-statement. */
14652 statement = begin_do_stmt ();
14653 /* Parse the body of the do-statement. */
14654 parser->in_statement = IN_ITERATION_STMT;
14655 bool prev = note_iteration_stmt_body_start ();
14656 cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);
14657 note_iteration_stmt_body_end (prev);
14658 parser->in_statement = in_statement;
14659 finish_do_body (statement);
14660 /* Look for the `while' keyword. */
14661 cp_parser_require_keyword (parser, RID_WHILE, RT_WHILE);
14662 /* Look for the `('. */
14663 matching_parens parens;
14664 parens.require_open (parser);
14665 /* Parse the expression. */
14666 expression = cp_parser_expression (parser);
14667 /* We're done with the do-statement. */
14668 finish_do_stmt (expression, statement, ivdep, unroll, novector);
14669 /* Look for the `)'. */
14670 parens.require_close (parser);
14671 /* Look for the `;'. */
14672 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
14673 }
14674 break;
14675
14676 case RID_FOR:
14677 {
14678 /* Look for the `('. */
14679 matching_parens parens;
14680 parens.require_open (parser);
14681
14682 statement = cp_parser_for (parser, ivdep, unroll, novector);
14683
14684 /* Look for the `)'. */
14685 parens.require_close (parser);
14686
14687 /* Parse the body of the for-statement. */
14688 parser->in_statement = IN_ITERATION_STMT;
14689 bool prev = note_iteration_stmt_body_start ();
14690 cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
14691 note_iteration_stmt_body_end (prev);
14692 parser->in_statement = in_statement;
14693
14694 /* We're done with the for-statement. */
14695 finish_for_stmt (statement);
14696 }
14697 break;
14698
14699 default:
14700 cp_parser_error (parser, gmsgid: "expected iteration-statement");
14701 statement = error_mark_node;
14702 break;
14703 }
14704
14705 return statement;
14706}
14707
14708/* Parse an init-statement or the declarator of a range-based-for.
14709 Returns true if a range-based-for declaration is seen.
14710
14711 init-statement:
14712 expression-statement
14713 simple-declaration
14714 alias-declaration */
14715
14716static bool
14717cp_parser_init_statement (cp_parser *parser, tree *decl)
14718{
14719 /* If the next token is a `;', then we have an empty
14720 expression-statement. Grammatically, this is also a
14721 simple-declaration, but an invalid one, because it does not
14722 declare anything. Therefore, if we did not handle this case
14723 specially, we would issue an error message about an invalid
14724 declaration. */
14725 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
14726 {
14727 bool is_range_for = false;
14728 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
14729
14730 /* A colon is used in range-based for. */
14731 parser->colon_corrects_to_scope_p = false;
14732
14733 /* We're going to speculatively look for a declaration, falling back
14734 to an expression, if necessary. */
14735 cp_parser_parse_tentatively (parser);
14736 bool expect_semicolon_p = true;
14737 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_USING))
14738 {
14739 cp_parser_alias_declaration (parser);
14740 expect_semicolon_p = false;
14741 if (cxx_dialect < cxx23
14742 && !cp_parser_uncommitted_to_tentative_parse_p (parser))
14743 pedwarn (cp_lexer_peek_token (lexer: parser->lexer)->location,
14744 OPT_Wc__23_extensions,
14745 "alias-declaration in init-statement only "
14746 "available with %<-std=c++23%> or %<-std=gnu++23%>");
14747 }
14748 else
14749 /* Parse the declaration. */
14750 cp_parser_simple_declaration (parser,
14751 /*function_definition_allowed_p=*/false,
14752 decl);
14753 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
14754 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
14755 {
14756 /* It is a range-for, consume the ':'. */
14757 cp_lexer_consume_token (lexer: parser->lexer);
14758 is_range_for = true;
14759 if (cxx_dialect < cxx11)
14760 pedwarn (cp_lexer_peek_token (lexer: parser->lexer)->location,
14761 OPT_Wc__11_extensions,
14762 "range-based %<for%> loops only available with "
14763 "%<-std=c++11%> or %<-std=gnu++11%>");
14764 }
14765 else if (expect_semicolon_p)
14766 /* The ';' is not consumed yet because we told
14767 cp_parser_simple_declaration not to. */
14768 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
14769
14770 if (cp_parser_parse_definitely (parser))
14771 return is_range_for;
14772 /* If the tentative parse failed, then we shall need to look for an
14773 expression-statement. */
14774 }
14775 /* If we are here, it is an expression-statement. */
14776 cp_parser_expression_statement (parser, NULL_TREE);
14777 return false;
14778}
14779
14780/* Parse a jump-statement.
14781
14782 jump-statement:
14783 break ;
14784 continue ;
14785 return expression [opt] ;
14786 return braced-init-list ;
14787 coroutine-return-statement;
14788 goto identifier ;
14789
14790 GNU extension:
14791
14792 jump-statement:
14793 goto * expression ;
14794
14795 Returns the new BREAK_STMT, CONTINUE_STMT, RETURN_EXPR, or GOTO_EXPR. */
14796
14797static tree
14798cp_parser_jump_statement (cp_parser* parser)
14799{
14800 tree statement = error_mark_node;
14801 cp_token *token;
14802 enum rid keyword;
14803 unsigned char in_statement;
14804
14805 /* Peek at the next token. */
14806 token = cp_parser_require (parser, CPP_KEYWORD, RT_JUMP);
14807 if (!token)
14808 return error_mark_node;
14809
14810 /* See what kind of keyword it is. */
14811 keyword = token->keyword;
14812 switch (keyword)
14813 {
14814 case RID_BREAK:
14815 in_statement = parser->in_statement & ~IN_IF_STMT;
14816 switch (in_statement)
14817 {
14818 case 0:
14819 error_at (token->location, "break statement not within loop or switch");
14820 break;
14821 default:
14822 gcc_assert ((in_statement & IN_SWITCH_STMT)
14823 || in_statement == IN_ITERATION_STMT);
14824 statement = finish_break_stmt ();
14825 if (in_statement == IN_ITERATION_STMT)
14826 break_maybe_infinite_loop ();
14827 break;
14828 case IN_OMP_BLOCK:
14829 error_at (token->location, "invalid exit from OpenMP structured block");
14830 break;
14831 case IN_OMP_FOR:
14832 error_at (token->location, "break statement used with OpenMP for loop");
14833 break;
14834 }
14835 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
14836 break;
14837
14838 case RID_CONTINUE:
14839 switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
14840 {
14841 case 0:
14842 error_at (token->location, "continue statement not within a loop");
14843 break;
14844 /* Fall through. */
14845 case IN_ITERATION_STMT:
14846 case IN_OMP_FOR:
14847 statement = finish_continue_stmt ();
14848 break;
14849 case IN_OMP_BLOCK:
14850 error_at (token->location, "invalid exit from OpenMP structured block");
14851 break;
14852 default:
14853 gcc_unreachable ();
14854 }
14855 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
14856 break;
14857
14858 case RID_CO_RETURN:
14859 case RID_RETURN:
14860 {
14861 tree expr;
14862
14863 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
14864 {
14865 cp_lexer_set_source_position (lexer: parser->lexer);
14866 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
14867 expr = cp_parser_braced_list (parser);
14868 }
14869 else if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
14870 expr = cp_parser_expression (parser);
14871 else
14872 /* If the next token is a `;', then there is no
14873 expression. */
14874 expr = NULL_TREE;
14875 /* Build the return-statement, check co-return first, since type
14876 deduction is not valid there. */
14877 if (keyword == RID_CO_RETURN)
14878 statement = finish_co_return_stmt (token->location, expr);
14879 else if (FNDECL_USED_AUTO (current_function_decl) && in_discarded_stmt)
14880 /* Don't deduce from a discarded return statement. */;
14881 else
14882 statement = finish_return_stmt (expr);
14883 /* Look for the final `;'. */
14884 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
14885 }
14886 break;
14887
14888 case RID_GOTO:
14889 if (parser->in_function_body
14890 && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
14891 && cxx_dialect < cxx23)
14892 {
14893 error ("%<goto%> in %<constexpr%> function only available with "
14894 "%<-std=c++2b%> or %<-std=gnu++2b%>");
14895 cp_function_chain->invalid_constexpr = true;
14896 }
14897
14898 /* Create the goto-statement. */
14899 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MULT))
14900 {
14901 /* Issue a warning about this use of a GNU extension. */
14902 pedwarn (token->location, OPT_Wpedantic, "ISO C++ forbids computed gotos");
14903 /* Consume the '*' token. */
14904 cp_lexer_consume_token (lexer: parser->lexer);
14905 /* Parse the dependent expression. */
14906 finish_goto_stmt (cp_parser_expression (parser));
14907 }
14908 else
14909 finish_goto_stmt (cp_parser_identifier (parser));
14910 /* Look for the final `;'. */
14911 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
14912 break;
14913
14914 default:
14915 cp_parser_error (parser, gmsgid: "expected jump-statement");
14916 break;
14917 }
14918
14919 return statement;
14920}
14921
14922/* Parse a declaration-statement.
14923
14924 declaration-statement:
14925 block-declaration */
14926
14927static void
14928cp_parser_declaration_statement (cp_parser* parser)
14929{
14930 void *p;
14931
14932 /* Get the high-water mark for the DECLARATOR_OBSTACK. */
14933 p = obstack_alloc (&declarator_obstack, 0);
14934
14935 /* Parse the block-declaration. */
14936 cp_parser_block_declaration (parser, /*statement_p=*/true);
14937
14938 /* Free any declarators allocated. */
14939 obstack_free (&declarator_obstack, p);
14940}
14941
14942/* Some dependent statements (like `if (cond) statement'), are
14943 implicitly in their own scope. In other words, if the statement is
14944 a single statement (as opposed to a compound-statement), it is
14945 none-the-less treated as if it were enclosed in braces. Any
14946 declarations appearing in the dependent statement are out of scope
14947 after control passes that point. This function parses a statement,
14948 but ensures that is in its own scope, even if it is not a
14949 compound-statement.
14950
14951 If IF_P is not NULL, *IF_P is set to indicate whether the statement
14952 is a (possibly labeled) if statement which is not enclosed in
14953 braces and has an else clause. This is used to implement
14954 -Wparentheses.
14955
14956 CHAIN is a vector of if-else-if conditions. This is used to implement
14957 -Wduplicated-cond.
14958
14959 Returns the new statement. */
14960
14961static tree
14962cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p,
14963 const token_indent_info &guard_tinfo,
14964 vec<tree> *chain)
14965{
14966 tree statement;
14967 location_t body_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
14968 location_t body_loc_after_labels = UNKNOWN_LOCATION;
14969 token_indent_info body_tinfo
14970 = get_token_indent_info (token: cp_lexer_peek_token (lexer: parser->lexer));
14971
14972 if (if_p != NULL)
14973 *if_p = false;
14974
14975 /* Mark if () ; with a special NOP_EXPR. */
14976 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
14977 {
14978 cp_lexer_consume_token (lexer: parser->lexer);
14979 statement = add_stmt (build_empty_stmt (body_loc));
14980
14981 if (guard_tinfo.keyword == RID_IF
14982 && !cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_ELSE))
14983 warning_at (body_loc, OPT_Wempty_body,
14984 "suggest braces around empty body in an %<if%> statement");
14985 else if (guard_tinfo.keyword == RID_ELSE)
14986 warning_at (body_loc, OPT_Wempty_body,
14987 "suggest braces around empty body in an %<else%> statement");
14988 }
14989 /* if a compound is opened, we simply parse the statement directly. */
14990 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
14991 statement = cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_NORMAL, function_body: false);
14992 /* If the token is not a `{', then we must take special action. */
14993 else
14994 {
14995 /* Create a compound-statement. */
14996 statement = begin_compound_stmt (0);
14997 /* Parse the dependent-statement. */
14998 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p, chain,
14999 loc_after_labels: &body_loc_after_labels);
15000 /* Finish the dummy compound-statement. */
15001 finish_compound_stmt (statement);
15002 }
15003
15004 token_indent_info next_tinfo
15005 = get_token_indent_info (token: cp_lexer_peek_token (lexer: parser->lexer));
15006 warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);
15007
15008 if (body_loc_after_labels != UNKNOWN_LOCATION
15009 && next_tinfo.type != CPP_SEMICOLON)
15010 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
15011 guard_tinfo.location, guard_tinfo.keyword);
15012
15013 /* Return the statement. */
15014 return statement;
15015}
15016
15017/* For some dependent statements (like `while (cond) statement'), we
15018 have already created a scope. Therefore, even if the dependent
15019 statement is a compound-statement, we do not want to create another
15020 scope. */
15021
15022static void
15023cp_parser_already_scoped_statement (cp_parser* parser, bool *if_p,
15024 const token_indent_info &guard_tinfo)
15025{
15026 /* If the token is a `{', then we must take special action. */
15027 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_BRACE))
15028 {
15029 token_indent_info body_tinfo
15030 = get_token_indent_info (token: cp_lexer_peek_token (lexer: parser->lexer));
15031 location_t loc_after_labels = UNKNOWN_LOCATION;
15032
15033 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p, NULL,
15034 loc_after_labels: &loc_after_labels);
15035 token_indent_info next_tinfo
15036 = get_token_indent_info (token: cp_lexer_peek_token (lexer: parser->lexer));
15037 warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);
15038
15039 if (loc_after_labels != UNKNOWN_LOCATION
15040 && next_tinfo.type != CPP_SEMICOLON)
15041 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
15042 guard_tinfo.location,
15043 guard_tinfo.keyword);
15044 }
15045 else
15046 {
15047 /* Avoid calling cp_parser_compound_statement, so that we
15048 don't create a new scope. Do everything else by hand. */
15049 matching_braces braces;
15050 braces.require_open (parser);
15051 /* If the next keyword is `__label__' we have a label declaration. */
15052 while (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_LABEL))
15053 cp_parser_label_declaration (parser);
15054 /* Parse an (optional) statement-seq. */
15055 cp_parser_statement_seq_opt (parser, NULL_TREE);
15056 braces.require_close (parser);
15057 }
15058}
15059
15060/* Modules */
15061
15062/* Parse a module-name or module-partition.
15063
15064 module-name:
15065 module-name-qualifier [opt] identifier
15066
15067 module-partition:
15068 : module-name-qualifier [opt] identifier
15069
15070 module-name-qualifier:
15071 identifier .
15072 module-name-qualifier identifier .
15073
15074 Returns a pointer to the module object, or NULL on failure.
15075 For PARTITION_P, PARENT is the module this is a partition of. */
15076
15077static module_state *
15078cp_parser_module_name (cp_parser *parser, bool partition_p = false,
15079 module_state *parent = NULL)
15080{
15081 if (partition_p
15082 && cp_lexer_consume_token (lexer: parser->lexer)->type != CPP_COLON)
15083 return NULL;
15084
15085 for (;;)
15086 {
15087 if (cp_lexer_peek_token (lexer: parser->lexer)->type != CPP_NAME)
15088 {
15089 if (partition_p)
15090 cp_parser_error (parser, gmsgid: "expected module-partition");
15091 else
15092 cp_parser_error (parser, gmsgid: "expected module-name");
15093 return NULL;
15094 }
15095
15096 tree name = cp_lexer_consume_token (lexer: parser->lexer)->u.value;
15097 parent = get_module (name, parent, partition: partition_p);
15098 if (cp_lexer_peek_token (lexer: parser->lexer)->type != CPP_DOT)
15099 break;
15100
15101 cp_lexer_consume_token (lexer: parser->lexer);
15102 }
15103
15104 return parent;
15105}
15106
15107/* Parse a module-partition. Defers to cp_parser_module_name. */
15108
15109static module_state *
15110cp_parser_module_partition (cp_parser *parser, module_state *parent = NULL)
15111{
15112 return cp_parser_module_name (parser, /*partition_p=*/true, parent);
15113}
15114
15115/* Named module-declaration
15116 __module ; PRAGMA_EOL
15117 __module : private ; PRAGMA_EOL (unimplemented)
15118 [__export] __module module-name module-partition [opt]
15119 attr-spec-seq-opt ; PRAGMA_EOL
15120*/
15121
15122static module_parse
15123cp_parser_module_declaration (cp_parser *parser, module_parse mp_state,
15124 bool exporting)
15125{
15126 /* We're a pseudo pragma. */
15127 parser->lexer->in_pragma = true;
15128 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
15129
15130 if (flag_header_unit)
15131 {
15132 error_at (token->location,
15133 "module-declaration not permitted in header-unit");
15134 goto skip_eol;
15135 }
15136 else if (mp_state == MP_FIRST && !exporting
15137 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
15138 {
15139 /* Start global module fragment. */
15140 cp_lexer_consume_token (lexer: parser->lexer);
15141 module_kind = MK_NAMED;
15142 mp_state = MP_GLOBAL;
15143 cp_parser_require_pragma_eol (parser, pragma_tok: token);
15144 }
15145 else if (!exporting
15146 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON)
15147 && cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_PRIVATE)
15148 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_SEMICOLON))
15149 {
15150 cp_lexer_consume_token (lexer: parser->lexer);
15151 cp_lexer_consume_token (lexer: parser->lexer);
15152 cp_lexer_consume_token (lexer: parser->lexer);
15153 cp_parser_require_pragma_eol (parser, pragma_tok: token);
15154
15155 if ((mp_state == MP_PURVIEW || mp_state == MP_PURVIEW_IMPORTS)
15156 && module_has_cmi_p ())
15157 {
15158 mp_state = MP_PRIVATE_IMPORTS;
15159 sorry_at (token->location, "private module fragment");
15160 }
15161 else
15162 error_at (token->location,
15163 "private module fragment only permitted in purview"
15164 " of module interface or partition");
15165 }
15166 else if (!(mp_state == MP_FIRST || mp_state == MP_GLOBAL))
15167 {
15168 /* Neither the first declaration, nor in a GMF. */
15169 error_at (token->location, "module-declaration only permitted as first"
15170 " declaration, or ending a global module fragment");
15171 skip_eol:
15172 cp_parser_skip_to_pragma_eol (parser, pragma_tok: token);
15173 }
15174 else
15175 {
15176 module_state *mod = cp_parser_module_name (parser);
15177 if (mod && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_COLON)
15178 mod = cp_parser_module_partition (parser, parent: mod);
15179 tree attrs = cp_parser_attributes_opt (parser);
15180
15181 if (mod)
15182 mp_state = MP_PURVIEW_IMPORTS;
15183 if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
15184 goto skip_eol;
15185
15186 declare_module (mod, token->location, export_p: exporting, attr: attrs, parse_in);
15187 cp_parser_require_pragma_eol (parser, pragma_tok: token);
15188 }
15189
15190 return mp_state;
15191}
15192
15193/* Import-declaration
15194 __import module-name attr-spec-seq-opt ; PRAGMA_EOL
15195 __import module-partition attr-spec-seq-opt ; PRAGMA_EOL
15196 __import header-name attr-spec-seq-opt ; PRAGMA_EOL
15197*/
15198
15199static void
15200cp_parser_import_declaration (cp_parser *parser, module_parse mp_state,
15201 bool exporting)
15202{
15203 /* We're a pseudo pragma. */
15204 parser->lexer->in_pragma = true;
15205 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
15206
15207 if (mp_state == MP_PURVIEW || mp_state == MP_PRIVATE)
15208 {
15209 error_at (token->location, "post-module-declaration"
15210 " imports must be contiguous");
15211 note_lexer:
15212 inform (token->location, "perhaps insert a line break, or other"
15213 " disambiguation, to prevent this being considered a"
15214 " module control-line");
15215 skip_eol:
15216 cp_parser_skip_to_pragma_eol (parser, pragma_tok: token);
15217 }
15218 else if (current_scope () != global_namespace)
15219 {
15220 error_at (token->location, "import-declaration must be at global scope");
15221 goto note_lexer;
15222 }
15223 else
15224 {
15225 module_state *mod = NULL;
15226 cp_token *next = cp_lexer_peek_token (lexer: parser->lexer);
15227 if (next->type == CPP_HEADER_NAME)
15228 {
15229 cp_lexer_consume_token (lexer: parser->lexer);
15230 mod = get_module (name: next->u.value);
15231 }
15232 else if (next->type == CPP_COLON)
15233 {
15234 /* An import specifying a module-partition shall only appear after the
15235 module-declaration in a module unit: [module.import]/4. */
15236 if (named_module_p ()
15237 && (mp_state == MP_PURVIEW_IMPORTS
15238 || mp_state == MP_PRIVATE_IMPORTS))
15239 mod = cp_parser_module_partition (parser);
15240 else
15241 error_at (next->location, "import specifying a module-partition"
15242 " must appear after a named module-declaration");
15243 }
15244 else
15245 mod = cp_parser_module_name (parser);
15246 tree attrs = cp_parser_attributes_opt (parser);
15247
15248 if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
15249 goto skip_eol;
15250 cp_parser_require_pragma_eol (parser, pragma_tok: token);
15251
15252 if (parser->in_unbraced_linkage_specification_p)
15253 error_at (token->location, "import cannot appear directly in"
15254 " a linkage-specification");
15255
15256 if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS)
15257 {
15258 /* Module-purview imports must not be from source inclusion
15259 [cpp.import]/7 */
15260 if (attrs
15261 && private_lookup_attribute (attr_name: "__translated",
15262 attr_len: strlen (s: "__translated"), list: attrs))
15263 error_at (token->location, "post-module-declaration imports"
15264 " must not be include-translated");
15265 else if (!token->main_source_p)
15266 error_at (token->location, "post-module-declaration imports"
15267 " must not be from header inclusion");
15268 }
15269
15270 import_module (mod, token->location, export_p: exporting, attr: attrs, parse_in);
15271 }
15272}
15273
15274/* export-declaration.
15275
15276 export declaration
15277 export { declaration-seq-opt } */
15278
15279static void
15280cp_parser_module_export (cp_parser *parser)
15281{
15282 gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT));
15283 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
15284
15285 if (!module_interface_p ())
15286 error_at (token->location,
15287 "%qE may only occur after a module interface declaration",
15288 token->u.value);
15289
15290 bool braced = cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE);
15291
15292 unsigned mk = module_kind;
15293 if (module_exporting_p ())
15294 error_at (token->location,
15295 "%qE may only occur once in an export declaration",
15296 token->u.value);
15297 module_kind |= MK_EXPORTING;
15298
15299 if (braced)
15300 {
15301 cp_ensure_no_omp_declare_simd (parser);
15302 cp_ensure_no_oacc_routine (parser);
15303
15304 cp_lexer_consume_token (lexer: parser->lexer);
15305 cp_parser_declaration_seq_opt (parser);
15306 cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
15307 }
15308 else
15309 {
15310 /* Explicitly check if the next tokens might be a
15311 module-directive line, so we can give a clearer error message
15312 about why the directive will be rejected. */
15313 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID__MODULE)
15314 || cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID__IMPORT)
15315 || cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID__EXPORT))
15316 error_at (token->location, "%<export%> not part of following"
15317 " module-directive");
15318 cp_parser_declaration (parser, NULL_TREE);
15319 }
15320
15321 module_kind = mk;
15322}
15323
15324/* Declarations [gram.dcl.dcl] */
15325
15326/* Parse an optional declaration-sequence. TOP_LEVEL is true, if this
15327 is the top-level declaration sequence. That affects whether we
15328 deal with module-preamble.
15329
15330 declaration-seq:
15331 declaration
15332 declaration-seq declaration */
15333
15334static void
15335cp_parser_declaration_seq_opt (cp_parser* parser)
15336{
15337 while (true)
15338 {
15339 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
15340
15341 if (token->type == CPP_CLOSE_BRACE
15342 || token->type == CPP_EOF)
15343 break;
15344 else
15345 cp_parser_toplevel_declaration (parser);
15346 }
15347}
15348
15349/* Parse a declaration.
15350
15351 declaration:
15352 block-declaration
15353 function-definition
15354 template-declaration
15355 explicit-instantiation
15356 explicit-specialization
15357 linkage-specification
15358 namespace-definition
15359
15360 C++17:
15361 deduction-guide
15362
15363 modules:
15364 (all these are only allowed at the outermost level, check
15365 that semantically, for better diagnostics)
15366 module-declaration
15367 module-export-declaration
15368 module-import-declaration
15369 export-declaration
15370
15371 GNU extension:
15372
15373 declaration:
15374 __extension__ declaration */
15375
15376static void
15377cp_parser_declaration (cp_parser* parser, tree prefix_attrs)
15378{
15379 int saved_pedantic;
15380
15381 /* Check for the `__extension__' keyword. */
15382 if (cp_parser_extension_opt (parser, &saved_pedantic))
15383 {
15384 /* Parse the qualified declaration. */
15385 cp_parser_declaration (parser, prefix_attrs);
15386 /* Restore the PEDANTIC flag. */
15387 pedantic = saved_pedantic;
15388
15389 return;
15390 }
15391
15392 /* Try to figure out what kind of declaration is present. */
15393 cp_token *token1 = cp_lexer_peek_token (lexer: parser->lexer);
15394 cp_token *token2 = (token1->type == CPP_EOF
15395 ? token1 : cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2));
15396
15397 if (token1->type == CPP_SEMICOLON)
15398 {
15399 cp_lexer_consume_token (lexer: parser->lexer);
15400 /* A declaration consisting of a single semicolon is invalid
15401 * before C++11. Allow it unless we're being pedantic. */
15402 if (cxx_dialect < cxx11)
15403 pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
15404 return;
15405 }
15406 else if (cp_lexer_nth_token_is (lexer: parser->lexer,
15407 n: cp_parser_skip_std_attribute_spec_seq (parser,
15408 1),
15409 type: CPP_SEMICOLON))
15410 {
15411 location_t attrs_loc = token1->location;
15412 tree std_attrs = cp_parser_std_attribute_spec_seq (parser);
15413
15414 if (std_attrs && (flag_openmp || flag_openmp_simd))
15415 {
15416 gcc_assert (!parser->lexer->in_omp_attribute_pragma);
15417 std_attrs = cp_parser_handle_statement_omp_attributes (parser,
15418 attrs: std_attrs);
15419 if (parser->lexer->in_omp_attribute_pragma)
15420 {
15421 cp_lexer *lexer = parser->lexer;
15422 while (parser->lexer->in_omp_attribute_pragma)
15423 {
15424 gcc_assert (cp_lexer_next_token_is (parser->lexer,
15425 CPP_PRAGMA));
15426 cp_parser_pragma (parser, pragma_external, NULL);
15427 }
15428 cp_lexer_destroy (lexer);
15429 }
15430 }
15431
15432 if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs))
15433 warning_at (make_location (caret: attrs_loc, start: attrs_loc, lexer: parser->lexer),
15434 OPT_Wattributes, "attribute ignored");
15435 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
15436 cp_lexer_consume_token (lexer: parser->lexer);
15437 return;
15438 }
15439
15440 /* Get the high-water mark for the DECLARATOR_OBSTACK. */
15441 void *p = obstack_alloc (&declarator_obstack, 0);
15442
15443 tree attributes = NULL_TREE;
15444
15445 /* Conditionally, allow attributes to precede a linkage specification. */
15446 if (token1->keyword == RID_ATTRIBUTE)
15447 {
15448 cp_lexer_save_tokens (lexer: parser->lexer);
15449 attributes = cp_parser_attributes_opt (parser);
15450 cp_token *t1 = cp_lexer_peek_token (lexer: parser->lexer);
15451 cp_token *t2 = (t1->type == CPP_EOF
15452 ? t1 : cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2));
15453 if (t1->keyword == RID_EXTERN
15454 && cp_parser_is_pure_string_literal (token: t2))
15455 {
15456 cp_lexer_commit_tokens (lexer: parser->lexer);
15457 /* We might have already been here. */
15458 if (!c_dialect_objc ())
15459 {
15460 location_t where = get_finish (loc: t2->location);
15461 warning_at (token1->location, OPT_Wattributes, "attributes are"
15462 " not permitted in this position");
15463 where = linemap_position_for_loc_and_offset (set: line_table,
15464 loc: where, offset: 1);
15465 inform (where, "attributes may be inserted here");
15466 attributes = NULL_TREE;
15467 }
15468 token1 = t1;
15469 token2 = t2;
15470 }
15471 else
15472 {
15473 cp_lexer_rollback_tokens (lexer: parser->lexer);
15474 attributes = NULL_TREE;
15475 }
15476 }
15477 /* If we already had some attributes, and we've added more, then prepend.
15478 Otherwise attributes just contains any that we just read. */
15479 if (prefix_attrs)
15480 {
15481 if (attributes)
15482 TREE_CHAIN (prefix_attrs) = attributes;
15483 attributes = prefix_attrs;
15484 }
15485
15486 /* If the next token is `extern' and the following token is a string
15487 literal, then we have a linkage specification. */
15488 if (token1->keyword == RID_EXTERN
15489 && cp_parser_is_pure_string_literal (token: token2))
15490 cp_parser_linkage_specification (parser, attributes);
15491 /* If the next token is `template', then we have either a template
15492 declaration, an explicit instantiation, or an explicit
15493 specialization. */
15494 else if (token1->keyword == RID_TEMPLATE)
15495 {
15496 /* `template <>' indicates a template specialization. */
15497 if (token2->type == CPP_LESS
15498 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type == CPP_GREATER)
15499 cp_parser_explicit_specialization (parser);
15500 /* `template <' indicates a template declaration. */
15501 else if (token2->type == CPP_LESS)
15502 cp_parser_template_declaration (parser, /*member_p=*/false);
15503 /* Anything else must be an explicit instantiation. */
15504 else
15505 cp_parser_explicit_instantiation (parser);
15506 }
15507 /* If the next token is `export', it's new-style modules or
15508 old-style template. */
15509 else if (token1->keyword == RID_EXPORT)
15510 {
15511 if (!modules_p ())
15512 cp_parser_template_declaration (parser, /*member_p=*/false);
15513 else
15514 cp_parser_module_export (parser);
15515 }
15516 else if (cp_token_is_module_directive (token: token1))
15517 {
15518 bool exporting = token1->keyword == RID__EXPORT;
15519 cp_token *next = exporting ? token2 : token1;
15520 if (exporting)
15521 cp_lexer_consume_token (lexer: parser->lexer);
15522 // In module purview this will be ill-formed.
15523 auto state = (!named_module_p () ? MP_NOT_MODULE
15524 : module_purview_p () ? MP_PURVIEW
15525 : MP_GLOBAL);
15526 if (next->keyword == RID__MODULE)
15527 cp_parser_module_declaration (parser, mp_state: state, exporting);
15528 else
15529 cp_parser_import_declaration (parser, mp_state: state, exporting);
15530 }
15531 /* If the next token is `extern', 'static' or 'inline' and the one
15532 after that is `template', we have a GNU extended explicit
15533 instantiation directive. */
15534 else if (cp_parser_allow_gnu_extensions_p (parser)
15535 && token2->keyword == RID_TEMPLATE
15536 && (token1->keyword == RID_EXTERN
15537 || token1->keyword == RID_STATIC
15538 || token1->keyword == RID_INLINE))
15539 cp_parser_explicit_instantiation (parser);
15540 /* If the next token is `namespace', check for a named or unnamed
15541 namespace definition. */
15542 else if (token1->keyword == RID_NAMESPACE
15543 && (/* A named namespace definition. */
15544 (token2->type == CPP_NAME
15545 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type
15546 != CPP_EQ))
15547 || (token2->type == CPP_OPEN_SQUARE
15548 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type
15549 == CPP_OPEN_SQUARE)
15550 /* An unnamed namespace definition. */
15551 || token2->type == CPP_OPEN_BRACE
15552 || token2->keyword == RID_ATTRIBUTE))
15553 cp_parser_namespace_definition (parser);
15554 /* An inline (associated) namespace definition. */
15555 else if (token2->keyword == RID_NAMESPACE
15556 && token1->keyword == RID_INLINE)
15557 cp_parser_namespace_definition (parser);
15558 /* Objective-C++ declaration/definition. */
15559 else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1->keyword))
15560 cp_parser_objc_declaration (parser, attributes);
15561 else if (c_dialect_objc ()
15562 && token1->keyword == RID_ATTRIBUTE
15563 && cp_parser_objc_valid_prefix_attributes (parser, &attributes))
15564 cp_parser_objc_declaration (parser, attributes);
15565 /* At this point we may have a template declared by a concept
15566 introduction. */
15567 else if (flag_concepts
15568 && cp_parser_template_declaration_after_export (parser,
15569 /*member_p=*/false))
15570 /* We did. */;
15571 else
15572 /* Try to parse a block-declaration, or a function-definition. */
15573 cp_parser_block_declaration (parser, /*statement_p=*/false);
15574
15575 /* Free any declarators allocated. */
15576 obstack_free (&declarator_obstack, p);
15577}
15578
15579/* Parse a namespace-scope declaration. */
15580
15581static void
15582cp_parser_toplevel_declaration (cp_parser* parser)
15583{
15584 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
15585
15586 if (token->type == CPP_PRAGMA)
15587 /* A top-level declaration can consist solely of a #pragma. A
15588 nested declaration cannot, so this is done here and not in
15589 cp_parser_declaration. (A #pragma at block scope is
15590 handled in cp_parser_statement.) */
15591 cp_parser_pragma (parser, pragma_external, NULL);
15592 else
15593 /* Parse the declaration itself. */
15594 cp_parser_declaration (parser, NULL_TREE);
15595}
15596
15597/* Parse a block-declaration.
15598
15599 block-declaration:
15600 simple-declaration
15601 asm-definition
15602 namespace-alias-definition
15603 using-declaration
15604 using-directive
15605
15606 GNU Extension:
15607
15608 block-declaration:
15609 __extension__ block-declaration
15610
15611 C++0x Extension:
15612
15613 block-declaration:
15614 static_assert-declaration
15615
15616 If STATEMENT_P is TRUE, then this block-declaration is occurring as
15617 part of a declaration-statement. */
15618
15619static void
15620cp_parser_block_declaration (cp_parser *parser,
15621 bool statement_p)
15622{
15623 int saved_pedantic;
15624
15625 /* Check for the `__extension__' keyword. */
15626 if (cp_parser_extension_opt (parser, &saved_pedantic))
15627 {
15628 /* Parse the qualified declaration. */
15629 cp_parser_block_declaration (parser, statement_p);
15630 /* Restore the PEDANTIC flag. */
15631 pedantic = saved_pedantic;
15632
15633 return;
15634 }
15635
15636 /* Peek at the next token to figure out which kind of declaration is
15637 present. */
15638 cp_token *token1 = cp_lexer_peek_token (lexer: parser->lexer);
15639
15640 /* If the next keyword is `asm', we have an asm-definition. */
15641 if (token1->keyword == RID_ASM)
15642 {
15643 if (statement_p)
15644 cp_parser_commit_to_tentative_parse (parser);
15645 cp_parser_asm_definition (parser);
15646 }
15647 /* If the next keyword is `namespace', we have a
15648 namespace-alias-definition. */
15649 else if (token1->keyword == RID_NAMESPACE)
15650 cp_parser_namespace_alias_definition (parser);
15651 /* If the next keyword is `using', we have a
15652 using-declaration, a using-directive, or an alias-declaration. */
15653 else if (token1->keyword == RID_USING)
15654 {
15655 cp_token *token2;
15656
15657 if (statement_p)
15658 cp_parser_commit_to_tentative_parse (parser);
15659 /* If the token after `using' is `namespace', then we have a
15660 using-directive. */
15661 token2 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
15662 if (token2->keyword == RID_NAMESPACE)
15663 cp_parser_using_directive (parser);
15664 else if (token2->keyword == RID_ENUM)
15665 cp_parser_using_enum (parser);
15666 /* If the second token after 'using' is '=', then we have an
15667 alias-declaration. */
15668 else if (cxx_dialect >= cxx11
15669 && token2->type == CPP_NAME
15670 && ((cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type == CPP_EQ)
15671 || (cp_nth_tokens_can_be_attribute_p (parser, 3))))
15672 cp_parser_alias_declaration (parser);
15673 /* Otherwise, it's a using-declaration. */
15674 else
15675 cp_parser_using_declaration (parser,
15676 /*access_declaration_p=*/false);
15677 }
15678 /* If the next keyword is `__label__' we have a misplaced label
15679 declaration. */
15680 else if (token1->keyword == RID_LABEL)
15681 {
15682 cp_lexer_consume_token (lexer: parser->lexer);
15683 error_at (token1->location, "%<__label__%> not at the beginning of a block");
15684 cp_parser_skip_to_end_of_statement (parser);
15685 /* If the next token is now a `;', consume it. */
15686 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
15687 cp_lexer_consume_token (lexer: parser->lexer);
15688 }
15689 /* If the next token is `static_assert' we have a static assertion. */
15690 else if (token1->keyword == RID_STATIC_ASSERT)
15691 cp_parser_static_assert (parser, /*member_p=*/false);
15692 else
15693 {
15694 size_t attr_idx = cp_parser_skip_std_attribute_spec_seq (parser, 1);
15695 cp_token *after_attr = NULL;
15696 if (attr_idx != 1)
15697 after_attr = cp_lexer_peek_nth_token (lexer: parser->lexer, n: attr_idx);
15698 /* If the next tokens after attributes is `using namespace', then we have
15699 a using-directive. */
15700 if (after_attr
15701 && after_attr->keyword == RID_USING
15702 && cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: attr_idx + 1,
15703 keyword: RID_NAMESPACE))
15704 {
15705 if (statement_p)
15706 cp_parser_commit_to_tentative_parse (parser);
15707 cp_parser_using_directive (parser);
15708 }
15709 /* If the next token after attributes is `asm', then we have
15710 an asm-definition. */
15711 else if (after_attr && after_attr->keyword == RID_ASM)
15712 {
15713 if (statement_p)
15714 cp_parser_commit_to_tentative_parse (parser);
15715 cp_parser_asm_definition (parser);
15716 }
15717 /* Anything else must be a simple-declaration. */
15718 else
15719 cp_parser_simple_declaration (parser, !statement_p,
15720 /*maybe_range_for_decl*/NULL);
15721 }
15722}
15723
15724/* Parse a simple-declaration.
15725
15726 simple-declaration:
15727 decl-specifier-seq [opt] init-declarator-list [opt] ;
15728 decl-specifier-seq ref-qualifier [opt] [ identifier-list ]
15729 brace-or-equal-initializer ;
15730
15731 init-declarator-list:
15732 init-declarator
15733 init-declarator-list , init-declarator
15734
15735 If FUNCTION_DEFINITION_ALLOWED_P is TRUE, then we also recognize a
15736 function-definition as a simple-declaration.
15737
15738 If MAYBE_RANGE_FOR_DECL is not NULL, the pointed tree will be set to the
15739 parsed declaration if it is an uninitialized single declarator not followed
15740 by a `;', or to error_mark_node otherwise. Either way, the trailing `;',
15741 if present, will not be consumed. */
15742
15743static void
15744cp_parser_simple_declaration (cp_parser* parser,
15745 bool function_definition_allowed_p,
15746 tree *maybe_range_for_decl)
15747{
15748 cp_decl_specifier_seq decl_specifiers;
15749 int declares_class_or_enum;
15750 bool saw_declarator;
15751 location_t comma_loc = UNKNOWN_LOCATION;
15752 location_t init_loc = UNKNOWN_LOCATION;
15753
15754 if (maybe_range_for_decl)
15755 *maybe_range_for_decl = NULL_TREE;
15756
15757 /* Defer access checks until we know what is being declared; the
15758 checks for names appearing in the decl-specifier-seq should be
15759 done as if we were in the scope of the thing being declared. */
15760 push_deferring_access_checks (dk_deferred);
15761
15762 /* Parse the decl-specifier-seq. We have to keep track of whether
15763 or not the decl-specifier-seq declares a named class or
15764 enumeration type, since that is the only case in which the
15765 init-declarator-list is allowed to be empty.
15766
15767 [dcl.dcl]
15768
15769 In a simple-declaration, the optional init-declarator-list can be
15770 omitted only when declaring a class or enumeration, that is when
15771 the decl-specifier-seq contains either a class-specifier, an
15772 elaborated-type-specifier, or an enum-specifier. */
15773 cp_parser_decl_specifier_seq (parser,
15774 CP_PARSER_FLAGS_OPTIONAL,
15775 &decl_specifiers,
15776 &declares_class_or_enum);
15777 /* We no longer need to defer access checks. */
15778 stop_deferring_access_checks ();
15779
15780 cp_omp_declare_simd_data odsd;
15781 if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
15782 cp_parser_handle_directive_omp_attributes (parser,
15783 pattrs: &decl_specifiers.attributes,
15784 data: &odsd, start: true);
15785
15786 /* In a block scope, a valid declaration must always have a
15787 decl-specifier-seq. By not trying to parse declarators, we can
15788 resolve the declaration/expression ambiguity more quickly. */
15789 if (!function_definition_allowed_p
15790 && !decl_specifiers.any_specifiers_p)
15791 {
15792 cp_parser_error (parser, gmsgid: "expected declaration");
15793 goto done;
15794 }
15795
15796 /* If the next two tokens are both identifiers, the code is
15797 erroneous. The usual cause of this situation is code like:
15798
15799 T t;
15800
15801 where "T" should name a type -- but does not. */
15802 if (!decl_specifiers.any_type_specifiers_p
15803 && cp_parser_parse_and_diagnose_invalid_type_name (parser))
15804 {
15805 /* If parsing tentatively, we should commit; we really are
15806 looking at a declaration. */
15807 cp_parser_commit_to_tentative_parse (parser);
15808 /* Give up. */
15809 goto done;
15810 }
15811
15812 cp_parser_maybe_commit_to_declaration (parser, decl_specs: &decl_specifiers);
15813
15814 /* Look for C++17 decomposition declaration. */
15815 for (size_t n = 1; ; n++)
15816 if (cp_lexer_nth_token_is (lexer: parser->lexer, n, type: CPP_AND)
15817 || cp_lexer_nth_token_is (lexer: parser->lexer, n, type: CPP_AND_AND))
15818 continue;
15819 else if (cp_lexer_nth_token_is (lexer: parser->lexer, n, type: CPP_OPEN_SQUARE)
15820 && !cp_lexer_nth_token_is (lexer: parser->lexer, n: n + 1, type: CPP_OPEN_SQUARE)
15821 && decl_specifiers.any_specifiers_p)
15822 {
15823 tree decl
15824 = cp_parser_decomposition_declaration (parser, &decl_specifiers,
15825 maybe_range_for_decl,
15826 &init_loc);
15827
15828 /* The next token should be either a `,' or a `;'. */
15829 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
15830 /* If it's a `;', we are done. */
15831 if (token->type == CPP_SEMICOLON)
15832 goto finish;
15833 else if (maybe_range_for_decl)
15834 {
15835 if (*maybe_range_for_decl == NULL_TREE)
15836 *maybe_range_for_decl = error_mark_node;
15837 goto finish;
15838 }
15839 /* Anything else is an error. */
15840 else
15841 {
15842 /* If we have already issued an error message we don't need
15843 to issue another one. */
15844 if ((decl != error_mark_node
15845 && DECL_INITIAL (decl) != error_mark_node)
15846 || cp_parser_uncommitted_to_tentative_parse_p (parser))
15847 cp_parser_error (parser, gmsgid: "expected %<;%>");
15848 /* Skip tokens until we reach the end of the statement. */
15849 cp_parser_skip_to_end_of_statement (parser);
15850 /* If the next token is now a `;', consume it. */
15851 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
15852 cp_lexer_consume_token (lexer: parser->lexer);
15853 goto done;
15854 }
15855 }
15856 else
15857 break;
15858
15859 tree last_type;
15860 bool auto_specifier_p;
15861 /* NULL_TREE if both variable and function declaration are allowed,
15862 error_mark_node if function declaration are not allowed and
15863 a FUNCTION_DECL that should be diagnosed if it is followed by
15864 variable declarations. */
15865 tree auto_function_declaration;
15866
15867 last_type = NULL_TREE;
15868 auto_specifier_p
15869 = decl_specifiers.type && type_uses_auto (decl_specifiers.type);
15870 auto_function_declaration = NULL_TREE;
15871
15872 /* Keep going until we hit the `;' at the end of the simple
15873 declaration. */
15874 saw_declarator = false;
15875 while (cp_lexer_next_token_is_not (lexer: parser->lexer,
15876 type: CPP_SEMICOLON))
15877 {
15878 cp_token *token;
15879 bool function_definition_p;
15880 tree decl;
15881 tree auto_result = NULL_TREE;
15882
15883 if (saw_declarator)
15884 {
15885 /* If we are processing next declarator, comma is expected */
15886 token = cp_lexer_peek_token (lexer: parser->lexer);
15887 gcc_assert (token->type == CPP_COMMA);
15888 cp_lexer_consume_token (lexer: parser->lexer);
15889 if (maybe_range_for_decl)
15890 {
15891 *maybe_range_for_decl = error_mark_node;
15892 if (comma_loc == UNKNOWN_LOCATION)
15893 comma_loc = token->location;
15894 }
15895 }
15896 else
15897 saw_declarator = true;
15898
15899 /* Parse the init-declarator. */
15900 decl = cp_parser_init_declarator (parser,
15901 CP_PARSER_FLAGS_NONE,
15902 &decl_specifiers,
15903 /*checks=*/NULL,
15904 function_definition_allowed_p,
15905 /*member_p=*/false,
15906 declares_class_or_enum,
15907 &function_definition_p,
15908 maybe_range_for_decl,
15909 &init_loc,
15910 &auto_result);
15911 const bool fndecl_p = TREE_CODE (decl) == FUNCTION_DECL;
15912 /* If an error occurred while parsing tentatively, exit quickly.
15913 (That usually happens when in the body of a function; each
15914 statement is treated as a declaration-statement until proven
15915 otherwise.) */
15916 if (cp_parser_error_occurred (parser))
15917 goto done;
15918
15919 if (auto_specifier_p && cxx_dialect >= cxx14)
15920 {
15921 /* If the init-declarator-list contains more than one
15922 init-declarator, they shall all form declarations of
15923 variables. */
15924 if (auto_function_declaration == NULL_TREE)
15925 auto_function_declaration = fndecl_p ? decl : error_mark_node;
15926 else if (fndecl_p || auto_function_declaration != error_mark_node)
15927 {
15928 error_at (decl_specifiers.locations[ds_type_spec],
15929 "non-variable %qD in declaration with more than one "
15930 "declarator with placeholder type",
15931 fndecl_p ? decl : auto_function_declaration);
15932 auto_function_declaration = error_mark_node;
15933 }
15934 }
15935
15936 if (auto_result
15937 && (!processing_template_decl || !type_uses_auto (auto_result)))
15938 {
15939 if (last_type
15940 && last_type != error_mark_node
15941 && !same_type_p (auto_result, last_type))
15942 {
15943 /* If the list of declarators contains more than one declarator,
15944 the type of each declared variable is determined as described
15945 above. If the type deduced for the template parameter U is not
15946 the same in each deduction, the program is ill-formed. */
15947 error_at (decl_specifiers.locations[ds_type_spec],
15948 "inconsistent deduction for %qT: %qT and then %qT",
15949 decl_specifiers.type, last_type, auto_result);
15950 last_type = error_mark_node;
15951 }
15952 else
15953 last_type = auto_result;
15954 }
15955
15956 /* Handle function definitions specially. */
15957 if (function_definition_p)
15958 {
15959 /* If the next token is a `,', then we are probably
15960 processing something like:
15961
15962 void f() {}, *p;
15963
15964 which is erroneous. */
15965 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
15966 {
15967 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
15968 error_at (token->location,
15969 "mixing"
15970 " declarations and function-definitions is forbidden");
15971 }
15972 /* Otherwise, we're done with the list of declarators. */
15973 else
15974 {
15975 pop_deferring_access_checks ();
15976 cp_finalize_omp_declare_simd (parser, data: &odsd);
15977 return;
15978 }
15979 }
15980 if (maybe_range_for_decl && *maybe_range_for_decl == NULL_TREE)
15981 *maybe_range_for_decl = decl;
15982 /* The next token should be either a `,' or a `;'. */
15983 token = cp_lexer_peek_token (lexer: parser->lexer);
15984 /* If it's a `,', there are more declarators to come. */
15985 if (token->type == CPP_COMMA)
15986 /* will be consumed next time around */;
15987 /* If it's a `;', we are done. */
15988 else if (token->type == CPP_SEMICOLON)
15989 break;
15990 else if (maybe_range_for_decl)
15991 {
15992 if ((declares_class_or_enum & 2) && token->type == CPP_COLON)
15993 permerror (decl_specifiers.locations[ds_type_spec],
15994 "types may not be defined in a for-range-declaration");
15995 break;
15996 }
15997 /* Anything else is an error. */
15998 else
15999 {
16000 /* If we have already issued an error message we don't need
16001 to issue another one. */
16002 if ((decl != error_mark_node
16003 /* grokfndecl sets DECL_INITIAL to error_mark_node for
16004 functions. */
16005 && (fndecl_p || DECL_INITIAL (decl) != error_mark_node))
16006 || cp_parser_uncommitted_to_tentative_parse_p (parser))
16007 cp_parser_error (parser, gmsgid: "expected %<,%> or %<;%>");
16008 /* Skip tokens until we reach the end of the statement. */
16009 cp_parser_skip_to_end_of_statement (parser);
16010 /* If the next token is now a `;', consume it. */
16011 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
16012 cp_lexer_consume_token (lexer: parser->lexer);
16013 goto done;
16014 }
16015 /* After the first time around, a function-definition is not
16016 allowed -- even if it was OK at first. For example:
16017
16018 int i, f() {}
16019
16020 is not valid. */
16021 function_definition_allowed_p = false;
16022 }
16023
16024 /* Issue an error message if no declarators are present, and the
16025 decl-specifier-seq does not itself declare a class or
16026 enumeration: [dcl.dcl]/3. */
16027 if (!saw_declarator)
16028 {
16029 if (cp_parser_declares_only_class_p (parser))
16030 {
16031 if (!declares_class_or_enum
16032 && decl_specifiers.type
16033 && OVERLOAD_TYPE_P (decl_specifiers.type))
16034 /* Ensure an error is issued anyway when finish_decltype_type,
16035 called via cp_parser_decl_specifier_seq, returns a class or
16036 an enumeration (c++/51786). */
16037 decl_specifiers.type = NULL_TREE;
16038 shadow_tag (&decl_specifiers);
16039 }
16040 /* Perform any deferred access checks. */
16041 perform_deferred_access_checks (tf_warning_or_error);
16042 }
16043
16044 /* Consume the `;'. */
16045 finish:
16046 if (!maybe_range_for_decl)
16047 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
16048 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
16049 {
16050 if (init_loc != UNKNOWN_LOCATION)
16051 error_at (init_loc, "initializer in range-based %<for%> loop");
16052 if (comma_loc != UNKNOWN_LOCATION)
16053 error_at (comma_loc,
16054 "multiple declarations in range-based %<for%> loop");
16055 }
16056
16057 done:
16058 pop_deferring_access_checks ();
16059 cp_finalize_omp_declare_simd (parser, data: &odsd);
16060}
16061
16062/* Helper of cp_parser_simple_declaration, parse a decomposition declaration.
16063 decl-specifier-seq ref-qualifier [opt] [ identifier-list ]
16064 initializer ; */
16065
16066static tree
16067cp_parser_decomposition_declaration (cp_parser *parser,
16068 cp_decl_specifier_seq *decl_specifiers,
16069 tree *maybe_range_for_decl,
16070 location_t *init_loc)
16071{
16072 cp_ref_qualifier ref_qual = cp_parser_ref_qualifier_opt (parser);
16073 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
16074 cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
16075
16076 /* Parse the identifier-list. */
16077 auto_vec<cp_expr, 10> v;
16078 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_SQUARE))
16079 while (true)
16080 {
16081 cp_expr e = cp_parser_identifier (parser);
16082 if (e.get_value () == error_mark_node)
16083 break;
16084 v.safe_push (obj: e);
16085 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
16086 break;
16087 cp_lexer_consume_token (lexer: parser->lexer);
16088 }
16089
16090 location_t end_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
16091 if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
16092 {
16093 end_loc = UNKNOWN_LOCATION;
16094 cp_parser_skip_to_closing_parenthesis_1 (parser, recovering: true, or_ttype: CPP_CLOSE_SQUARE,
16095 consume_paren: false);
16096 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_SQUARE))
16097 cp_lexer_consume_token (lexer: parser->lexer);
16098 else
16099 {
16100 cp_parser_skip_to_end_of_statement (parser);
16101 return error_mark_node;
16102 }
16103 }
16104
16105 if (cxx_dialect < cxx17)
16106 pedwarn (loc, OPT_Wc__17_extensions,
16107 "structured bindings only available with "
16108 "%<-std=c++17%> or %<-std=gnu++17%>");
16109
16110 tree pushed_scope;
16111 cp_declarator *declarator = make_declarator (kind: cdk_decomp);
16112 loc = end_loc == UNKNOWN_LOCATION ? loc : make_location (caret: loc, start: loc, finish: end_loc);
16113 declarator->id_loc = loc;
16114 if (ref_qual != REF_QUAL_NONE)
16115 declarator = make_reference_declarator (cv_qualifiers: TYPE_UNQUALIFIED, target: declarator,
16116 rvalue_ref: ref_qual == REF_QUAL_RVALUE,
16117 NULL_TREE);
16118 tree decl = start_decl (declarator, decl_specifiers, SD_INITIALIZED,
16119 NULL_TREE, decl_specifiers->attributes,
16120 &pushed_scope);
16121 tree orig_decl = decl;
16122
16123 unsigned int i;
16124 cp_expr e;
16125 cp_decl_specifier_seq decl_specs;
16126 clear_decl_specs (decl_specs: &decl_specs);
16127 decl_specs.type = make_auto ();
16128 if (decl_specifiers->storage_class == sc_static)
16129 decl_specs.storage_class = sc_static;
16130 tree prev = decl;
16131 FOR_EACH_VEC_ELT (v, i, e)
16132 {
16133 if (i == 0)
16134 declarator = make_id_declarator (NULL_TREE, unqualified_name: e.get_value (),
16135 sfk: sfk_none, id_location: e.get_location ());
16136 else
16137 {
16138 declarator->u.id.unqualified_name = e.get_value ();
16139 declarator->id_loc = e.get_location ();
16140 }
16141 tree elt_pushed_scope;
16142 tree decl2 = start_decl (declarator, &decl_specs, SD_DECOMPOSITION,
16143 NULL_TREE, NULL_TREE, &elt_pushed_scope);
16144 if (decl2 == error_mark_node)
16145 decl = error_mark_node;
16146 else if (decl != error_mark_node && DECL_CHAIN (decl2) != prev)
16147 {
16148 /* Ensure we've diagnosed redeclaration if we aren't creating
16149 a new VAR_DECL. */
16150 gcc_assert (errorcount);
16151 decl = error_mark_node;
16152 }
16153 else
16154 prev = decl2;
16155 if (elt_pushed_scope)
16156 pop_scope (elt_pushed_scope);
16157 }
16158
16159 if (v.is_empty ())
16160 {
16161 error_at (loc, "empty structured binding declaration");
16162 decl = error_mark_node;
16163 }
16164
16165 if (maybe_range_for_decl == NULL
16166 || cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COLON))
16167 {
16168 bool non_constant_p = false, is_direct_init = false;
16169 *init_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
16170 tree initializer = cp_parser_initializer (parser, &is_direct_init,
16171 &non_constant_p);
16172 if (initializer == NULL_TREE
16173 || (TREE_CODE (initializer) == TREE_LIST
16174 && TREE_CHAIN (initializer))
16175 || (is_direct_init
16176 && BRACE_ENCLOSED_INITIALIZER_P (initializer)
16177 && CONSTRUCTOR_NELTS (initializer) != 1))
16178 {
16179 error_at (loc, "invalid initializer for structured binding "
16180 "declaration");
16181 initializer = error_mark_node;
16182 }
16183
16184 if (decl != error_mark_node)
16185 {
16186 cp_decomp decomp = { .decl: prev, .count: v.length () };
16187 cp_finish_decl (decl, initializer, non_constant_p, NULL_TREE,
16188 (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT),
16189 &decomp);
16190 cp_finish_decomp (decl, &decomp);
16191 }
16192 }
16193 else if (decl != error_mark_node)
16194 {
16195 *maybe_range_for_decl = prev;
16196 cp_decomp decomp = { .decl: prev, .count: v.length () };
16197 /* Ensure DECL_VALUE_EXPR is created for all the decls but
16198 the underlying DECL. */
16199 cp_finish_decomp (decl, &decomp);
16200 }
16201
16202 if (pushed_scope)
16203 pop_scope (pushed_scope);
16204
16205 if (decl == error_mark_node && DECL_P (orig_decl))
16206 {
16207 if (DECL_NAMESPACE_SCOPE_P (orig_decl))
16208 SET_DECL_ASSEMBLER_NAME (orig_decl, get_identifier ("<decomp>"));
16209 }
16210
16211 return decl;
16212}
16213
16214/* Names of storage classes. */
16215
16216static const char *const
16217cp_storage_class_name[] = {
16218 "", "auto", "register", "static", "extern", "mutable"
16219};
16220
16221/* Parse a decl-specifier-seq.
16222
16223 decl-specifier-seq:
16224 decl-specifier-seq [opt] decl-specifier
16225 decl-specifier attribute-specifier-seq [opt] (C++11)
16226
16227 decl-specifier:
16228 storage-class-specifier
16229 type-specifier
16230 function-specifier
16231 friend
16232 typedef
16233
16234 GNU Extension:
16235
16236 decl-specifier:
16237 attributes
16238
16239 Concepts Extension:
16240
16241 decl-specifier:
16242 concept
16243
16244 Set *DECL_SPECS to a representation of the decl-specifier-seq.
16245
16246 The parser flags FLAGS is used to control type-specifier parsing.
16247
16248 *DECLARES_CLASS_OR_ENUM is set to the bitwise or of the following
16249 flags:
16250
16251 1: one of the decl-specifiers is an elaborated-type-specifier
16252 (i.e., a type declaration)
16253 2: one of the decl-specifiers is an enum-specifier or a
16254 class-specifier (i.e., a type definition)
16255
16256 */
16257
16258static void
16259cp_parser_decl_specifier_seq (cp_parser* parser,
16260 cp_parser_flags flags,
16261 cp_decl_specifier_seq *decl_specs,
16262 int* declares_class_or_enum)
16263{
16264 bool constructor_possible_p = !parser->in_declarator_p;
16265 bool found_decl_spec = false;
16266 cp_token *start_token = NULL;
16267 cp_decl_spec ds;
16268
16269 /* Clear DECL_SPECS. */
16270 clear_decl_specs (decl_specs);
16271
16272 /* Assume no class or enumeration type is declared. */
16273 *declares_class_or_enum = 0;
16274
16275 /* Keep a token that additionally will be used for diagnostics. */
16276 cp_token *first_specifier = NULL;
16277 /* Keep reading specifiers until there are no more to read. */
16278 while (true)
16279 {
16280 bool constructor_p;
16281 cp_token *token;
16282 ds = ds_last;
16283
16284 /* Peek at the next token. */
16285 token = cp_lexer_peek_token (lexer: parser->lexer);
16286
16287 /* Save the first token of the decl spec list for error
16288 reporting. */
16289 if (!start_token)
16290 start_token = token;
16291 /* Handle attributes. */
16292 if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) == 0
16293 && cp_next_tokens_can_be_attribute_p (parser))
16294 {
16295 /* Parse the attributes. */
16296 tree attrs = cp_parser_attributes_opt (parser);
16297
16298 /* In a sequence of declaration specifiers, c++11 attributes
16299 appertain to the type that precede them. In that case
16300 [dcl.spec]/1 says:
16301
16302 The attribute-specifier-seq affects the type only for
16303 the declaration it appears in, not other declarations
16304 involving the same type.
16305
16306 But for now let's force the user to position the
16307 attribute either at the beginning of the declaration or
16308 after the declarator-id, which would clearly mean that it
16309 applies to the declarator. */
16310 if (cxx11_attribute_p (attrs))
16311 {
16312 if (!found_decl_spec)
16313 /* The c++11 attribute is at the beginning of the
16314 declaration. It appertains to the entity being
16315 declared. */;
16316 else
16317 {
16318 if (find_contract (attrs))
16319 {
16320 diagnose_misapplied_contracts (attrs);
16321 attrs = NULL_TREE;
16322 }
16323 else if (decl_specs->type && CLASS_TYPE_P (decl_specs->type))
16324 {
16325 /* This is an attribute following a
16326 class-specifier. */
16327 if (decl_specs->type_definition_p)
16328 warn_misplaced_attr_for_class_type (location: token->location,
16329 class_type: decl_specs->type);
16330 attrs = NULL_TREE;
16331 }
16332 else
16333 {
16334 decl_specs->std_attributes
16335 = attr_chainon (attrs: decl_specs->std_attributes, attr: attrs);
16336 if (decl_specs->locations[ds_std_attribute] == 0)
16337 decl_specs->locations[ds_std_attribute] = token->location;
16338 }
16339 continue;
16340 }
16341 }
16342
16343 decl_specs->attributes
16344 = attr_chainon (attrs: decl_specs->attributes, attr: attrs);
16345 if (decl_specs->locations[ds_attribute] == 0)
16346 decl_specs->locations[ds_attribute] = token->location;
16347 continue;
16348 }
16349 /* We know by this point that the token is not part of an attribute. */
16350 if (!first_specifier)
16351 first_specifier = token;
16352 /* Special case for "this" specifier, indicating a parm is an xobj parm.
16353 The "this" specifier must be the first specifier in the declaration,
16354 after any attributes. */
16355 if (token->keyword == RID_THIS && (flags & CP_PARSER_FLAGS_PARAMETER))
16356 {
16357 cp_lexer_consume_token (lexer: parser->lexer);
16358 if (token != first_specifier)
16359 {
16360 /* Don't emit diagnostics if we have already seen "this",
16361 leave it for set_and_check_decl_spec_loc. */
16362 if (decl_specs->locations[ds_this] == 0)
16363 {
16364 auto_diagnostic_group d;
16365 gcc_rich_location richloc (token->location);
16366 /* Works, need to add tests for it though. */
16367 richloc.add_fixit_remove ();
16368 richloc.add_fixit_insert_before (where: first_specifier->location,
16369 new_content: "this ");
16370 error_at (&richloc,
16371 "%<this%> must be the first specifier "
16372 "in a parameter declaration");
16373 }
16374 }
16375 set_and_check_decl_spec_loc (decl_specs, ds: ds_this, token);
16376 continue;
16377 }
16378
16379 /* Assume we will find a decl-specifier keyword. */
16380 found_decl_spec = true;
16381 /* If the next token is an appropriate keyword, we can simply
16382 add it to the list. */
16383 switch (token->keyword)
16384 {
16385 /* decl-specifier:
16386 friend
16387 constexpr
16388 constinit */
16389 case RID_FRIEND:
16390 if (!at_class_scope_p ())
16391 {
16392 gcc_rich_location richloc (token->location);
16393 richloc.add_fixit_remove ();
16394 error_at (&richloc, "%<friend%> used outside of class");
16395 cp_lexer_purge_token (lexer: parser->lexer);
16396 }
16397 else
16398 {
16399 ds = ds_friend;
16400 /* Consume the token. */
16401 cp_lexer_consume_token (lexer: parser->lexer);
16402 }
16403 break;
16404
16405 case RID_CONSTEXPR:
16406 ds = ds_constexpr;
16407 cp_lexer_consume_token (lexer: parser->lexer);
16408 break;
16409
16410 case RID_CONSTINIT:
16411 ds = ds_constinit;
16412 cp_lexer_consume_token (lexer: parser->lexer);
16413 break;
16414
16415 case RID_CONSTEVAL:
16416 ds = ds_consteval;
16417 cp_lexer_consume_token (lexer: parser->lexer);
16418 break;
16419
16420 case RID_CONCEPT:
16421 ds = ds_concept;
16422 cp_lexer_consume_token (lexer: parser->lexer);
16423
16424 if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
16425 break;
16426
16427 /* Warn for concept as a decl-specifier. We'll rewrite these as
16428 concept declarations later. */
16429 if (!flag_concepts_ts)
16430 {
16431 cp_token *next = cp_lexer_peek_token (lexer: parser->lexer);
16432 if (next->keyword == RID_BOOL)
16433 permerror (next->location, "the %<bool%> keyword is not "
16434 "allowed in a C++20 concept definition");
16435 else
16436 error_at (token->location, "C++20 concept definition syntax "
16437 "is %<concept <name> = <expr>%>");
16438 }
16439
16440 /* In C++20 a concept definition is just 'concept name = expr;'
16441 Support that syntax as a TS extension by pretending we've seen
16442 the 'bool' specifier. */
16443 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
16444 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_EQ)
16445 && !decl_specs->any_type_specifiers_p)
16446 {
16447 cp_parser_set_decl_spec_type (decl_specs, boolean_type_node,
16448 token, /*type_definition*/false);
16449 decl_specs->any_type_specifiers_p = true;
16450 }
16451 break;
16452
16453 /* function-specifier:
16454 inline
16455 virtual
16456 explicit */
16457 case RID_INLINE:
16458 case RID_VIRTUAL:
16459 case RID_EXPLICIT:
16460 cp_parser_function_specifier_opt (parser, decl_specs);
16461 break;
16462
16463 /* decl-specifier:
16464 typedef */
16465 case RID_TYPEDEF:
16466 ds = ds_typedef;
16467 /* Consume the token. */
16468 cp_lexer_consume_token (lexer: parser->lexer);
16469
16470 if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
16471 break;
16472
16473 /* A constructor declarator cannot appear in a typedef. */
16474 constructor_possible_p = false;
16475 /* The "typedef" keyword can only occur in a declaration; we
16476 may as well commit at this point. */
16477 cp_parser_commit_to_tentative_parse (parser);
16478
16479 if (decl_specs->storage_class != sc_none)
16480 {
16481 if (decl_specs->conflicting_specifiers_p)
16482 break;
16483 gcc_rich_location richloc (token->location);
16484 location_t oloc = decl_specs->locations[ds_storage_class];
16485 richloc.add_location_if_nearby (loc: oloc);
16486 error_at (&richloc,
16487 "%<typedef%> specifier conflicts with %qs",
16488 cp_storage_class_name[decl_specs->storage_class]);
16489 decl_specs->conflicting_specifiers_p = true;
16490 }
16491 break;
16492
16493 /* storage-class-specifier:
16494 auto
16495 register
16496 static
16497 extern
16498 mutable
16499
16500 GNU Extension:
16501 thread */
16502 case RID_AUTO:
16503 if (cxx_dialect == cxx98)
16504 {
16505 /* Consume the token. */
16506 cp_lexer_consume_token (lexer: parser->lexer);
16507
16508 /* Complain about `auto' as a storage specifier, if
16509 we're complaining about C++0x compatibility. */
16510 gcc_rich_location richloc (token->location);
16511 richloc.add_fixit_remove ();
16512 warning_at (&richloc, OPT_Wc__11_compat,
16513 "%<auto%> changes meaning in C++11; "
16514 "please remove it");
16515
16516 /* Set the storage class anyway. */
16517 cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
16518 token);
16519 }
16520 else
16521 /* C++0x auto type-specifier. */
16522 found_decl_spec = false;
16523 break;
16524
16525 case RID_REGISTER:
16526 case RID_STATIC:
16527 case RID_EXTERN:
16528 case RID_MUTABLE:
16529 /* Consume the token. */
16530 cp_lexer_consume_token (lexer: parser->lexer);
16531 cp_parser_set_storage_class (parser, decl_specs, token->keyword,
16532 token);
16533 break;
16534 case RID_THREAD:
16535 /* Consume the token. */
16536 ds = ds_thread;
16537 cp_lexer_consume_token (lexer: parser->lexer);
16538 break;
16539
16540 default:
16541 /* We did not yet find a decl-specifier yet. */
16542 found_decl_spec = false;
16543 break;
16544 }
16545
16546 if (found_decl_spec
16547 && (flags & CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR)
16548 && token->keyword != RID_CONSTEXPR)
16549 error ("%qD invalid in condition", ridpointers[token->keyword]);
16550
16551 if (found_decl_spec
16552 && (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
16553 && token->keyword != RID_MUTABLE
16554 && token->keyword != RID_CONSTEXPR
16555 && token->keyword != RID_CONSTEVAL)
16556 {
16557 if (token->keyword != RID_STATIC)
16558 error_at (token->location, "%qD invalid in lambda",
16559 ridpointers[token->keyword]);
16560 else if (cxx_dialect < cxx23)
16561 pedwarn (token->location, OPT_Wc__23_extensions,
16562 "%qD only valid in lambda with %<-std=c++23%> or "
16563 "%<-std=gnu++23%>", ridpointers[token->keyword]);
16564 }
16565
16566 if (ds != ds_last)
16567 set_and_check_decl_spec_loc (decl_specs, ds, token);
16568
16569 /* Constructors are a special case. The `S' in `S()' is not a
16570 decl-specifier; it is the beginning of the declarator. */
16571 constructor_p
16572 = (!found_decl_spec
16573 && constructor_possible_p
16574 && (cp_parser_constructor_declarator_p
16575 (parser, flags, decl_spec_seq_has_spec_p (decl_specs,
16576 ds_friend))));
16577
16578 /* If we don't have a DECL_SPEC yet, then we must be looking at
16579 a type-specifier. */
16580 if (!found_decl_spec && !constructor_p)
16581 {
16582 int decl_spec_declares_class_or_enum;
16583 bool is_cv_qualifier;
16584 tree type_spec;
16585
16586 if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
16587 flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
16588
16589 type_spec
16590 = cp_parser_type_specifier (parser, flags,
16591 decl_specs,
16592 /*is_declaration=*/true,
16593 &decl_spec_declares_class_or_enum,
16594 &is_cv_qualifier);
16595 *declares_class_or_enum |= decl_spec_declares_class_or_enum;
16596
16597 /* If this type-specifier referenced a user-defined type
16598 (a typedef, class-name, etc.), then we can't allow any
16599 more such type-specifiers henceforth.
16600
16601 [dcl.spec]
16602
16603 The longest sequence of decl-specifiers that could
16604 possibly be a type name is taken as the
16605 decl-specifier-seq of a declaration. The sequence shall
16606 be self-consistent as described below.
16607
16608 [dcl.type]
16609
16610 As a general rule, at most one type-specifier is allowed
16611 in the complete decl-specifier-seq of a declaration. The
16612 only exceptions are the following:
16613
16614 -- const or volatile can be combined with any other
16615 type-specifier.
16616
16617 -- signed or unsigned can be combined with char, long,
16618 short, or int.
16619
16620 -- ..
16621
16622 Example:
16623
16624 typedef char* Pc;
16625 void g (const int Pc);
16626
16627 Here, Pc is *not* part of the decl-specifier seq; it's
16628 the declarator. Therefore, once we see a type-specifier
16629 (other than a cv-qualifier), we forbid any additional
16630 user-defined types. We *do* still allow things like `int
16631 int' to be considered a decl-specifier-seq, and issue the
16632 error message later. */
16633 if (type_spec && !is_cv_qualifier)
16634 flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
16635 /* A constructor declarator cannot follow a type-specifier. */
16636 if (type_spec)
16637 {
16638 constructor_possible_p = false;
16639 found_decl_spec = true;
16640 if (!is_cv_qualifier)
16641 decl_specs->any_type_specifiers_p = true;
16642
16643 if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) != 0)
16644 error_at (token->location, "type-specifier invalid in lambda");
16645 }
16646 }
16647
16648 /* If we still do not have a DECL_SPEC, then there are no more
16649 decl-specifiers. */
16650 if (!found_decl_spec)
16651 break;
16652
16653 if (decl_specs->std_attributes)
16654 {
16655 error_at (decl_specs->locations[ds_std_attribute],
16656 "standard attributes in middle of decl-specifiers");
16657 inform (decl_specs->locations[ds_std_attribute],
16658 "standard attributes must precede the decl-specifiers to "
16659 "apply to the declaration, or follow them to apply to "
16660 "the type");
16661 }
16662
16663 decl_specs->any_specifiers_p = true;
16664 /* After we see one decl-specifier, further decl-specifiers are
16665 always optional. */
16666 flags |= CP_PARSER_FLAGS_OPTIONAL;
16667 }
16668
16669 /* Don't allow a friend specifier with a class definition. */
16670 if (decl_spec_seq_has_spec_p (decl_specs, ds_friend)
16671 && (*declares_class_or_enum & 2))
16672 error_at (decl_specs->locations[ds_friend],
16673 "class definition may not be declared a friend");
16674}
16675
16676/* Parse an (optional) storage-class-specifier.
16677
16678 storage-class-specifier:
16679 auto
16680 register
16681 static
16682 extern
16683 mutable
16684
16685 GNU Extension:
16686
16687 storage-class-specifier:
16688 thread
16689
16690 Returns an IDENTIFIER_NODE corresponding to the keyword used. */
16691
16692static tree
16693cp_parser_storage_class_specifier_opt (cp_parser* parser)
16694{
16695 switch (cp_lexer_peek_token (lexer: parser->lexer)->keyword)
16696 {
16697 case RID_AUTO:
16698 if (cxx_dialect != cxx98)
16699 return NULL_TREE;
16700 /* Fall through for C++98. */
16701 gcc_fallthrough ();
16702
16703 case RID_REGISTER:
16704 case RID_STATIC:
16705 case RID_EXTERN:
16706 case RID_MUTABLE:
16707 case RID_THREAD:
16708 /* Consume the token. */
16709 return cp_lexer_consume_token (lexer: parser->lexer)->u.value;
16710
16711 default:
16712 return NULL_TREE;
16713 }
16714}
16715
16716/* Parse an (optional) function-specifier.
16717
16718 function-specifier:
16719 inline
16720 virtual
16721 explicit
16722
16723 C++20 Extension:
16724 explicit(constant-expression)
16725
16726 Returns an IDENTIFIER_NODE corresponding to the keyword used.
16727 Updates DECL_SPECS, if it is non-NULL. */
16728
16729static tree
16730cp_parser_function_specifier_opt (cp_parser* parser,
16731 cp_decl_specifier_seq *decl_specs)
16732{
16733 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
16734 switch (token->keyword)
16735 {
16736 case RID_INLINE:
16737 set_and_check_decl_spec_loc (decl_specs, ds: ds_inline, token);
16738 break;
16739
16740 case RID_VIRTUAL:
16741 /* 14.5.2.3 [temp.mem]
16742
16743 A member function template shall not be virtual. */
16744 if (PROCESSING_REAL_TEMPLATE_DECL_P ()
16745 && current_class_type)
16746 error_at (token->location, "templates may not be %<virtual%>");
16747 else
16748 set_and_check_decl_spec_loc (decl_specs, ds: ds_virtual, token);
16749 break;
16750
16751 case RID_EXPLICIT:
16752 {
16753 tree id = cp_lexer_consume_token (lexer: parser->lexer)->u.value;
16754 /* If we see '(', it's C++20 explicit(bool). */
16755 tree expr;
16756 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
16757 {
16758 matching_parens parens;
16759 parens.consume_open (parser);
16760
16761 /* New types are not allowed in an explicit-specifier. */
16762 const char *saved_message
16763 = parser->type_definition_forbidden_message;
16764 parser->type_definition_forbidden_message
16765 = G_("types may not be defined in explicit-specifier");
16766
16767 if (cxx_dialect < cxx20)
16768 pedwarn (token->location, OPT_Wc__20_extensions,
16769 "%<explicit(bool)%> only available with %<-std=c++20%> "
16770 "or %<-std=gnu++20%>");
16771
16772 /* Parse the constant-expression. */
16773 expr = cp_parser_constant_expression (parser);
16774
16775 /* Restore the saved message. */
16776 parser->type_definition_forbidden_message = saved_message;
16777 parens.require_close (parser);
16778 }
16779 else
16780 /* The explicit-specifier explicit without a constant-expression is
16781 equivalent to the explicit-specifier explicit(true). */
16782 expr = boolean_true_node;
16783
16784 /* [dcl.fct.spec]
16785 "the constant-expression, if supplied, shall be a contextually
16786 converted constant expression of type bool." */
16787 expr = build_explicit_specifier (expr, tf_warning_or_error);
16788 /* We could evaluate it -- mark the decl as appropriate. */
16789 if (expr == boolean_true_node)
16790 set_and_check_decl_spec_loc (decl_specs, ds: ds_explicit, token);
16791 else if (expr == boolean_false_node)
16792 /* Don't mark the decl as explicit. */;
16793 else if (decl_specs)
16794 /* The expression was value-dependent. Remember it so that we can
16795 substitute it later. */
16796 decl_specs->explicit_specifier = expr;
16797 return id;
16798 }
16799
16800 default:
16801 return NULL_TREE;
16802 }
16803
16804 /* Consume the token. */
16805 return cp_lexer_consume_token (lexer: parser->lexer)->u.value;
16806}
16807
16808/* Parse a linkage-specification.
16809
16810 linkage-specification:
16811 extern string-literal { declaration-seq [opt] }
16812 extern string-literal declaration */
16813
16814static void
16815cp_parser_linkage_specification (cp_parser* parser, tree prefix_attr)
16816{
16817 /* Look for the `extern' keyword. */
16818 cp_token *extern_token
16819 = cp_parser_require_keyword (parser, RID_EXTERN, RT_EXTERN);
16820
16821 /* Look for the string-literal. */
16822 cp_token *string_token = cp_lexer_peek_token (lexer: parser->lexer);
16823 tree linkage;
16824 if (cxx_dialect >= cxx26)
16825 linkage = cp_parser_unevaluated_string_literal (parser);
16826 else
16827 linkage = cp_parser_string_literal (parser, /*translate=*/false,
16828 /*wide_ok=*/false);
16829
16830 /* Transform the literal into an identifier. If the literal is a
16831 wide-character string, or contains embedded NULs, then we can't
16832 handle it as the user wants. */
16833 if (linkage == error_mark_node
16834 || strlen (TREE_STRING_POINTER (linkage))
16835 != (size_t) (TREE_STRING_LENGTH (linkage) - 1))
16836 {
16837 cp_parser_error (parser, gmsgid: "invalid linkage-specification");
16838 /* Assume C++ linkage. */
16839 linkage = lang_name_cplusplus;
16840 }
16841 else
16842 linkage = get_identifier (TREE_STRING_POINTER (linkage));
16843
16844 /* We're now using the new linkage. */
16845 unsigned saved_module = module_kind;
16846 module_kind &= ~MK_ATTACH;
16847 push_lang_context (linkage);
16848
16849 /* Preserve the location of the innermost linkage specification,
16850 tracking the locations of nested specifications via a local. */
16851 location_t saved_location
16852 = parser->innermost_linkage_specification_location;
16853 /* Construct a location ranging from the start of the "extern" to
16854 the end of the string-literal, with the caret at the start, e.g.:
16855 extern "C" {
16856 ^~~~~~~~~~
16857 */
16858 parser->innermost_linkage_specification_location
16859 = make_location (caret: extern_token->location,
16860 start: extern_token->location,
16861 finish: get_finish (loc: string_token->location));
16862
16863 /* If the next token is a `{', then we're using the first
16864 production. */
16865 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
16866 {
16867 cp_ensure_no_omp_declare_simd (parser);
16868 cp_ensure_no_oacc_routine (parser);
16869
16870 /* Consume the `{' token. */
16871 matching_braces braces;
16872 braces.consume_open (parser);
16873 /* Parse the declarations. */
16874 cp_parser_declaration_seq_opt (parser);
16875 /* Look for the closing `}'. */
16876 braces.require_close (parser);
16877 }
16878 /* Otherwise, there's just one declaration. */
16879 else
16880 {
16881 bool saved_in_unbraced_linkage_specification_p;
16882
16883 saved_in_unbraced_linkage_specification_p
16884 = parser->in_unbraced_linkage_specification_p;
16885 parser->in_unbraced_linkage_specification_p = true;
16886 cp_parser_declaration (parser, prefix_attrs: prefix_attr);
16887 parser->in_unbraced_linkage_specification_p
16888 = saved_in_unbraced_linkage_specification_p;
16889 }
16890
16891 /* We're done with the linkage-specification. */
16892 pop_lang_context ();
16893 module_kind = saved_module;
16894
16895 /* Restore location of parent linkage specification, if any. */
16896 parser->innermost_linkage_specification_location = saved_location;
16897}
16898
16899/* Parse a static_assert-declaration.
16900
16901 static_assert-declaration:
16902 static_assert ( constant-expression , string-literal ) ;
16903 static_assert ( constant-expression ) ; (C++17)
16904 static_assert ( constant-expression, conditional-expression ) ; (C++26)
16905
16906 If MEMBER_P, this static_assert is a class member. */
16907
16908static void
16909cp_parser_static_assert (cp_parser *parser, bool member_p)
16910{
16911 cp_expr condition;
16912 location_t token_loc;
16913 tree message;
16914
16915 /* Peek at the `static_assert' token so we can keep track of exactly
16916 where the static assertion started. */
16917 token_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
16918
16919 /* Look for the `static_assert' keyword. */
16920 if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT,
16921 RT_STATIC_ASSERT))
16922 return;
16923
16924 /* We know we are in a static assertion; commit to any tentative
16925 parse. */
16926 if (cp_parser_parsing_tentatively (parser))
16927 cp_parser_commit_to_tentative_parse (parser);
16928
16929 /* Parse the `(' starting the static assertion condition. */
16930 matching_parens parens;
16931 parens.require_open (parser);
16932
16933 /* Parse the constant-expression. Allow a non-constant expression
16934 here in order to give better diagnostics in finish_static_assert. */
16935 condition
16936 = cp_parser_constant_expression (parser,
16937 /*allow_non_constant_p=*/true,
16938 /*non_constant_p=*/nullptr);
16939
16940 if (cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_CLOSE_PAREN)
16941 {
16942 if (pedantic && cxx_dialect < cxx17)
16943 pedwarn (input_location, OPT_Wc__17_extensions,
16944 "%<static_assert%> without a message "
16945 "only available with %<-std=c++17%> or %<-std=gnu++17%>");
16946 /* Eat the ')' */
16947 cp_lexer_consume_token (lexer: parser->lexer);
16948 message = build_string (1, "");
16949 TREE_TYPE (message) = char_array_type_node;
16950 fix_string_type (message);
16951 }
16952 else
16953 {
16954 /* Parse the separating `,'. */
16955 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
16956
16957 /* Parse the message expression. */
16958 bool string_lit = true;
16959 for (unsigned int i = 1; ; ++i)
16960 {
16961 cp_token *tok = cp_lexer_peek_nth_token (lexer: parser->lexer, n: i);
16962 if (cp_parser_is_pure_string_literal (token: tok))
16963 continue;
16964 else if (tok->type == CPP_CLOSE_PAREN)
16965 break;
16966 string_lit = false;
16967 break;
16968 }
16969 if (!string_lit)
16970 {
16971 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
16972 if (cxx_dialect < cxx26)
16973 pedwarn (loc, OPT_Wc__26_extensions,
16974 "%<static_assert%> with non-string message only "
16975 "available with %<-std=c++2c%> or %<-std=gnu++2c%>");
16976
16977 message = cp_parser_conditional_expression (parser);
16978 if (TREE_CODE (message) == STRING_CST)
16979 message = build1_loc (loc, code: PAREN_EXPR, TREE_TYPE (message),
16980 arg1: message);
16981 }
16982 else if (cxx_dialect >= cxx26)
16983 message = cp_parser_unevaluated_string_literal (parser);
16984 else
16985 message = cp_parser_string_literal (parser, /*translate=*/false,
16986 /*wide_ok=*/true);
16987
16988 /* A `)' completes the static assertion. */
16989 if (!parens.require_close (parser))
16990 cp_parser_skip_to_closing_parenthesis (parser,
16991 /*recovering=*/true,
16992 /*or_comma=*/false,
16993 /*consume_paren=*/true);
16994 }
16995
16996 /* A semicolon terminates the declaration. */
16997 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
16998
16999 /* Get the location for the static assertion. Use that of the
17000 condition if available, otherwise, use that of the "static_assert"
17001 token. */
17002 location_t assert_loc = condition.get_location ();
17003 if (assert_loc == UNKNOWN_LOCATION)
17004 assert_loc = token_loc;
17005
17006 /* Complete the static assertion, which may mean either processing
17007 the static assert now or saving it for template instantiation. */
17008 finish_static_assert (condition, message, assert_loc, member_p,
17009 /*show_expr_p=*/false);
17010}
17011
17012/* Parse the expression in decltype ( expression ). */
17013
17014static tree
17015cp_parser_decltype_expr (cp_parser *parser,
17016 bool &id_expression_or_member_access_p)
17017{
17018 cp_token *id_expr_start_token;
17019 tree expr;
17020
17021 /* First, try parsing an id-expression. */
17022 id_expr_start_token = cp_lexer_peek_token (lexer: parser->lexer);
17023 cp_parser_parse_tentatively (parser);
17024 expr = cp_parser_id_expression (parser,
17025 /*template_keyword_p=*/false,
17026 /*check_dependency_p=*/true,
17027 /*template_p=*/NULL,
17028 /*declarator_p=*/false,
17029 /*optional_p=*/false);
17030
17031 if (!cp_parser_error_occurred (parser) && expr != error_mark_node)
17032 {
17033 bool non_integral_constant_expression_p = false;
17034 tree id_expression = expr;
17035 cp_id_kind idk;
17036 const char *error_msg;
17037
17038 if (identifier_p (t: expr))
17039 /* Lookup the name we got back from the id-expression. */
17040 expr = cp_parser_lookup_name_simple (parser, expr,
17041 id_expr_start_token->location);
17042
17043 if (expr
17044 && expr != error_mark_node
17045 && TREE_CODE (expr) != TYPE_DECL
17046 && (TREE_CODE (expr) != BIT_NOT_EXPR
17047 || !TYPE_P (TREE_OPERAND (expr, 0)))
17048 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_CLOSE_PAREN)
17049 {
17050 /* Complete lookup of the id-expression. */
17051 expr = (finish_id_expression
17052 (id_expression, expr, parser->scope, &idk,
17053 /*integral_constant_expression_p=*/false,
17054 /*allow_non_integral_constant_expression_p=*/true,
17055 &non_integral_constant_expression_p,
17056 /*template_p=*/false,
17057 /*done=*/true,
17058 /*address_p=*/false,
17059 /*template_arg_p=*/false,
17060 &error_msg,
17061 id_expr_start_token->location));
17062
17063 if (error_msg)
17064 {
17065 /* We found an id-expression, but it was something that we
17066 should not have found. This is an error, not something
17067 we can recover from, so report the error we found and
17068 we'll recover as gracefully as possible. */
17069 cp_parser_parse_definitely (parser);
17070 cp_parser_error (parser, gmsgid: error_msg);
17071 id_expression_or_member_access_p = true;
17072 return error_mark_node;
17073 }
17074 }
17075
17076 if (expr
17077 && expr != error_mark_node
17078 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_CLOSE_PAREN)
17079 /* We have an id-expression. */
17080 id_expression_or_member_access_p = true;
17081 }
17082
17083 if (!id_expression_or_member_access_p)
17084 {
17085 /* Abort the id-expression parse. */
17086 cp_parser_abort_tentative_parse (parser);
17087
17088 /* Parsing tentatively, again. */
17089 cp_parser_parse_tentatively (parser);
17090
17091 /* Parse a class member access. */
17092 expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
17093 /*cast_p=*/false, /*decltype*/member_access_only_p: true,
17094 /*member_access_only_p=*/decltype_p: true, NULL);
17095
17096 if (expr
17097 && expr != error_mark_node
17098 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_CLOSE_PAREN)
17099 /* We have an id-expression. */
17100 id_expression_or_member_access_p = true;
17101 }
17102
17103 if (id_expression_or_member_access_p)
17104 /* We have parsed the complete id-expression or member access. */
17105 cp_parser_parse_definitely (parser);
17106 else
17107 {
17108 /* Abort our attempt to parse an id-expression or member access
17109 expression. */
17110 cp_parser_abort_tentative_parse (parser);
17111
17112 /* Parse a full expression. */
17113 expr = cp_parser_expression (parser, /*pidk=*/NULL, /*cast_p=*/false,
17114 /*decltype_p=*/true);
17115 }
17116
17117 return expr;
17118}
17119
17120/* Parse a `decltype' type. Returns the type.
17121
17122 decltype-specifier:
17123 decltype ( expression )
17124 C++14:
17125 decltype ( auto ) */
17126
17127static tree
17128cp_parser_decltype (cp_parser *parser)
17129{
17130 bool id_expression_or_member_access_p = false;
17131 cp_token *start_token = cp_lexer_peek_token (lexer: parser->lexer);
17132
17133 if (start_token->type == CPP_DECLTYPE)
17134 {
17135 /* Already parsed. */
17136 cp_lexer_consume_token (lexer: parser->lexer);
17137 return saved_checks_value (check_value: start_token->u.tree_check_value);
17138 }
17139
17140 /* Look for the `decltype' token. */
17141 if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE))
17142 return error_mark_node;
17143
17144 /* Parse the opening `('. */
17145 matching_parens parens;
17146 if (!parens.require_open (parser))
17147 return error_mark_node;
17148
17149 /* Since we're going to preserve any side-effects from this parse, set up a
17150 firewall to protect our callers from cp_parser_commit_to_tentative_parse
17151 in the expression. */
17152 tentative_firewall firewall (parser);
17153
17154 /* If in_declarator_p, a reparse as an expression might succeed (60361).
17155 Otherwise, commit now for better diagnostics. */
17156 if (cp_parser_uncommitted_to_tentative_parse_p (parser)
17157 && !parser->in_declarator_p)
17158 cp_parser_commit_to_topmost_tentative_parse (parser);
17159
17160 push_deferring_access_checks (dk_deferred);
17161
17162 tree expr = NULL_TREE;
17163
17164 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_AUTO)
17165 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_CLOSE_PAREN))
17166 {
17167 /* decltype (auto) */
17168 cp_lexer_consume_token (lexer: parser->lexer);
17169 if (cxx_dialect < cxx14)
17170 {
17171 error_at (start_token->location,
17172 "%<decltype(auto)%> type specifier only available with "
17173 "%<-std=c++14%> or %<-std=gnu++14%>");
17174 expr = error_mark_node;
17175 }
17176 }
17177 else
17178 {
17179 /* decltype (expression) */
17180
17181 /* Types cannot be defined in a `decltype' expression. Save away the
17182 old message and set the new one. */
17183 const char *saved_message = parser->type_definition_forbidden_message;
17184 parser->type_definition_forbidden_message
17185 = G_("types may not be defined in %<decltype%> expressions");
17186
17187 /* The restrictions on constant-expressions do not apply inside
17188 decltype expressions. */
17189 bool saved_integral_constant_expression_p
17190 = parser->integral_constant_expression_p;
17191 bool saved_non_integral_constant_expression_p
17192 = parser->non_integral_constant_expression_p;
17193 parser->integral_constant_expression_p = false;
17194
17195 /* Within a parenthesized expression, a `>' token is always
17196 the greater-than operator. */
17197 bool saved_greater_than_is_operator_p
17198 = parser->greater_than_is_operator_p;
17199 parser->greater_than_is_operator_p = true;
17200
17201 /* Don't synthesize an implicit template type parameter here. This
17202 could happen with C++23 code like
17203
17204 void f(decltype(new auto{0}));
17205
17206 where we want to deduce the auto right away so that the parameter
17207 is of type 'int *'. */
17208 auto cleanup = make_temp_override
17209 (var&: parser->auto_is_implicit_function_template_parm_p, overrider: false);
17210
17211 /* Do not actually evaluate the expression. */
17212 ++cp_unevaluated_operand;
17213
17214 /* Do not warn about problems with the expression. */
17215 ++c_inhibit_evaluation_warnings;
17216
17217 expr = cp_parser_decltype_expr (parser, id_expression_or_member_access_p);
17218 STRIP_ANY_LOCATION_WRAPPER (expr);
17219
17220 /* Go back to evaluating expressions. */
17221 --cp_unevaluated_operand;
17222 --c_inhibit_evaluation_warnings;
17223
17224 /* The `>' token might be the end of a template-id or
17225 template-parameter-list now. */
17226 parser->greater_than_is_operator_p
17227 = saved_greater_than_is_operator_p;
17228
17229 /* Restore the old message and the integral constant expression
17230 flags. */
17231 parser->type_definition_forbidden_message = saved_message;
17232 parser->integral_constant_expression_p
17233 = saved_integral_constant_expression_p;
17234 parser->non_integral_constant_expression_p
17235 = saved_non_integral_constant_expression_p;
17236 }
17237
17238 /* Parse to the closing `)'. */
17239 if (expr == error_mark_node || !parens.require_close (parser))
17240 {
17241 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false,
17242 /*consume_paren=*/true);
17243 expr = error_mark_node;
17244 }
17245
17246 /* If we got a parse error while tentative, bail out now. */
17247 if (cp_parser_error_occurred (parser))
17248 {
17249 pop_deferring_access_checks ();
17250 return error_mark_node;
17251 }
17252
17253 if (!expr)
17254 /* Build auto. */
17255 expr = make_decltype_auto ();
17256 else
17257 expr = finish_decltype_type (expr, id_expression_or_member_access_p,
17258 tf_warning_or_error);
17259
17260 /* Replace the decltype with a CPP_DECLTYPE so we don't need to parse
17261 it again. */
17262 start_token->type = CPP_DECLTYPE;
17263 start_token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
17264 start_token->tree_check_p = true;
17265 start_token->u.tree_check_value->value = expr;
17266 start_token->u.tree_check_value->checks = get_deferred_access_checks ();
17267 start_token->keyword = RID_MAX;
17268
17269 location_t loc = start_token->location;
17270 loc = make_location (caret: loc, start: loc, lexer: parser->lexer);
17271 start_token->location = loc;
17272
17273 cp_lexer_purge_tokens_after (lexer: parser->lexer, tok: start_token);
17274
17275 pop_to_parent_deferring_access_checks ();
17276
17277 return expr;
17278}
17279
17280/* Special member functions [gram.special] */
17281
17282/* Parse a conversion-function-id.
17283
17284 conversion-function-id:
17285 operator conversion-type-id
17286
17287 Returns an IDENTIFIER_NODE representing the operator. */
17288
17289static tree
17290cp_parser_conversion_function_id (cp_parser* parser)
17291{
17292 tree type;
17293 tree saved_scope;
17294 tree saved_qualifying_scope;
17295 tree saved_object_scope;
17296 tree pushed_scope = NULL_TREE;
17297
17298 /* Look for the `operator' token. */
17299 if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
17300 return error_mark_node;
17301 /* When we parse the conversion-type-id, the current scope will be
17302 reset. However, we need that information in able to look up the
17303 conversion function later, so we save it here. */
17304 saved_scope = parser->scope;
17305 saved_qualifying_scope = parser->qualifying_scope;
17306 saved_object_scope = parser->object_scope;
17307 /* We must enter the scope of the class so that the names of
17308 entities declared within the class are available in the
17309 conversion-type-id. For example, consider:
17310
17311 struct S {
17312 typedef int I;
17313 operator I();
17314 };
17315
17316 S::operator I() { ... }
17317
17318 In order to see that `I' is a type-name in the definition, we
17319 must be in the scope of `S'. */
17320 if (saved_scope)
17321 pushed_scope = push_scope (saved_scope);
17322 /* Parse the conversion-type-id. */
17323 type = cp_parser_conversion_type_id (parser);
17324 /* Leave the scope of the class, if any. */
17325 if (pushed_scope)
17326 pop_scope (pushed_scope);
17327 /* Restore the saved scope. */
17328 parser->scope = saved_scope;
17329 parser->qualifying_scope = saved_qualifying_scope;
17330 parser->object_scope = saved_object_scope;
17331 /* If the TYPE is invalid, indicate failure. */
17332 if (type == error_mark_node)
17333 return error_mark_node;
17334 return make_conv_op_name (type);
17335}
17336
17337/* Parse a conversion-type-id:
17338
17339 conversion-type-id:
17340 type-specifier-seq conversion-declarator [opt]
17341
17342 Returns the TYPE specified. */
17343
17344static tree
17345cp_parser_conversion_type_id (cp_parser* parser)
17346{
17347 tree attributes;
17348 cp_decl_specifier_seq type_specifiers;
17349 cp_declarator *declarator;
17350 tree type_specified;
17351 const char *saved_message;
17352
17353 /* Parse the attributes. */
17354 attributes = cp_parser_attributes_opt (parser);
17355
17356 saved_message = parser->type_definition_forbidden_message;
17357 parser->type_definition_forbidden_message
17358 = G_("types may not be defined in a conversion-type-id");
17359
17360 /* Parse the type-specifiers. DR 2413 clarifies that `typename' is
17361 optional in conversion-type-id. */
17362 cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
17363 /*is_declaration=*/false,
17364 /*is_trailing_return=*/false,
17365 &type_specifiers);
17366
17367 parser->type_definition_forbidden_message = saved_message;
17368
17369 /* If that didn't work, stop. */
17370 if (type_specifiers.type == error_mark_node)
17371 return error_mark_node;
17372 /* Parse the conversion-declarator. */
17373 declarator = cp_parser_conversion_declarator_opt (parser);
17374
17375 type_specified = grokdeclarator (declarator, &type_specifiers, TYPENAME,
17376 /*initialized=*/0, &attributes);
17377 if (attributes)
17378 cplus_decl_attributes (&type_specified, attributes, /*flags=*/0);
17379
17380 /* Don't give this error when parsing tentatively. This happens to
17381 work because we always parse this definitively once. */
17382 if (! cp_parser_uncommitted_to_tentative_parse_p (parser)
17383 && type_uses_auto (type_specified))
17384 {
17385 if (cxx_dialect < cxx14)
17386 {
17387 error ("invalid use of %<auto%> in conversion operator");
17388 return error_mark_node;
17389 }
17390 else if (template_parm_scope_p ())
17391 warning (0, "use of %<auto%> in member template "
17392 "conversion operator can never be deduced");
17393 }
17394
17395 return type_specified;
17396}
17397
17398/* Parse an (optional) conversion-declarator.
17399
17400 conversion-declarator:
17401 ptr-operator conversion-declarator [opt]
17402
17403 */
17404
17405static cp_declarator *
17406cp_parser_conversion_declarator_opt (cp_parser* parser)
17407{
17408 enum tree_code code;
17409 tree class_type, std_attributes = NULL_TREE;
17410 cp_cv_quals cv_quals;
17411
17412 /* We don't know if there's a ptr-operator next, or not. */
17413 cp_parser_parse_tentatively (parser);
17414 /* Try the ptr-operator. */
17415 code = cp_parser_ptr_operator (parser, &class_type, &cv_quals,
17416 &std_attributes);
17417 /* If it worked, look for more conversion-declarators. */
17418 if (cp_parser_parse_definitely (parser))
17419 {
17420 cp_declarator *declarator;
17421
17422 /* Parse another optional declarator. */
17423 declarator = cp_parser_conversion_declarator_opt (parser);
17424
17425 declarator = cp_parser_make_indirect_declarator
17426 (code, class_type, cv_qualifiers: cv_quals, target: declarator, attributes: std_attributes);
17427
17428 return declarator;
17429 }
17430
17431 return NULL;
17432}
17433
17434/* Parse an (optional) ctor-initializer.
17435
17436 ctor-initializer:
17437 : mem-initializer-list */
17438
17439static void
17440cp_parser_ctor_initializer_opt (cp_parser* parser)
17441{
17442 /* If the next token is not a `:', then there is no
17443 ctor-initializer. */
17444 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COLON))
17445 {
17446 /* Do default initialization of any bases and members. */
17447 if (DECL_CONSTRUCTOR_P (current_function_decl))
17448 finish_mem_initializers (NULL_TREE);
17449 return;
17450 }
17451
17452 /* Consume the `:' token. */
17453 cp_lexer_consume_token (lexer: parser->lexer);
17454 /* And the mem-initializer-list. */
17455 cp_parser_mem_initializer_list (parser);
17456}
17457
17458/* Parse a mem-initializer-list.
17459
17460 mem-initializer-list:
17461 mem-initializer ... [opt]
17462 mem-initializer ... [opt] , mem-initializer-list */
17463
17464static void
17465cp_parser_mem_initializer_list (cp_parser* parser)
17466{
17467 tree mem_initializer_list = NULL_TREE;
17468 tree target_ctor = error_mark_node;
17469 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
17470
17471 /* Let the semantic analysis code know that we are starting the
17472 mem-initializer-list. */
17473 if (!DECL_CONSTRUCTOR_P (current_function_decl))
17474 error_at (token->location,
17475 "only constructors take member initializers");
17476
17477 /* Loop through the list. */
17478 while (true)
17479 {
17480 tree mem_initializer;
17481
17482 token = cp_lexer_peek_token (lexer: parser->lexer);
17483 /* Parse the mem-initializer. */
17484 mem_initializer = cp_parser_mem_initializer (parser);
17485 /* If the next token is a `...', we're expanding member initializers. */
17486 bool ellipsis = cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS);
17487 if (ellipsis
17488 || (mem_initializer != error_mark_node
17489 && check_for_bare_parameter_packs (TREE_PURPOSE
17490 (mem_initializer))))
17491 {
17492 /* Consume the `...'. */
17493 if (ellipsis)
17494 cp_lexer_consume_token (lexer: parser->lexer);
17495
17496 /* The TREE_PURPOSE must be a _TYPE, because base-specifiers
17497 can be expanded but members cannot. */
17498 if (mem_initializer != error_mark_node
17499 && !TYPE_P (TREE_PURPOSE (mem_initializer)))
17500 {
17501 error_at (token->location,
17502 "cannot expand initializer for member %qD",
17503 TREE_PURPOSE (mem_initializer));
17504 mem_initializer = error_mark_node;
17505 }
17506
17507 /* Construct the pack expansion type. */
17508 if (mem_initializer != error_mark_node)
17509 mem_initializer = make_pack_expansion (mem_initializer);
17510 }
17511 if (target_ctor != error_mark_node
17512 && mem_initializer != error_mark_node)
17513 {
17514 error ("mem-initializer for %qD follows constructor delegation",
17515 TREE_PURPOSE (mem_initializer));
17516 mem_initializer = error_mark_node;
17517 }
17518 /* Look for a target constructor. */
17519 if (mem_initializer != error_mark_node
17520 && CLASS_TYPE_P (TREE_PURPOSE (mem_initializer))
17521 && same_type_p (TREE_PURPOSE (mem_initializer), current_class_type))
17522 {
17523 maybe_warn_cpp0x (str: CPP0X_DELEGATING_CTORS);
17524 if (mem_initializer_list)
17525 {
17526 error ("constructor delegation follows mem-initializer for %qD",
17527 TREE_PURPOSE (mem_initializer_list));
17528 mem_initializer = error_mark_node;
17529 }
17530 target_ctor = mem_initializer;
17531 }
17532 /* Add it to the list, unless it was erroneous. */
17533 if (mem_initializer != error_mark_node)
17534 {
17535 TREE_CHAIN (mem_initializer) = mem_initializer_list;
17536 mem_initializer_list = mem_initializer;
17537 }
17538 /* If the next token is not a `,', we're done. */
17539 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
17540 break;
17541 /* Consume the `,' token. */
17542 cp_lexer_consume_token (lexer: parser->lexer);
17543 }
17544
17545 /* Perform semantic analysis. */
17546 if (DECL_CONSTRUCTOR_P (current_function_decl))
17547 finish_mem_initializers (mem_initializer_list);
17548}
17549
17550/* Parse a mem-initializer.
17551
17552 mem-initializer:
17553 mem-initializer-id ( expression-list [opt] )
17554 mem-initializer-id braced-init-list
17555
17556 GNU extension:
17557
17558 mem-initializer:
17559 ( expression-list [opt] )
17560
17561 Returns a TREE_LIST. The TREE_PURPOSE is the TYPE (for a base
17562 class) or FIELD_DECL (for a non-static data member) to initialize;
17563 the TREE_VALUE is the expression-list. An empty initialization
17564 list is represented by void_list_node. */
17565
17566static tree
17567cp_parser_mem_initializer (cp_parser* parser)
17568{
17569 tree mem_initializer_id;
17570 tree expression_list;
17571 tree member;
17572 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
17573
17574 /* Find out what is being initialized. */
17575 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
17576 {
17577 permerror (token->location,
17578 "anachronistic old-style base class initializer");
17579 mem_initializer_id = NULL_TREE;
17580 }
17581 else
17582 {
17583 mem_initializer_id = cp_parser_mem_initializer_id (parser);
17584 if (mem_initializer_id == error_mark_node)
17585 return mem_initializer_id;
17586 }
17587 member = expand_member_init (mem_initializer_id);
17588 if (member && !DECL_P (member))
17589 in_base_initializer = 1;
17590
17591 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
17592 {
17593 cp_lexer_set_source_position (lexer: parser->lexer);
17594 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
17595 expression_list = cp_parser_braced_list (parser);
17596 CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
17597 expression_list = build_tree_list (NULL_TREE, expression_list);
17598 }
17599 else
17600 {
17601 vec<tree, va_gc> *vec;
17602 vec = cp_parser_parenthesized_expression_list (parser, is_attribute_list: non_attr,
17603 /*cast_p=*/false,
17604 /*allow_expansion_p=*/true,
17605 /*non_constant_p=*/NULL,
17606 /*close_paren_loc=*/NULL,
17607 /*wrap_locations_p=*/true);
17608 if (vec == NULL)
17609 return error_mark_node;
17610 expression_list = build_tree_list_vec (vec);
17611 release_tree_vector (vec);
17612 }
17613
17614 if (expression_list == error_mark_node)
17615 return error_mark_node;
17616 if (!expression_list)
17617 expression_list = void_type_node;
17618
17619 in_base_initializer = 0;
17620
17621 if (!member)
17622 return error_mark_node;
17623 tree node = build_tree_list (member, expression_list);
17624
17625 /* We can't attach the source location of this initializer directly to
17626 the list node, so we instead attach it to a dummy EMPTY_CLASS_EXPR
17627 within the TREE_TYPE of the list node. */
17628 location_t loc
17629 = make_location (caret: token->location, start: token->location, lexer: parser->lexer);
17630 tree dummy = build0 (EMPTY_CLASS_EXPR, NULL_TREE);
17631 SET_EXPR_LOCATION (dummy, loc);
17632 TREE_TYPE (node) = dummy;
17633
17634 return node;
17635}
17636
17637/* Parse a mem-initializer-id.
17638
17639 mem-initializer-id:
17640 :: [opt] nested-name-specifier [opt] class-name
17641 decltype-specifier (C++11)
17642 identifier
17643
17644 Returns a TYPE indicating the class to be initialized for the first
17645 production (and the second in C++11). Returns an IDENTIFIER_NODE
17646 indicating the data member to be initialized for the last production. */
17647
17648static tree
17649cp_parser_mem_initializer_id (cp_parser* parser)
17650{
17651 bool global_scope_p;
17652 bool nested_name_specifier_p;
17653 bool template_p = false;
17654 tree id;
17655
17656 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
17657
17658 /* `typename' is not allowed in this context ([temp.res]). */
17659 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TYPENAME))
17660 {
17661 error_at (token->location,
17662 "keyword %<typename%> not allowed in this context (a qualified "
17663 "member initializer is implicitly a type)");
17664 cp_lexer_consume_token (lexer: parser->lexer);
17665 }
17666 /* Look for the optional `::' operator. */
17667 global_scope_p
17668 = (cp_parser_global_scope_opt (parser,
17669 /*current_scope_valid_p=*/false)
17670 != NULL_TREE);
17671 /* Look for the optional nested-name-specifier. The simplest way to
17672 implement:
17673
17674 [temp.res]
17675
17676 The keyword `typename' is not permitted in a base-specifier or
17677 mem-initializer; in these contexts a qualified name that
17678 depends on a template-parameter is implicitly assumed to be a
17679 type name.
17680
17681 is to assume that we have seen the `typename' keyword at this
17682 point. */
17683 nested_name_specifier_p
17684 = (cp_parser_nested_name_specifier_opt (parser,
17685 /*typename_keyword_p=*/true,
17686 /*check_dependency_p=*/true,
17687 /*type_p=*/true,
17688 /*is_declaration=*/true)
17689 != NULL_TREE);
17690 if (nested_name_specifier_p)
17691 template_p = cp_parser_optional_template_keyword (parser);
17692 /* If there is a `::' operator or a nested-name-specifier, then we
17693 are definitely looking for a class-name. */
17694 if (global_scope_p || nested_name_specifier_p)
17695 return cp_parser_class_name (parser,
17696 /*typename_keyword_p=*/true,
17697 /*template_keyword_p=*/template_p,
17698 typename_type,
17699 /*check_dependency_p=*/true,
17700 /*class_head_p=*/false,
17701 /*is_declaration=*/true);
17702 /* Otherwise, we could also be looking for an ordinary identifier. */
17703 cp_parser_parse_tentatively (parser);
17704 if (cp_lexer_next_token_is_decltype (lexer: parser->lexer))
17705 /* Try a decltype-specifier. */
17706 id = cp_parser_decltype (parser);
17707 else
17708 /* Otherwise, try a class-name. */
17709 id = cp_parser_class_name (parser,
17710 /*typename_keyword_p=*/true,
17711 /*template_keyword_p=*/false,
17712 none_type,
17713 /*check_dependency_p=*/true,
17714 /*class_head_p=*/false,
17715 /*is_declaration=*/true);
17716 /* If we found one, we're done. */
17717 if (cp_parser_parse_definitely (parser))
17718 return id;
17719 /* Otherwise, look for an ordinary identifier. */
17720 return cp_parser_identifier (parser);
17721}
17722
17723/* Overloading [gram.over] */
17724
17725/* Parse an operator-function-id.
17726
17727 operator-function-id:
17728 operator operator
17729
17730 Returns an IDENTIFIER_NODE for the operator which is a
17731 human-readable spelling of the identifier, e.g., `operator +'. */
17732
17733static cp_expr
17734cp_parser_operator_function_id (cp_parser* parser)
17735{
17736 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
17737 /* Look for the `operator' keyword. */
17738 if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
17739 return error_mark_node;
17740 /* And then the name of the operator itself. */
17741 return cp_parser_operator (parser, start_loc);
17742}
17743
17744/* Return an identifier node for a user-defined literal operator.
17745 The suffix identifier is chained to the operator name identifier. */
17746
17747tree
17748cp_literal_operator_id (const char* name)
17749{
17750 tree identifier;
17751 char *buffer = XNEWVEC (char, strlen (UDLIT_OP_ANSI_PREFIX)
17752 + strlen (name) + 10);
17753 sprintf (s: buffer, UDLIT_OP_ANSI_FORMAT, name);
17754 identifier = get_identifier (buffer);
17755 XDELETEVEC (buffer);
17756
17757 return identifier;
17758}
17759
17760/* Parse an operator.
17761
17762 operator:
17763 new delete new[] delete[] + - * / % ^ & | ~ ! = < >
17764 += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= &&
17765 || ++ -- , ->* -> () []
17766
17767 GNU Extensions:
17768
17769 operator:
17770 <? >? <?= >?=
17771
17772 Returns an IDENTIFIER_NODE for the operator which is a
17773 human-readable spelling of the identifier, e.g., `operator +'. */
17774
17775static cp_expr
17776cp_parser_operator (cp_parser* parser, location_t start_loc)
17777{
17778 tree id = NULL_TREE;
17779 cp_token *token;
17780 bool utf8 = false;
17781
17782 /* Peek at the next token. */
17783 token = cp_lexer_peek_token (lexer: parser->lexer);
17784
17785 location_t end_loc = token->location;
17786
17787 /* Figure out which operator we have. */
17788 enum tree_code op = ERROR_MARK;
17789 bool assop = false;
17790 bool consumed = false;
17791 switch (token->type)
17792 {
17793 case CPP_KEYWORD:
17794 {
17795 /* The keyword should be either `new', `delete' or `co_await'. */
17796 if (token->keyword == RID_NEW)
17797 op = NEW_EXPR;
17798 else if (token->keyword == RID_DELETE)
17799 op = DELETE_EXPR;
17800 else if (token->keyword == RID_CO_AWAIT)
17801 op = CO_AWAIT_EXPR;
17802 else
17803 break;
17804
17805 /* Consume the `new', `delete' or co_await token. */
17806 end_loc = cp_lexer_consume_token (lexer: parser->lexer)->location;
17807
17808 /* Peek at the next token. */
17809 token = cp_lexer_peek_token (lexer: parser->lexer);
17810 /* If it's a `[' token then this is the array variant of the
17811 operator. */
17812 if (token->type == CPP_OPEN_SQUARE
17813 && op != CO_AWAIT_EXPR)
17814 {
17815 /* Consume the `[' token. */
17816 cp_lexer_consume_token (lexer: parser->lexer);
17817 /* Look for the `]' token. */
17818 if (cp_token *close_token
17819 = cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
17820 end_loc = close_token->location;
17821 op = op == NEW_EXPR ? VEC_NEW_EXPR : VEC_DELETE_EXPR;
17822 }
17823 consumed = true;
17824 break;
17825 }
17826
17827 case CPP_PLUS:
17828 op = PLUS_EXPR;
17829 break;
17830
17831 case CPP_MINUS:
17832 op = MINUS_EXPR;
17833 break;
17834
17835 case CPP_MULT:
17836 op = MULT_EXPR;
17837 break;
17838
17839 case CPP_DIV:
17840 op = TRUNC_DIV_EXPR;
17841 break;
17842
17843 case CPP_MOD:
17844 op = TRUNC_MOD_EXPR;
17845 break;
17846
17847 case CPP_XOR:
17848 op = BIT_XOR_EXPR;
17849 break;
17850
17851 case CPP_AND:
17852 op = BIT_AND_EXPR;
17853 break;
17854
17855 case CPP_OR:
17856 op = BIT_IOR_EXPR;
17857 break;
17858
17859 case CPP_COMPL:
17860 op = BIT_NOT_EXPR;
17861 break;
17862
17863 case CPP_NOT:
17864 op = TRUTH_NOT_EXPR;
17865 break;
17866
17867 case CPP_EQ:
17868 assop = true;
17869 op = NOP_EXPR;
17870 break;
17871
17872 case CPP_LESS:
17873 op = LT_EXPR;
17874 break;
17875
17876 case CPP_GREATER:
17877 op = GT_EXPR;
17878 break;
17879
17880 case CPP_PLUS_EQ:
17881 assop = true;
17882 op = PLUS_EXPR;
17883 break;
17884
17885 case CPP_MINUS_EQ:
17886 assop = true;
17887 op = MINUS_EXPR;
17888 break;
17889
17890 case CPP_MULT_EQ:
17891 assop = true;
17892 op = MULT_EXPR;
17893 break;
17894
17895 case CPP_DIV_EQ:
17896 assop = true;
17897 op = TRUNC_DIV_EXPR;
17898 break;
17899
17900 case CPP_MOD_EQ:
17901 assop = true;
17902 op = TRUNC_MOD_EXPR;
17903 break;
17904
17905 case CPP_XOR_EQ:
17906 assop = true;
17907 op = BIT_XOR_EXPR;
17908 break;
17909
17910 case CPP_AND_EQ:
17911 assop = true;
17912 op = BIT_AND_EXPR;
17913 break;
17914
17915 case CPP_OR_EQ:
17916 assop = true;
17917 op = BIT_IOR_EXPR;
17918 break;
17919
17920 case CPP_LSHIFT:
17921 op = LSHIFT_EXPR;
17922 break;
17923
17924 case CPP_RSHIFT:
17925 op = RSHIFT_EXPR;
17926 break;
17927
17928 case CPP_LSHIFT_EQ:
17929 assop = true;
17930 op = LSHIFT_EXPR;
17931 break;
17932
17933 case CPP_RSHIFT_EQ:
17934 assop = true;
17935 op = RSHIFT_EXPR;
17936 break;
17937
17938 case CPP_EQ_EQ:
17939 op = EQ_EXPR;
17940 break;
17941
17942 case CPP_NOT_EQ:
17943 op = NE_EXPR;
17944 break;
17945
17946 case CPP_LESS_EQ:
17947 op = LE_EXPR;
17948 break;
17949
17950 case CPP_GREATER_EQ:
17951 op = GE_EXPR;
17952 break;
17953
17954 case CPP_SPACESHIP:
17955 op = SPACESHIP_EXPR;
17956 break;
17957
17958 case CPP_AND_AND:
17959 op = TRUTH_ANDIF_EXPR;
17960 break;
17961
17962 case CPP_OR_OR:
17963 op = TRUTH_ORIF_EXPR;
17964 break;
17965
17966 case CPP_PLUS_PLUS:
17967 op = POSTINCREMENT_EXPR;
17968 break;
17969
17970 case CPP_MINUS_MINUS:
17971 op = PREDECREMENT_EXPR;
17972 break;
17973
17974 case CPP_COMMA:
17975 op = COMPOUND_EXPR;
17976 break;
17977
17978 case CPP_DEREF_STAR:
17979 op = MEMBER_REF;
17980 break;
17981
17982 case CPP_DEREF:
17983 op = COMPONENT_REF;
17984 break;
17985
17986 case CPP_QUERY:
17987 op = COND_EXPR;
17988 /* Consume the `?'. */
17989 cp_lexer_consume_token (lexer: parser->lexer);
17990 /* Look for the matching `:'. */
17991 cp_parser_require (parser, CPP_COLON, RT_COLON);
17992 consumed = true;
17993 break;
17994
17995 case CPP_OPEN_PAREN:
17996 {
17997 /* Consume the `('. */
17998 matching_parens parens;
17999 parens.consume_open (parser);
18000 /* Look for the matching `)'. */
18001 token = parens.require_close (parser);
18002 if (token)
18003 end_loc = token->location;
18004 op = CALL_EXPR;
18005 consumed = true;
18006 break;
18007 }
18008
18009 case CPP_OPEN_SQUARE:
18010 /* Consume the `['. */
18011 cp_lexer_consume_token (lexer: parser->lexer);
18012 /* Look for the matching `]'. */
18013 token = cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
18014 if (token)
18015 end_loc = token->location;
18016 op = ARRAY_REF;
18017 consumed = true;
18018 break;
18019
18020 case CPP_UTF8STRING:
18021 case CPP_UTF8STRING_USERDEF:
18022 utf8 = true;
18023 /* FALLTHRU */
18024 case CPP_STRING:
18025 case CPP_WSTRING:
18026 case CPP_STRING16:
18027 case CPP_STRING32:
18028 case CPP_STRING_USERDEF:
18029 case CPP_WSTRING_USERDEF:
18030 case CPP_STRING16_USERDEF:
18031 case CPP_STRING32_USERDEF:
18032 {
18033 tree string_tree;
18034 int sz, len;
18035
18036 if (cxx_dialect == cxx98)
18037 maybe_warn_cpp0x (str: CPP0X_USER_DEFINED_LITERALS);
18038
18039 /* Consume the string. */
18040 cp_expr str = cp_parser_userdef_string_literal (parser,
18041 /*lookup_udlit=*/false);
18042 if (str == error_mark_node)
18043 return error_mark_node;
18044 else if (TREE_CODE (str) == USERDEF_LITERAL)
18045 {
18046 string_tree = USERDEF_LITERAL_VALUE (str.get_value ());
18047 id = USERDEF_LITERAL_SUFFIX_ID (str.get_value ());
18048 end_loc = str.get_location ();
18049 }
18050 else
18051 {
18052 string_tree = str;
18053 /* Look for the suffix identifier. */
18054 token = cp_lexer_peek_token (lexer: parser->lexer);
18055 if (token->type == CPP_NAME)
18056 {
18057 id = cp_parser_identifier (parser);
18058 end_loc = token->location;
18059 }
18060 else if (token->type == CPP_KEYWORD)
18061 {
18062 error ("unexpected keyword;"
18063 " remove space between quotes and suffix identifier");
18064 return error_mark_node;
18065 }
18066 else
18067 {
18068 error ("expected suffix identifier");
18069 return error_mark_node;
18070 }
18071 }
18072 sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
18073 (TREE_TYPE (TREE_TYPE (string_tree))));
18074 len = TREE_STRING_LENGTH (string_tree) / sz - 1;
18075 if (len != 0)
18076 {
18077 error ("expected empty string after %<operator%> keyword");
18078 return error_mark_node;
18079 }
18080 if (utf8 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string_tree)))
18081 != char_type_node)
18082 {
18083 error ("invalid encoding prefix in literal operator");
18084 return error_mark_node;
18085 }
18086 if (id != error_mark_node)
18087 {
18088 const char *name = IDENTIFIER_POINTER (id);
18089 id = cp_literal_operator_id (name);
18090 }
18091 /* Generate a location of the form:
18092 "" _suffix_identifier
18093 ^~~~~~~~~~~~~~~~~~~~~
18094 with caret == start at the start token, finish at the end of the
18095 suffix identifier. */
18096 location_t combined_loc
18097 = make_location (caret: start_loc, start: start_loc, lexer: parser->lexer);
18098 return cp_expr (id, combined_loc);
18099 }
18100
18101 default:
18102 /* Anything else is an error. */
18103 break;
18104 }
18105
18106 /* If we have selected an identifier, we need to consume the
18107 operator token. */
18108 if (op != ERROR_MARK)
18109 {
18110 id = ovl_op_identifier (isass: assop, code: op);
18111 if (!consumed)
18112 cp_lexer_consume_token (lexer: parser->lexer);
18113 }
18114 /* Otherwise, no valid operator name was present. */
18115 else
18116 {
18117 cp_parser_error (parser, gmsgid: "expected operator");
18118 id = error_mark_node;
18119 }
18120
18121 start_loc = make_location (caret: start_loc, start: start_loc, finish: get_finish (loc: end_loc));
18122 return cp_expr (id, start_loc);
18123}
18124
18125/* Parse a template-declaration.
18126
18127 template-declaration:
18128 export [opt] template < template-parameter-list > declaration
18129
18130 If MEMBER_P is TRUE, this template-declaration occurs within a
18131 class-specifier.
18132
18133 The grammar rule given by the standard isn't correct. What
18134 is really meant is:
18135
18136 template-declaration:
18137 export [opt] template-parameter-list-seq
18138 decl-specifier-seq [opt] init-declarator [opt] ;
18139 export [opt] template-parameter-list-seq
18140 function-definition
18141
18142 template-parameter-list-seq:
18143 template-parameter-list-seq [opt]
18144 template < template-parameter-list >
18145
18146 Concept Extensions:
18147
18148 template-parameter-list-seq:
18149 template < template-parameter-list > requires-clause [opt]
18150
18151 requires-clause:
18152 requires logical-or-expression */
18153
18154static void
18155cp_parser_template_declaration (cp_parser* parser, bool member_p)
18156{
18157 /* Check for `export'. */
18158 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_EXPORT))
18159 {
18160 /* Consume the `export' token. */
18161 cp_lexer_consume_token (lexer: parser->lexer);
18162 /* Warn that this use of export is deprecated. */
18163 if (cxx_dialect < cxx11)
18164 warning (0, "keyword %<export%> not implemented, and will be ignored");
18165 else if (cxx_dialect < cxx20)
18166 warning (0, "keyword %<export%> is deprecated, and is ignored");
18167 else
18168 warning (0, "keyword %<export%> is enabled with %<-fmodules-ts%>");
18169 }
18170
18171 cp_parser_template_declaration_after_export (parser, member_p);
18172}
18173
18174/* Parse a template-parameter-list.
18175
18176 template-parameter-list:
18177 template-parameter
18178 template-parameter-list , template-parameter
18179
18180 Returns a TREE_LIST. Each node represents a template parameter.
18181 The nodes are connected via their TREE_CHAINs. */
18182
18183static tree
18184cp_parser_template_parameter_list (cp_parser* parser)
18185{
18186 tree parameter_list = NULL_TREE;
18187
18188 /* Don't create wrapper nodes within a template-parameter-list,
18189 since we don't want to have different types based on the
18190 spelling location of constants and decls within them. */
18191 auto_suppress_location_wrappers sentinel;
18192
18193 begin_template_parm_list ();
18194
18195 /* The loop below parses the template parms. We first need to know
18196 the total number of template parms to be able to compute proper
18197 canonical types of each dependent type. So after the loop, when
18198 we know the total number of template parms,
18199 end_template_parm_list computes the proper canonical types and
18200 fixes up the dependent types accordingly. */
18201 while (true)
18202 {
18203 tree parameter;
18204 bool is_non_type;
18205 bool is_parameter_pack;
18206 location_t parm_loc;
18207
18208 /* Parse the template-parameter. */
18209 parm_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
18210 parameter = cp_parser_template_parameter (parser,
18211 &is_non_type,
18212 &is_parameter_pack);
18213 /* Add it to the list. */
18214 if (parameter != error_mark_node)
18215 parameter_list = process_template_parm (parameter_list,
18216 parm_loc,
18217 parameter,
18218 is_non_type,
18219 is_parameter_pack);
18220 else
18221 {
18222 tree err_parm = build_tree_list (parameter, parameter);
18223 parameter_list = chainon (parameter_list, err_parm);
18224 }
18225
18226 /* If the next token is not a `,', we're done. */
18227 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
18228 break;
18229 /* Otherwise, consume the `,' token. */
18230 cp_lexer_consume_token (lexer: parser->lexer);
18231 }
18232
18233 return end_template_parm_list (parameter_list);
18234}
18235
18236/* Parse a introduction-list.
18237
18238 introduction-list:
18239 introduced-parameter
18240 introduction-list , introduced-parameter
18241
18242 introduced-parameter:
18243 ...[opt] identifier
18244
18245 Returns a TREE_VEC of WILDCARD_DECLs. If the parameter is a pack
18246 then the introduced parm will have WILDCARD_PACK_P set. In addition, the
18247 WILDCARD_DECL will also have DECL_NAME set and token location in
18248 DECL_SOURCE_LOCATION. */
18249
18250static tree
18251cp_parser_introduction_list (cp_parser *parser)
18252{
18253 vec<tree, va_gc> *introduction_vec = make_tree_vector ();
18254
18255 while (true)
18256 {
18257 bool is_pack = cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS);
18258 if (is_pack)
18259 cp_lexer_consume_token (lexer: parser->lexer);
18260
18261 tree identifier = cp_parser_identifier (parser);
18262 if (identifier == error_mark_node)
18263 break;
18264
18265 /* Build placeholder. */
18266 tree parm = build_nt (WILDCARD_DECL);
18267 DECL_SOURCE_LOCATION (parm)
18268 = cp_lexer_peek_token (lexer: parser->lexer)->location;
18269 DECL_NAME (parm) = identifier;
18270 WILDCARD_PACK_P (parm) = is_pack;
18271 vec_safe_push (v&: introduction_vec, obj: parm);
18272
18273 /* If the next token is not a `,', we're done. */
18274 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
18275 break;
18276 /* Otherwise, consume the `,' token. */
18277 cp_lexer_consume_token (lexer: parser->lexer);
18278 }
18279
18280 /* Convert the vec into a TREE_VEC. */
18281 tree introduction_list = make_tree_vec (introduction_vec->length ());
18282 unsigned int n;
18283 tree parm;
18284 FOR_EACH_VEC_ELT (*introduction_vec, n, parm)
18285 TREE_VEC_ELT (introduction_list, n) = parm;
18286
18287 release_tree_vector (introduction_vec);
18288 return introduction_list;
18289}
18290
18291/* Given a declarator, get the declarator-id part, or NULL_TREE if this
18292 is an abstract declarator. */
18293
18294static inline cp_declarator*
18295get_id_declarator (cp_declarator *declarator)
18296{
18297 cp_declarator *d = declarator;
18298 while (d && d->kind != cdk_id)
18299 d = d->declarator;
18300 return d;
18301}
18302
18303/* Get the unqualified-id from the DECLARATOR or NULL_TREE if this
18304 is an abstract declarator. */
18305
18306static inline tree
18307get_unqualified_id (cp_declarator *declarator)
18308{
18309 declarator = get_id_declarator (declarator);
18310 if (declarator)
18311 return declarator->u.id.unqualified_name;
18312 else
18313 return NULL_TREE;
18314}
18315
18316/* Returns true if TYPE would declare a constrained constrained-parameter. */
18317
18318static inline bool
18319is_constrained_parameter (tree type)
18320{
18321 return (type
18322 && TREE_CODE (type) == TYPE_DECL
18323 && CONSTRAINED_PARM_CONCEPT (type)
18324 && DECL_P (CONSTRAINED_PARM_CONCEPT (type)));
18325}
18326
18327/* Returns true if PARM declares a constrained-parameter. */
18328
18329static inline bool
18330is_constrained_parameter (cp_parameter_declarator *parm)
18331{
18332 return is_constrained_parameter (type: parm->decl_specifiers.type);
18333}
18334
18335/* Check that the type parameter is only a declarator-id, and that its
18336 type is not cv-qualified. */
18337
18338bool
18339cp_parser_check_constrained_type_parm (cp_parser *parser,
18340 cp_parameter_declarator *parm)
18341{
18342 if (!parm->declarator)
18343 return true;
18344
18345 if (parm->declarator->kind != cdk_id)
18346 {
18347 cp_parser_error (parser, gmsgid: "invalid constrained type parameter");
18348 return false;
18349 }
18350
18351 /* Don't allow cv-qualified type parameters. */
18352 if (decl_spec_seq_has_spec_p (&parm->decl_specifiers, ds_const)
18353 || decl_spec_seq_has_spec_p (&parm->decl_specifiers, ds_volatile))
18354 {
18355 cp_parser_error (parser, gmsgid: "cv-qualified type parameter");
18356 return false;
18357 }
18358
18359 return true;
18360}
18361
18362/* Finish parsing/processing a template type parameter and checking
18363 various restrictions. */
18364
18365static inline tree
18366cp_parser_constrained_type_template_parm (cp_parser *parser,
18367 tree id,
18368 cp_parameter_declarator* parmdecl)
18369{
18370 if (cp_parser_check_constrained_type_parm (parser, parm: parmdecl))
18371 return finish_template_type_parm (class_type_node, id);
18372 else
18373 return error_mark_node;
18374}
18375
18376static tree
18377finish_constrained_template_template_parm (tree proto, tree id)
18378{
18379 /* FIXME: This should probably be copied, and we may need to adjust
18380 the template parameter depths. */
18381 tree saved_parms = current_template_parms;
18382 begin_template_parm_list ();
18383 current_template_parms = DECL_TEMPLATE_PARMS (proto);
18384 end_template_parm_list ();
18385
18386 tree parm = finish_template_template_parm (class_type_node, id);
18387 current_template_parms = saved_parms;
18388
18389 return parm;
18390}
18391
18392/* Finish parsing/processing a template template parameter by borrowing
18393 the template parameter list from the prototype parameter. */
18394
18395static tree
18396cp_parser_constrained_template_template_parm (cp_parser *parser,
18397 tree proto,
18398 tree id,
18399 cp_parameter_declarator *parmdecl)
18400{
18401 if (!cp_parser_check_constrained_type_parm (parser, parm: parmdecl))
18402 return error_mark_node;
18403 return finish_constrained_template_template_parm (proto, id);
18404}
18405
18406/* Create a new non-type template parameter from the given PARM
18407 declarator. */
18408
18409static tree
18410cp_parser_constrained_non_type_template_parm (bool *is_non_type,
18411 cp_parameter_declarator *parm)
18412{
18413 *is_non_type = true;
18414 cp_declarator *decl = parm->declarator;
18415 cp_decl_specifier_seq *specs = &parm->decl_specifiers;
18416 specs->type = TREE_TYPE (DECL_INITIAL (specs->type));
18417 return grokdeclarator (decl, specs, TPARM, 0, NULL);
18418}
18419
18420/* Build a constrained template parameter based on the PARMDECL
18421 declarator. The type of PARMDECL is the constrained type, which
18422 refers to the prototype template parameter that ultimately
18423 specifies the type of the declared parameter. */
18424
18425static tree
18426finish_constrained_parameter (cp_parser *parser,
18427 cp_parameter_declarator *parmdecl,
18428 bool *is_non_type)
18429{
18430 tree decl = parmdecl->decl_specifiers.type;
18431 tree id = get_unqualified_id (declarator: parmdecl->declarator);
18432 tree def = parmdecl->default_argument;
18433 tree proto = DECL_INITIAL (decl);
18434
18435 /* Build the parameter. Return an error if the declarator was invalid. */
18436 tree parm;
18437 if (TREE_CODE (proto) == TYPE_DECL)
18438 parm = cp_parser_constrained_type_template_parm (parser, id, parmdecl);
18439 else if (TREE_CODE (proto) == TEMPLATE_DECL)
18440 parm = cp_parser_constrained_template_template_parm (parser, proto, id,
18441 parmdecl);
18442 else
18443 parm = cp_parser_constrained_non_type_template_parm (is_non_type, parm: parmdecl);
18444 if (parm == error_mark_node)
18445 return error_mark_node;
18446
18447 /* Finish the parameter decl and create a node attaching the
18448 default argument and constraint. */
18449 parm = build_tree_list (def, parm);
18450 TEMPLATE_PARM_CONSTRAINTS (parm) = decl;
18451
18452 return parm;
18453}
18454
18455/* Returns true if the parsed type actually represents the declaration
18456 of a type template-parameter. */
18457
18458static bool
18459declares_constrained_type_template_parameter (tree type)
18460{
18461 return (is_constrained_parameter (type)
18462 && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TYPE_PARM);
18463}
18464
18465/* Returns true if the parsed type actually represents the declaration of
18466 a template template-parameter. */
18467
18468static bool
18469declares_constrained_template_template_parameter (tree type)
18470{
18471 return (is_constrained_parameter (type)
18472 && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TEMPLATE_PARM);
18473}
18474
18475/* Parse a default argument for a type template-parameter.
18476 Note that diagnostics are handled in cp_parser_template_parameter. */
18477
18478static tree
18479cp_parser_default_type_template_argument (cp_parser *parser)
18480{
18481 gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_EQ));
18482
18483 /* Consume the `=' token. */
18484 cp_lexer_consume_token (lexer: parser->lexer);
18485
18486 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
18487
18488 /* Tell cp_parser_lambda_expression this is a default argument. */
18489 auto lvf = make_temp_override (var&: parser->local_variables_forbidden_p);
18490 parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
18491
18492 /* Parse the default-argument. */
18493 push_deferring_access_checks (dk_no_deferred);
18494 tree default_argument = cp_parser_type_id (parser,
18495 CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
18496 NULL);
18497 pop_deferring_access_checks ();
18498
18499 if (flag_concepts && type_uses_auto (default_argument))
18500 {
18501 error_at (token->location,
18502 "invalid use of %<auto%> in default template argument");
18503 return error_mark_node;
18504 }
18505
18506 return default_argument;
18507}
18508
18509/* Parse a default argument for a template template-parameter. */
18510
18511static tree
18512cp_parser_default_template_template_argument (cp_parser *parser)
18513{
18514 gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_EQ));
18515
18516 bool is_template;
18517
18518 /* Consume the `='. */
18519 cp_lexer_consume_token (lexer: parser->lexer);
18520 /* Parse the id-expression. */
18521 push_deferring_access_checks (dk_no_deferred);
18522 /* save token before parsing the id-expression, for error
18523 reporting */
18524 const cp_token* token = cp_lexer_peek_token (lexer: parser->lexer);
18525 tree default_argument
18526 = cp_parser_id_expression (parser,
18527 /*template_keyword_p=*/false,
18528 /*check_dependency_p=*/true,
18529 /*template_p=*/&is_template,
18530 /*declarator_p=*/false,
18531 /*optional_p=*/false);
18532 if (TREE_CODE (default_argument) == TYPE_DECL)
18533 /* If the id-expression was a template-id that refers to
18534 a template-class, we already have the declaration here,
18535 so no further lookup is needed. */
18536 ;
18537 else
18538 /* Look up the name. */
18539 default_argument
18540 = cp_parser_lookup_name (parser, default_argument,
18541 none_type,
18542 /*is_template=*/is_template,
18543 /*is_namespace=*/false,
18544 /*check_dependency=*/true,
18545 /*ambiguous_decls=*/NULL,
18546 token->location);
18547 /* See if the default argument is valid. */
18548 default_argument = check_template_template_default_arg (default_argument);
18549 pop_deferring_access_checks ();
18550 return default_argument;
18551}
18552
18553/* Parse a template-parameter.
18554
18555 template-parameter:
18556 type-parameter
18557 parameter-declaration
18558
18559 If all goes well, returns a TREE_LIST. The TREE_VALUE represents
18560 the parameter. The TREE_PURPOSE is the default value, if any.
18561 Returns ERROR_MARK_NODE on failure. *IS_NON_TYPE is set to true
18562 iff this parameter is a non-type parameter. *IS_PARAMETER_PACK is
18563 set to true iff this parameter is a parameter pack. */
18564
18565static tree
18566cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
18567 bool *is_parameter_pack)
18568{
18569 cp_token *token;
18570 cp_parameter_declarator *parameter_declarator;
18571 tree parm;
18572
18573 /* Assume it is a type parameter or a template parameter. */
18574 *is_non_type = false;
18575 /* Assume it not a parameter pack. */
18576 *is_parameter_pack = false;
18577 /* Peek at the next token. */
18578 token = cp_lexer_peek_token (lexer: parser->lexer);
18579 /* If it is `template', we have a type-parameter. */
18580 if (token->keyword == RID_TEMPLATE)
18581 return cp_parser_type_parameter (parser, is_parameter_pack);
18582 /* If it is `class' or `typename' we do not know yet whether it is a
18583 type parameter or a non-type parameter. Consider:
18584
18585 template <typename T, typename T::X X> ...
18586
18587 or:
18588
18589 template <class C, class D*> ...
18590
18591 Here, the first parameter is a type parameter, and the second is
18592 a non-type parameter. We can tell by looking at the token after
18593 the identifier -- if it is a `,', `=', or `>' then we have a type
18594 parameter. */
18595 if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
18596 {
18597 /* Peek at the token after `class' or `typename'. */
18598 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
18599 /* If it's an ellipsis, we have a template type parameter
18600 pack. */
18601 if (token->type == CPP_ELLIPSIS)
18602 return cp_parser_type_parameter (parser, is_parameter_pack);
18603 /* If it's an identifier, skip it. */
18604 if (token->type == CPP_NAME)
18605 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3);
18606 /* Now, see if the token looks like the end of a template
18607 parameter. */
18608 if (token->type == CPP_COMMA
18609 || token->type == CPP_EQ
18610 || token->type == CPP_GREATER)
18611 return cp_parser_type_parameter (parser, is_parameter_pack);
18612 }
18613
18614 /* Otherwise, it is a non-type parameter or a constrained parameter.
18615
18616 [temp.param]
18617
18618 When parsing a default template-argument for a non-type
18619 template-parameter, the first non-nested `>' is taken as the end
18620 of the template parameter-list rather than a greater-than
18621 operator. */
18622 parameter_declarator
18623 = cp_parser_parameter_declaration (parser,
18624 CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
18625 /*template_parm_p=*/true,
18626 /*parenthesized_p=*/NULL);
18627
18628 if (!parameter_declarator)
18629 return error_mark_node;
18630
18631 /* If the parameter declaration is marked as a parameter pack, set
18632 *IS_PARAMETER_PACK to notify the caller. */
18633 if (parameter_declarator->template_parameter_pack_p)
18634 *is_parameter_pack = true;
18635
18636 if (parameter_declarator->default_argument)
18637 {
18638 /* Can happen in some cases of erroneous input (c++/34892). */
18639 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
18640 /* Consume the `...' for better error recovery. */
18641 cp_lexer_consume_token (lexer: parser->lexer);
18642 }
18643
18644 /* The parameter may have been constrained type parameter. */
18645 if (is_constrained_parameter (parm: parameter_declarator))
18646 return finish_constrained_parameter (parser,
18647 parmdecl: parameter_declarator,
18648 is_non_type);
18649
18650 // Now we're sure that the parameter is a non-type parameter.
18651 *is_non_type = true;
18652
18653 parm = grokdeclarator (parameter_declarator->declarator,
18654 &parameter_declarator->decl_specifiers,
18655 TPARM, /*initialized=*/0,
18656 /*attrlist=*/NULL);
18657 if (parm == error_mark_node)
18658 return error_mark_node;
18659
18660 return build_tree_list (parameter_declarator->default_argument, parm);
18661}
18662
18663/* Parse a type-parameter.
18664
18665 type-parameter:
18666 class identifier [opt]
18667 class identifier [opt] = type-id
18668 typename identifier [opt]
18669 typename identifier [opt] = type-id
18670 template < template-parameter-list > class identifier [opt]
18671 template < template-parameter-list > class identifier [opt]
18672 = id-expression
18673
18674 GNU Extension (variadic templates):
18675
18676 type-parameter:
18677 class ... identifier [opt]
18678 typename ... identifier [opt]
18679
18680 Returns a TREE_LIST. The TREE_VALUE is itself a TREE_LIST. The
18681 TREE_PURPOSE is the default-argument, if any. The TREE_VALUE is
18682 the declaration of the parameter.
18683
18684 Sets *IS_PARAMETER_PACK if this is a template parameter pack. */
18685
18686static tree
18687cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
18688{
18689 cp_token *token;
18690 tree parameter;
18691
18692 /* Look for a keyword to tell us what kind of parameter this is. */
18693 token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_TYPENAME_TEMPLATE);
18694 if (!token)
18695 return error_mark_node;
18696
18697 switch (token->keyword)
18698 {
18699 case RID_CLASS:
18700 case RID_TYPENAME:
18701 {
18702 tree identifier;
18703 tree default_argument;
18704
18705 /* If the next token is an ellipsis, we have a template
18706 argument pack. */
18707 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
18708 {
18709 /* Consume the `...' token. */
18710 cp_lexer_consume_token (lexer: parser->lexer);
18711 maybe_warn_variadic_templates ();
18712
18713 *is_parameter_pack = true;
18714 }
18715
18716 /* If the next token is an identifier, then it names the
18717 parameter. */
18718 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
18719 identifier = cp_parser_identifier (parser);
18720 else
18721 identifier = NULL_TREE;
18722
18723 /* Create the parameter. */
18724 parameter = finish_template_type_parm (class_type_node, identifier);
18725
18726 /* If the next token is an `=', we have a default argument. */
18727 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
18728 {
18729 default_argument
18730 = cp_parser_default_type_template_argument (parser);
18731
18732 /* Template parameter packs cannot have default
18733 arguments. */
18734 if (*is_parameter_pack)
18735 {
18736 if (identifier)
18737 error_at (token->location,
18738 "template parameter pack %qD cannot have a "
18739 "default argument", identifier);
18740 else
18741 error_at (token->location,
18742 "template parameter packs cannot have "
18743 "default arguments");
18744 default_argument = NULL_TREE;
18745 }
18746 else if (check_for_bare_parameter_packs (default_argument))
18747 default_argument = error_mark_node;
18748 }
18749 else
18750 default_argument = NULL_TREE;
18751
18752 /* Create the combined representation of the parameter and the
18753 default argument. */
18754 parameter = build_tree_list (default_argument, parameter);
18755 }
18756 break;
18757
18758 case RID_TEMPLATE:
18759 {
18760 tree identifier;
18761 tree default_argument;
18762
18763 /* Look for the `<'. */
18764 cp_parser_require (parser, CPP_LESS, RT_LESS);
18765 /* Parse the template-parameter-list. */
18766 cp_parser_template_parameter_list (parser);
18767 /* Look for the `>'. */
18768 cp_parser_require (parser, CPP_GREATER, RT_GREATER);
18769
18770 /* If template requirements are present, parse them. */
18771 if (flag_concepts)
18772 {
18773 tree reqs = get_shorthand_constraints (current_template_parms);
18774 if (tree dreqs = cp_parser_requires_clause_opt (parser, false))
18775 reqs = combine_constraint_expressions (reqs, dreqs);
18776 TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
18777 }
18778
18779 /* Look for the `class' or 'typename' keywords. */
18780 cp_parser_type_parameter_key (parser);
18781 /* If the next token is an ellipsis, we have a template
18782 argument pack. */
18783 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
18784 {
18785 /* Consume the `...' token. */
18786 cp_lexer_consume_token (lexer: parser->lexer);
18787 maybe_warn_variadic_templates ();
18788
18789 *is_parameter_pack = true;
18790 }
18791 /* If the next token is an `=', then there is a
18792 default-argument. If the next token is a `>', we are at
18793 the end of the parameter-list. If the next token is a `,',
18794 then we are at the end of this parameter. */
18795 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_EQ)
18796 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_GREATER)
18797 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
18798 {
18799 identifier = cp_parser_identifier (parser);
18800 /* Treat invalid names as if the parameter were nameless. */
18801 if (identifier == error_mark_node)
18802 identifier = NULL_TREE;
18803 }
18804 else
18805 identifier = NULL_TREE;
18806
18807 /* Create the template parameter. */
18808 parameter = finish_template_template_parm (class_type_node,
18809 identifier);
18810
18811 /* If the next token is an `=', then there is a
18812 default-argument. */
18813 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
18814 {
18815 default_argument
18816 = cp_parser_default_template_template_argument (parser);
18817
18818 /* Template parameter packs cannot have default
18819 arguments. */
18820 if (*is_parameter_pack)
18821 {
18822 if (identifier)
18823 error_at (token->location,
18824 "template parameter pack %qD cannot "
18825 "have a default argument",
18826 identifier);
18827 else
18828 error_at (token->location, "template parameter packs cannot "
18829 "have default arguments");
18830 default_argument = NULL_TREE;
18831 }
18832 }
18833 else
18834 default_argument = NULL_TREE;
18835
18836 /* Create the combined representation of the parameter and the
18837 default argument. */
18838 parameter = build_tree_list (default_argument, parameter);
18839 }
18840 break;
18841
18842 default:
18843 gcc_unreachable ();
18844 break;
18845 }
18846
18847 return parameter;
18848}
18849
18850/* Parse a template-id.
18851
18852 template-id:
18853 template-name < template-argument-list [opt] >
18854
18855 If TEMPLATE_KEYWORD_P is TRUE, then we have just seen the
18856 `template' keyword. In this case, a TEMPLATE_ID_EXPR will be
18857 returned. Otherwise, if the template-name names a function, or set
18858 of functions, returns a TEMPLATE_ID_EXPR. If the template-name
18859 names a class, returns a TYPE_DECL for the specialization.
18860
18861 If CHECK_DEPENDENCY_P is FALSE, names are looked up in
18862 uninstantiated templates. */
18863
18864static tree
18865cp_parser_template_id (cp_parser *parser,
18866 bool template_keyword_p,
18867 bool check_dependency_p,
18868 enum tag_types tag_type,
18869 bool is_declaration)
18870{
18871 tree templ;
18872 tree arguments;
18873 tree template_id;
18874 cp_token_position start_of_id = 0;
18875 cp_token *next_token = NULL, *next_token_2 = NULL;
18876 bool is_identifier;
18877
18878 /* If the next token corresponds to a template-id, there is no need
18879 to reparse it. */
18880 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
18881
18882 if (token->type == CPP_TEMPLATE_ID)
18883 {
18884 cp_lexer_consume_token (lexer: parser->lexer);
18885 return saved_checks_value (check_value: token->u.tree_check_value);
18886 }
18887
18888 /* Avoid performing name lookup if there is no possibility of
18889 finding a template-id. */
18890 if ((token->type != CPP_NAME && token->keyword != RID_OPERATOR)
18891 || (token->type == CPP_NAME
18892 && !cp_parser_nth_token_starts_template_argument_list_p
18893 (parser, 2)))
18894 {
18895 cp_parser_error (parser, gmsgid: "expected template-id");
18896 return error_mark_node;
18897 }
18898
18899 /* Remember where the template-id starts. */
18900 if (cp_parser_uncommitted_to_tentative_parse_p (parser))
18901 start_of_id = cp_lexer_token_position (lexer: parser->lexer, previous_p: false);
18902
18903 push_deferring_access_checks (dk_deferred);
18904
18905 /* Parse the template-name. */
18906 is_identifier = false;
18907 templ = cp_parser_template_name (parser, template_keyword_p,
18908 check_dependency_p,
18909 is_declaration,
18910 tag_type,
18911 &is_identifier);
18912
18913 /* Push any access checks inside the firewall we're about to create. */
18914 vec<deferred_access_check, va_gc> *checks = get_deferred_access_checks ();
18915 pop_deferring_access_checks ();
18916 if (templ == error_mark_node || is_identifier)
18917 return templ;
18918
18919 /* Since we're going to preserve any side-effects from this parse, set up a
18920 firewall to protect our callers from cp_parser_commit_to_tentative_parse
18921 in the template arguments. */
18922 tentative_firewall firewall (parser);
18923 reopen_deferring_access_checks (checks);
18924
18925 /* If we find the sequence `[:' after a template-name, it's probably
18926 a digraph-typo for `< ::'. Substitute the tokens and check if we can
18927 parse correctly the argument list. */
18928 if (((next_token = cp_lexer_peek_token (lexer: parser->lexer))->type
18929 == CPP_OPEN_SQUARE)
18930 && next_token->flags & DIGRAPH
18931 && ((next_token_2 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2))->type
18932 == CPP_COLON)
18933 && !(next_token_2->flags & PREV_WHITE))
18934 {
18935 cp_parser_parse_tentatively (parser);
18936 /* Change `:' into `::'. */
18937 next_token_2->type = CPP_SCOPE;
18938 /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is
18939 CPP_LESS. */
18940 cp_lexer_consume_token (lexer: parser->lexer);
18941
18942 /* Parse the arguments. */
18943 arguments = cp_parser_enclosed_template_argument_list (parser);
18944 if (!cp_parser_parse_definitely (parser))
18945 {
18946 /* If we couldn't parse an argument list, then we revert our changes
18947 and return simply an error. Maybe this is not a template-id
18948 after all. */
18949 next_token_2->type = CPP_COLON;
18950 cp_parser_error (parser, gmsgid: "expected %<<%>");
18951 pop_deferring_access_checks ();
18952 return error_mark_node;
18953 }
18954 /* Otherwise, emit an error about the invalid digraph, but continue
18955 parsing because we got our argument list. */
18956 if (permerror (next_token->location,
18957 "%<<::%> cannot begin a template-argument list"))
18958 {
18959 static bool hint = false;
18960 inform (next_token->location,
18961 "%<<:%> is an alternate spelling for %<[%>."
18962 " Insert whitespace between %<<%> and %<::%>");
18963 if (!hint && !flag_permissive)
18964 {
18965 inform (next_token->location, "(if you use %<-fpermissive%> "
18966 "or %<-std=c++11%>, or %<-std=gnu++11%> G++ will "
18967 "accept your code)");
18968 hint = true;
18969 }
18970 }
18971 }
18972 else
18973 {
18974 /* Look for the `<' that starts the template-argument-list. */
18975 if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
18976 {
18977 pop_deferring_access_checks ();
18978 return error_mark_node;
18979 }
18980 /* Parse the arguments. */
18981 arguments = cp_parser_enclosed_template_argument_list (parser);
18982
18983 if ((cxx_dialect > cxx17)
18984 && (TREE_CODE (templ) == FUNCTION_DECL || identifier_p (t: templ))
18985 && !template_keyword_p
18986 && (cp_parser_error_occurred (parser)
18987 || cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_PAREN)))
18988 {
18989 /* This didn't go well. */
18990 if (TREE_CODE (templ) == FUNCTION_DECL)
18991 {
18992 /* C++20 says that "function-name < a;" is now ill-formed. */
18993 if (cp_parser_error_occurred (parser))
18994 {
18995 error_at (token->location, "invalid template-argument-list");
18996 inform (token->location, "function name as the left hand "
18997 "operand of %<<%> is ill-formed in C++20; wrap the "
18998 "function name in %<()%>");
18999 }
19000 else
19001 /* We expect "f<targs>" to be followed by "(args)". */
19002 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
19003 "expected %<(%> after template-argument-list");
19004 if (start_of_id)
19005 /* Purge all subsequent tokens. */
19006 cp_lexer_purge_tokens_after (lexer: parser->lexer, tok: start_of_id);
19007 }
19008 else
19009 cp_parser_simulate_error (parser);
19010 pop_deferring_access_checks ();
19011 return error_mark_node;
19012 }
19013 }
19014
19015 /* Set the location to be of the form:
19016 template-name < template-argument-list [opt] >
19017 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19018 with caret == start at the start of the template-name,
19019 ranging until the closing '>'. */
19020 location_t combined_loc
19021 = make_location (caret: token->location, start: token->location, lexer: parser->lexer);
19022
19023 /* Check for concepts autos where they don't belong. We could
19024 identify types in some cases of identifier TEMPL, looking ahead
19025 for a CPP_SCOPE, but that would buy us nothing: we accept auto in
19026 types. We reject them in functions, but if what we have is an
19027 identifier, even with none_type we can't conclude it's NOT a
19028 type, we have to wait for template substitution. */
19029 if (flag_concepts && check_auto_in_tmpl_args (templ, arguments))
19030 template_id = error_mark_node;
19031 /* Build a representation of the specialization. */
19032 else if (identifier_p (t: templ))
19033 template_id = build_min_nt_loc (combined_loc,
19034 TEMPLATE_ID_EXPR,
19035 templ, arguments);
19036 else if (DECL_TYPE_TEMPLATE_P (templ)
19037 || DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
19038 {
19039 /* In "template <typename T> ... A<T>::", A<T> is the abstract A
19040 template (rather than some instantiation thereof) only if
19041 is not nested within some other construct. For example, in
19042 "template <typename T> void f(T) { A<T>::", A<T> is just an
19043 instantiation of A. */
19044 bool entering_scope
19045 = (template_parm_scope_p ()
19046 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE));
19047 template_id
19048 = finish_template_type (templ, arguments, entering_scope);
19049 }
19050 else if (concept_definition_p (t: templ))
19051 {
19052 /* The caller will decide whether this is a concept check or type
19053 constraint. */
19054 template_id = build2_loc (loc: combined_loc, code: TEMPLATE_ID_EXPR,
19055 boolean_type_node, arg0: templ, arg1: arguments);
19056 }
19057 else if (variable_template_p (t: templ))
19058 {
19059 template_id = lookup_template_variable (templ, arguments, tf_warning_or_error);
19060 if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
19061 SET_EXPR_LOCATION (template_id, combined_loc);
19062 }
19063 else if (TREE_CODE (templ) == TYPE_DECL
19064 && TREE_CODE (TREE_TYPE (templ)) == TYPENAME_TYPE)
19065 {
19066 /* Some type template in dependent scope. */
19067 tree &name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (templ));
19068 name = build_min_nt_loc (combined_loc,
19069 TEMPLATE_ID_EXPR,
19070 name, arguments);
19071 template_id = templ;
19072 }
19073 else
19074 {
19075 /* If it's not a class-template or a template-template, it should be
19076 a function-template. */
19077 gcc_assert (OVL_P (templ) || BASELINK_P (templ));
19078
19079 template_id = lookup_template_function (templ, arguments);
19080 if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
19081 SET_EXPR_LOCATION (template_id, combined_loc);
19082 }
19083
19084 /* If parsing tentatively, replace the sequence of tokens that makes
19085 up the template-id with a CPP_TEMPLATE_ID token. That way,
19086 should we re-parse the token stream, we will not have to repeat
19087 the effort required to do the parse, nor will we issue duplicate
19088 error messages about problems during instantiation of the
19089 template. */
19090 if (start_of_id
19091 /* Don't do this if we had a parse error in a declarator; re-parsing
19092 might succeed if a name changes meaning (60361). */
19093 && !(cp_parser_error_occurred (parser)
19094 && cp_parser_parsing_tentatively (parser)
19095 && parser->in_declarator_p))
19096 {
19097 /* Reset the contents of the START_OF_ID token. */
19098 token->type = CPP_TEMPLATE_ID;
19099 token->location = combined_loc;
19100
19101 /* Retrieve any deferred checks. Do not pop this access checks yet
19102 so the memory will not be reclaimed during token replacing below. */
19103 token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
19104 token->tree_check_p = true;
19105 token->u.tree_check_value->value = template_id;
19106 token->u.tree_check_value->checks = get_deferred_access_checks ();
19107 token->keyword = RID_MAX;
19108
19109 /* Purge all subsequent tokens. */
19110 cp_lexer_purge_tokens_after (lexer: parser->lexer, tok: start_of_id);
19111
19112 /* ??? Can we actually assume that, if template_id ==
19113 error_mark_node, we will have issued a diagnostic to the
19114 user, as opposed to simply marking the tentative parse as
19115 failed? */
19116 if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
19117 error_at (token->location, "parse error in template argument list");
19118 }
19119
19120 pop_to_parent_deferring_access_checks ();
19121 return template_id;
19122}
19123
19124/* Like cp_parser_template_id, called in non-type context. */
19125
19126static tree
19127cp_parser_template_id_expr (cp_parser *parser,
19128 bool template_keyword_p,
19129 bool check_dependency_p,
19130 bool is_declaration)
19131{
19132 tree x = cp_parser_template_id (parser, template_keyword_p, check_dependency_p,
19133 tag_type: none_type, is_declaration);
19134 if (TREE_CODE (x) == TEMPLATE_ID_EXPR
19135 && concept_check_p (t: x))
19136 /* We didn't check the arguments in cp_parser_template_id; do that now. */
19137 return build_concept_id (x);
19138 return x;
19139}
19140
19141/* Parse a template-name.
19142
19143 template-name:
19144 identifier
19145
19146 The standard should actually say:
19147
19148 template-name:
19149 identifier
19150 operator-function-id
19151
19152 A defect report has been filed about this issue.
19153
19154 A conversion-function-id cannot be a template name because they cannot
19155 be part of a template-id. In fact, looking at this code:
19156
19157 a.operator K<int>()
19158
19159 the conversion-function-id is "operator K<int>", and K<int> is a type-id.
19160 It is impossible to call a templated conversion-function-id with an
19161 explicit argument list, since the only allowed template parameter is
19162 the type to which it is converting.
19163
19164 If TEMPLATE_KEYWORD_P is true, then we have just seen the
19165 `template' keyword, in a construction like:
19166
19167 T::template f<3>()
19168
19169 In that case `f' is taken to be a template-name, even though there
19170 is no way of knowing for sure.
19171
19172 Returns the TEMPLATE_DECL for the template, or an OVERLOAD if the
19173 name refers to a set of overloaded functions, at least one of which
19174 is a template, or an IDENTIFIER_NODE with the name of the template,
19175 if TEMPLATE_KEYWORD_P is true. If CHECK_DEPENDENCY_P is FALSE,
19176 names are looked up inside uninstantiated templates. */
19177
19178static tree
19179cp_parser_template_name (cp_parser* parser,
19180 bool template_keyword_p,
19181 bool check_dependency_p,
19182 bool is_declaration,
19183 enum tag_types tag_type,
19184 bool *is_identifier)
19185{
19186 tree identifier;
19187 tree decl;
19188 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
19189
19190 /* If the next token is `operator', then we have either an
19191 operator-function-id or a conversion-function-id. */
19192 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_OPERATOR))
19193 {
19194 /* We don't know whether we're looking at an
19195 operator-function-id or a conversion-function-id. */
19196 cp_parser_parse_tentatively (parser);
19197 /* Try an operator-function-id. */
19198 identifier = cp_parser_operator_function_id (parser);
19199 /* If that didn't work, try a conversion-function-id. */
19200 if (!cp_parser_parse_definitely (parser))
19201 {
19202 cp_parser_error (parser, gmsgid: "expected template-name");
19203 return error_mark_node;
19204 }
19205 }
19206 /* Look for the identifier. */
19207 else
19208 identifier = cp_parser_identifier (parser);
19209
19210 /* If we didn't find an identifier, we don't have a template-id. */
19211 if (identifier == error_mark_node)
19212 return error_mark_node;
19213
19214 /* If the name immediately followed the `template' keyword, then it
19215 is a template-name. However, if the next token is not `<', then
19216 we do not treat it as a template-name, since it is not being used
19217 as part of a template-id. This enables us to handle constructs
19218 like:
19219
19220 template <typename T> struct S { S(); };
19221 template <typename T> S<T>::S();
19222
19223 correctly. We would treat `S' as a template -- if it were `S<T>'
19224 -- but we do not if there is no `<'. */
19225
19226 if (processing_template_decl
19227 && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
19228 {
19229 /* In a declaration, in a dependent context, we pretend that the
19230 "template" keyword was present in order to improve error
19231 recovery. For example, given:
19232
19233 template <typename T> void f(T::X<int>);
19234
19235 we want to treat "X<int>" as a template-id. */
19236 if (is_declaration
19237 && !template_keyword_p
19238 && parser->scope && TYPE_P (parser->scope)
19239 && check_dependency_p
19240 && dependent_scope_p (parser->scope)
19241 /* Do not do this for dtors (or ctors), since they never
19242 need the template keyword before their name. */
19243 && !constructor_name_p (identifier, parser->scope))
19244 {
19245 cp_token_position start = 0;
19246
19247 /* Explain what went wrong. */
19248 error_at (token->location, "non-template %qD used as template",
19249 identifier);
19250 inform (token->location, "use %<%T::template %D%> to indicate that it is a template",
19251 parser->scope, identifier);
19252 /* If parsing tentatively, find the location of the "<" token. */
19253 if (cp_parser_simulate_error (parser))
19254 start = cp_lexer_token_position (lexer: parser->lexer, previous_p: true);
19255 /* Parse the template arguments so that we can issue error
19256 messages about them. */
19257 cp_lexer_consume_token (lexer: parser->lexer);
19258 cp_parser_enclosed_template_argument_list (parser);
19259 /* Skip tokens until we find a good place from which to
19260 continue parsing. */
19261 cp_parser_skip_to_closing_parenthesis (parser,
19262 /*recovering=*/true,
19263 /*or_comma=*/true,
19264 /*consume_paren=*/false);
19265 /* If parsing tentatively, permanently remove the
19266 template argument list. That will prevent duplicate
19267 error messages from being issued about the missing
19268 "template" keyword. */
19269 if (start)
19270 cp_lexer_purge_tokens_after (lexer: parser->lexer, tok: start);
19271 if (is_identifier)
19272 *is_identifier = true;
19273 parser->context->object_type = NULL_TREE;
19274 return identifier;
19275 }
19276
19277 /* If the "template" keyword is present, then there is generally
19278 no point in doing name-lookup, so we just return IDENTIFIER.
19279 But, if the qualifying scope is non-dependent then we can
19280 (and must) do name-lookup normally. */
19281 if (template_keyword_p)
19282 {
19283 tree scope = (parser->scope ? parser->scope
19284 : parser->context->object_type);
19285 if (scope && TYPE_P (scope)
19286 && (!CLASS_TYPE_P (scope)
19287 || (check_dependency_p && dependent_scope_p (scope))))
19288 {
19289 /* We're optimizing away the call to cp_parser_lookup_name, but
19290 we still need to do this. */
19291 parser->object_scope = parser->context->object_type;
19292 parser->context->object_type = NULL_TREE;
19293 return identifier;
19294 }
19295 }
19296 }
19297
19298 /* cp_parser_lookup_name clears OBJECT_TYPE. */
19299 tree scope = (parser->scope ? parser->scope
19300 : parser->context->object_type);
19301
19302 /* Look up the name. */
19303 decl = cp_parser_lookup_name (parser, identifier,
19304 tag_type,
19305 /*is_template=*/1 + template_keyword_p,
19306 /*is_namespace=*/false,
19307 check_dependency_p,
19308 /*ambiguous_decls=*/NULL,
19309 token->location);
19310
19311 decl = strip_using_decl (decl);
19312
19313 /* 13.3 [temp.names] A < is interpreted as the delimiter of a
19314 template-argument-list if it follows a name that is not a
19315 conversion-function-id and
19316 - that follows the keyword template or a ~ after a nested-name-specifier or
19317 in a class member access expression, or
19318 - for which name lookup finds the injected-class-name of a class template
19319 or finds any declaration of a template, or
19320 - that is an unqualified name for which name lookup either finds one or
19321 more functions or finds nothing, or
19322 - that is a terminal name in a using-declarator (9.9), in a declarator-id
19323 (9.3.4), or in a type-only context other than a nested-name-specifier
19324 (13.8). */
19325
19326 /* Handle injected-class-name. */
19327 decl = maybe_get_template_decl_from_type_decl (decl);
19328
19329 /* If DECL is a template, then the name was a template-name. */
19330 if (TREE_CODE (decl) == TEMPLATE_DECL)
19331 {
19332 if ((TREE_DEPRECATED (decl) || TREE_UNAVAILABLE (decl))
19333 && deprecated_state != UNAVAILABLE_DEPRECATED_SUPPRESS)
19334 {
19335 tree d = DECL_TEMPLATE_RESULT (decl);
19336 tree attr;
19337 if (TREE_CODE (d) == TYPE_DECL)
19338 attr = TYPE_ATTRIBUTES (TREE_TYPE (d));
19339 else
19340 attr = DECL_ATTRIBUTES (d);
19341 if (TREE_UNAVAILABLE (decl))
19342 {
19343 attr = lookup_attribute (attr_name: "unavailable", list: attr);
19344 error_unavailable_use (decl, attr);
19345 }
19346 else if (TREE_DEPRECATED (decl)
19347 && deprecated_state != DEPRECATED_SUPPRESS)
19348 {
19349 attr = lookup_attribute (attr_name: "deprecated", list: attr);
19350 warn_deprecated_use (decl, attr);
19351 }
19352 }
19353 }
19354 else
19355 {
19356 /* Look through an overload set for any templates. */
19357 bool found = false;
19358
19359 for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
19360 !found && iter; ++iter)
19361 if (TREE_CODE (*iter) == TEMPLATE_DECL)
19362 found = true;
19363
19364 /* "an unqualified name for which name lookup either finds one or more
19365 functions or finds nothing". */
19366 if (!found
19367 && (cxx_dialect > cxx17)
19368 && !scope
19369 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_LESS)
19370 && tag_type == none_type)
19371 {
19372 /* The "more functions" case. Just use the OVERLOAD as normally.
19373 We don't use is_overloaded_fn here to avoid considering
19374 BASELINKs. */
19375 if (TREE_CODE (decl) == OVERLOAD
19376 /* Name lookup found one function. */
19377 || TREE_CODE (decl) == FUNCTION_DECL
19378 /* Name lookup found nothing. */
19379 || decl == error_mark_node)
19380 found = true;
19381 }
19382
19383 /* "that follows the keyword template"..."in a type-only context" */
19384 if (!found && scope
19385 && (template_keyword_p || tag_type != none_type)
19386 && dependentish_scope_p (scope)
19387 && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
19388 found = true;
19389
19390 if (!found)
19391 {
19392 /* The name does not name a template. */
19393 cp_parser_error (parser, gmsgid: "expected template-name");
19394 return error_mark_node;
19395 }
19396 else if ((!DECL_P (decl) && !is_overloaded_fn (decl))
19397 || TREE_CODE (decl) == USING_DECL
19398 /* cp_parser_template_id can only handle some TYPE_DECLs. */
19399 || (TREE_CODE (decl) == TYPE_DECL
19400 && TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE))
19401 /* Repeat the lookup at instantiation time. */
19402 decl = identifier;
19403 }
19404
19405 return decl;
19406}
19407
19408/* Parse a template-argument-list.
19409
19410 template-argument-list:
19411 template-argument ... [opt]
19412 template-argument-list , template-argument ... [opt]
19413
19414 Returns a TREE_VEC containing the arguments. */
19415
19416static tree
19417cp_parser_template_argument_list (cp_parser* parser)
19418{
19419 bool saved_in_template_argument_list_p;
19420 bool saved_ice_p;
19421 bool saved_non_ice_p;
19422
19423 /* Don't create location wrapper nodes within a template-argument-list. */
19424 auto_suppress_location_wrappers sentinel;
19425
19426 saved_in_template_argument_list_p = parser->in_template_argument_list_p;
19427 parser->in_template_argument_list_p = true;
19428 /* Even if the template-id appears in an integral
19429 constant-expression, the contents of the argument list do
19430 not. */
19431 saved_ice_p = parser->integral_constant_expression_p;
19432 parser->integral_constant_expression_p = false;
19433 saved_non_ice_p = parser->non_integral_constant_expression_p;
19434 parser->non_integral_constant_expression_p = false;
19435
19436 /* Parse the arguments. */
19437 auto_vec<tree, 10> args;
19438 do
19439 {
19440 if (!args.is_empty ())
19441 /* Consume the comma. */
19442 cp_lexer_consume_token (lexer: parser->lexer);
19443
19444 /* Parse the template-argument. */
19445 tree argument = cp_parser_template_argument (parser);
19446
19447 /* If the next token is an ellipsis, we're expanding a template
19448 argument pack. */
19449 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
19450 {
19451 if (argument == error_mark_node)
19452 {
19453 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
19454 error_at (token->location,
19455 "expected parameter pack before %<...%>");
19456 }
19457 /* Consume the `...' token. */
19458 cp_lexer_consume_token (lexer: parser->lexer);
19459
19460 /* Make the argument into a TYPE_PACK_EXPANSION or
19461 EXPR_PACK_EXPANSION. */
19462 argument = make_pack_expansion (argument);
19463 }
19464
19465 args.safe_push (obj: argument);
19466 }
19467 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA));
19468
19469 int n_args = args.length ();
19470 tree vec = make_tree_vec (n_args);
19471
19472 for (int i = 0; i < n_args; i++)
19473 TREE_VEC_ELT (vec, i) = args[i];
19474
19475 parser->non_integral_constant_expression_p = saved_non_ice_p;
19476 parser->integral_constant_expression_p = saved_ice_p;
19477 parser->in_template_argument_list_p = saved_in_template_argument_list_p;
19478 if (CHECKING_P)
19479 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
19480 return vec;
19481}
19482
19483/* Parse a template-argument.
19484
19485 template-argument:
19486 assignment-expression
19487 type-id
19488 id-expression
19489
19490 The representation is that of an assignment-expression, type-id, or
19491 id-expression -- except that the qualified id-expression is
19492 evaluated, so that the value returned is either a DECL or an
19493 OVERLOAD.
19494
19495 Although the standard says "assignment-expression", it forbids
19496 throw-expressions or assignments in the template argument.
19497 Therefore, we use "conditional-expression" instead. */
19498
19499static tree
19500cp_parser_template_argument (cp_parser* parser)
19501{
19502 tree argument;
19503 bool template_p;
19504 bool address_p;
19505 bool maybe_type_id = false;
19506 cp_token *token = NULL, *argument_start_token = NULL;
19507 location_t loc = 0;
19508 cp_id_kind idk;
19509
19510 /* There's really no way to know what we're looking at, so we just
19511 try each alternative in order.
19512
19513 [temp.arg]
19514
19515 In a template-argument, an ambiguity between a type-id and an
19516 expression is resolved to a type-id, regardless of the form of
19517 the corresponding template-parameter.
19518
19519 Therefore, we try a type-id first. */
19520 cp_parser_parse_tentatively (parser);
19521 argument = cp_parser_template_type_arg (parser);
19522 /* If there was no error parsing the type-id but the next token is a
19523 '>>', our behavior depends on which dialect of C++ we're
19524 parsing. In C++98, we probably found a typo for '> >'. But there
19525 are type-id which are also valid expressions. For instance:
19526
19527 struct X { int operator >> (int); };
19528 template <int V> struct Foo {};
19529 Foo<X () >> 5> r;
19530
19531 Here 'X()' is a valid type-id of a function type, but the user just
19532 wanted to write the expression "X() >> 5". Thus, we remember that we
19533 found a valid type-id, but we still try to parse the argument as an
19534 expression to see what happens.
19535
19536 In C++0x, the '>>' will be considered two separate '>'
19537 tokens. */
19538 if (!cp_parser_error_occurred (parser)
19539 && ((cxx_dialect == cxx98
19540 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_RSHIFT))
19541 /* Similarly for >= which
19542 cp_parser_next_token_ends_template_argument_p treats for
19543 diagnostics purposes as mistyped > =, but can be valid
19544 after a type-id. */
19545 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_GREATER_EQ)))
19546 {
19547 maybe_type_id = true;
19548 cp_parser_abort_tentative_parse (parser);
19549 }
19550 else
19551 {
19552 /* If the next token isn't a `,' or a `>', then this argument wasn't
19553 really finished. This means that the argument is not a valid
19554 type-id. */
19555 if (!cp_parser_next_token_ends_template_argument_p (parser))
19556 cp_parser_error (parser, gmsgid: "expected template-argument");
19557 /* If that worked, we're done. */
19558 if (cp_parser_parse_definitely (parser))
19559 return argument;
19560 }
19561 /* We're still not sure what the argument will be. */
19562 cp_parser_parse_tentatively (parser);
19563 /* Try a template. */
19564 argument_start_token = cp_lexer_peek_token (lexer: parser->lexer);
19565 argument = cp_parser_id_expression (parser,
19566 /*template_keyword_p=*/false,
19567 /*check_dependency_p=*/true,
19568 template_p: &template_p,
19569 /*declarator_p=*/false,
19570 /*optional_p=*/false);
19571 /* If the next token isn't a `,' or a `>', then this argument wasn't
19572 really finished. */
19573 if (!cp_parser_next_token_ends_template_argument_p (parser))
19574 cp_parser_error (parser, gmsgid: "expected template-argument");
19575 if (!cp_parser_error_occurred (parser))
19576 {
19577 /* Figure out what is being referred to. If the id-expression
19578 was for a class template specialization, then we will have a
19579 TYPE_DECL at this point. There is no need to do name lookup
19580 at this point in that case. */
19581 if (TREE_CODE (argument) != TYPE_DECL)
19582 argument = cp_parser_lookup_name (parser, argument,
19583 none_type,
19584 /*is_template=*/template_p,
19585 /*is_namespace=*/false,
19586 /*check_dependency=*/true,
19587 /*ambiguous_decls=*/NULL,
19588 argument_start_token->location);
19589 if (TREE_CODE (argument) != TEMPLATE_DECL
19590 && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
19591 cp_parser_error (parser, gmsgid: "expected template-name");
19592 }
19593 if (cp_parser_parse_definitely (parser))
19594 {
19595 if (TREE_UNAVAILABLE (argument))
19596 error_unavailable_use (argument, NULL_TREE);
19597 else if (TREE_DEPRECATED (argument))
19598 warn_deprecated_use (argument, NULL_TREE);
19599 return argument;
19600 }
19601 /* It must be a non-type argument. In C++17 any constant-expression is
19602 allowed. */
19603 if (cxx_dialect > cxx14)
19604 goto general_expr;
19605
19606 /* Otherwise, the permitted cases are given in [temp.arg.nontype]:
19607
19608 -- an integral constant-expression of integral or enumeration
19609 type; or
19610
19611 -- the name of a non-type template-parameter; or
19612
19613 -- the name of an object or function with external linkage...
19614
19615 -- the address of an object or function with external linkage...
19616
19617 -- a pointer to member... */
19618 /* Look for a non-type template parameter. */
19619 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
19620 {
19621 cp_parser_parse_tentatively (parser);
19622 argument = cp_parser_primary_expression (parser,
19623 /*address_p=*/false,
19624 /*cast_p=*/false,
19625 /*template_arg_p=*/true,
19626 idk: &idk);
19627 if (TREE_CODE (argument) != TEMPLATE_PARM_INDEX
19628 || !cp_parser_next_token_ends_template_argument_p (parser))
19629 cp_parser_simulate_error (parser);
19630 if (cp_parser_parse_definitely (parser))
19631 return argument;
19632 }
19633
19634 /* If the next token is "&", the argument must be the address of an
19635 object or function with external linkage. */
19636 address_p = cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_AND);
19637 if (address_p)
19638 {
19639 loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
19640 cp_lexer_consume_token (lexer: parser->lexer);
19641 }
19642 /* See if we might have an id-expression. */
19643 token = cp_lexer_peek_token (lexer: parser->lexer);
19644 if (token->type == CPP_NAME
19645 || token->keyword == RID_OPERATOR
19646 || token->type == CPP_SCOPE
19647 || token->type == CPP_TEMPLATE_ID
19648 || token->type == CPP_NESTED_NAME_SPECIFIER)
19649 {
19650 cp_parser_parse_tentatively (parser);
19651 argument = cp_parser_primary_expression (parser,
19652 address_p,
19653 /*cast_p=*/false,
19654 /*template_arg_p=*/true,
19655 idk: &idk);
19656 if (cp_parser_error_occurred (parser)
19657 || !cp_parser_next_token_ends_template_argument_p (parser))
19658 cp_parser_abort_tentative_parse (parser);
19659 else
19660 {
19661 tree probe;
19662
19663 if (INDIRECT_REF_P (argument))
19664 {
19665 /* Strip the dereference temporarily. */
19666 gcc_assert (REFERENCE_REF_P (argument));
19667 argument = TREE_OPERAND (argument, 0);
19668 }
19669
19670 /* If we're in a template, we represent a qualified-id referring
19671 to a static data member as a SCOPE_REF even if the scope isn't
19672 dependent so that we can check access control later. */
19673 probe = argument;
19674 if (TREE_CODE (probe) == SCOPE_REF)
19675 probe = TREE_OPERAND (probe, 1);
19676 if (VAR_P (probe))
19677 {
19678 /* A variable without external linkage might still be a
19679 valid constant-expression, so no error is issued here
19680 if the external-linkage check fails. */
19681 if (!address_p && !DECL_EXTERNAL_LINKAGE_P (probe))
19682 cp_parser_simulate_error (parser);
19683 }
19684 else if (is_overloaded_fn (argument))
19685 /* All overloaded functions are allowed; if the external
19686 linkage test does not pass, an error will be issued
19687 later. */
19688 ;
19689 else if (address_p
19690 && (TREE_CODE (argument) == OFFSET_REF
19691 || TREE_CODE (argument) == SCOPE_REF))
19692 /* A pointer-to-member. */
19693 ;
19694 else if (TREE_CODE (argument) == TEMPLATE_PARM_INDEX)
19695 ;
19696 else
19697 cp_parser_simulate_error (parser);
19698
19699 if (cp_parser_parse_definitely (parser))
19700 {
19701 if (address_p)
19702 argument = build_x_unary_op (loc, ADDR_EXPR, argument,
19703 NULL_TREE, tf_warning_or_error);
19704 else
19705 argument = convert_from_reference (argument);
19706 return argument;
19707 }
19708 }
19709 }
19710 /* If the argument started with "&", there are no other valid
19711 alternatives at this point. */
19712 if (address_p)
19713 {
19714 cp_parser_error (parser, gmsgid: "invalid non-type template argument");
19715 return error_mark_node;
19716 }
19717
19718 general_expr:
19719 /* If the argument wasn't successfully parsed as a type-id followed
19720 by '>>', the argument can only be a constant expression now.
19721 Otherwise, we try parsing the constant-expression tentatively,
19722 because the argument could really be a type-id. */
19723 if (maybe_type_id)
19724 cp_parser_parse_tentatively (parser);
19725
19726 if (cxx_dialect <= cxx14)
19727 argument = cp_parser_constant_expression (parser);
19728 else
19729 {
19730 /* In C++20, we can encounter a braced-init-list. */
19731 if (cxx_dialect >= cxx20
19732 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
19733 return cp_parser_braced_list (parser);
19734
19735 /* With C++17 generalized non-type template arguments we need to handle
19736 lvalue constant expressions, too. */
19737 argument = cp_parser_assignment_expression (parser);
19738 require_potential_constant_expression (argument);
19739 }
19740
19741 if (!maybe_type_id)
19742 return argument;
19743 if (!cp_parser_next_token_ends_template_argument_p (parser))
19744 cp_parser_error (parser, gmsgid: "expected template-argument");
19745 if (cp_parser_parse_definitely (parser))
19746 return argument;
19747 /* We did our best to parse the argument as a non type-id, but that
19748 was the only alternative that matched (albeit with a '>' after
19749 it). We can assume it's just a typo from the user, and a
19750 diagnostic will then be issued. */
19751 return cp_parser_template_type_arg (parser);
19752}
19753
19754/* Parse an explicit-instantiation.
19755
19756 explicit-instantiation:
19757 template declaration
19758
19759 Although the standard says `declaration', what it really means is:
19760
19761 explicit-instantiation:
19762 template decl-specifier-seq [opt] declarator [opt] ;
19763
19764 Things like `template int S<int>::i = 5, int S<double>::j;' are not
19765 supposed to be allowed. A defect report has been filed about this
19766 issue.
19767
19768 GNU Extension:
19769
19770 explicit-instantiation:
19771 storage-class-specifier template
19772 decl-specifier-seq [opt] declarator [opt] ;
19773 function-specifier template
19774 decl-specifier-seq [opt] declarator [opt] ; */
19775
19776static void
19777cp_parser_explicit_instantiation (cp_parser* parser)
19778{
19779 int declares_class_or_enum;
19780 cp_decl_specifier_seq decl_specifiers;
19781 tree extension_specifier = NULL_TREE;
19782
19783 auto_timevar tv (TV_TEMPLATE_INST);
19784
19785 /* Look for an (optional) storage-class-specifier or
19786 function-specifier. */
19787 if (cp_parser_allow_gnu_extensions_p (parser))
19788 {
19789 extension_specifier
19790 = cp_parser_storage_class_specifier_opt (parser);
19791 if (!extension_specifier)
19792 extension_specifier
19793 = cp_parser_function_specifier_opt (parser,
19794 /*decl_specs=*/NULL);
19795 }
19796
19797 /* Look for the `template' keyword. */
19798 cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
19799 /* Let the front end know that we are processing an explicit
19800 instantiation. */
19801 begin_explicit_instantiation ();
19802 /* [temp.explicit] says that we are supposed to ignore access
19803 control while processing explicit instantiation directives. */
19804 push_deferring_access_checks (dk_no_check);
19805 /* Parse a decl-specifier-seq. */
19806 cp_parser_decl_specifier_seq (parser,
19807 flags: CP_PARSER_FLAGS_OPTIONAL,
19808 decl_specs: &decl_specifiers,
19809 declares_class_or_enum: &declares_class_or_enum);
19810
19811 cp_omp_declare_simd_data odsd;
19812 if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
19813 cp_parser_handle_directive_omp_attributes (parser,
19814 pattrs: &decl_specifiers.attributes,
19815 data: &odsd, start: true);
19816
19817 /* If there was exactly one decl-specifier, and it declared a class,
19818 and there's no declarator, then we have an explicit type
19819 instantiation. */
19820 if (declares_class_or_enum && cp_parser_declares_only_class_p (parser))
19821 {
19822 tree type = check_tag_decl (&decl_specifiers,
19823 /*explicit_type_instantiation_p=*/true);
19824 /* Turn access control back on for names used during
19825 template instantiation. */
19826 pop_deferring_access_checks ();
19827 if (type)
19828 do_type_instantiation (type, extension_specifier,
19829 /*complain=*/tf_error);
19830 }
19831 else
19832 {
19833 cp_declarator *declarator;
19834 tree decl;
19835
19836 /* Parse the declarator. */
19837 declarator
19838 = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
19839 CP_PARSER_FLAGS_NONE,
19840 /*ctor_dtor_or_conv_p=*/NULL,
19841 /*parenthesized_p=*/NULL,
19842 /*member_p=*/false,
19843 /*friend_p=*/false,
19844 /*static_p=*/false);
19845 if (declares_class_or_enum & 2)
19846 cp_parser_check_for_definition_in_return_type (declarator,
19847 type: decl_specifiers.type,
19848 type_location: decl_specifiers.locations[ds_type_spec]);
19849 if (declarator != cp_error_declarator)
19850 {
19851 if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_inline))
19852 permerror (decl_specifiers.locations[ds_inline],
19853 "explicit instantiation shall not use"
19854 " %<inline%> specifier");
19855 if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_constexpr))
19856 permerror (decl_specifiers.locations[ds_constexpr],
19857 "explicit instantiation shall not use"
19858 " %<constexpr%> specifier");
19859 if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_consteval))
19860 permerror (decl_specifiers.locations[ds_consteval],
19861 "explicit instantiation shall not use"
19862 " %<consteval%> specifier");
19863
19864 decl = grokdeclarator (declarator, &decl_specifiers,
19865 NORMAL, 0, &decl_specifiers.attributes);
19866 /* Turn access control back on for names used during
19867 template instantiation. */
19868 pop_deferring_access_checks ();
19869 /* Do the explicit instantiation. */
19870 do_decl_instantiation (decl, extension_specifier);
19871 }
19872 else
19873 {
19874 pop_deferring_access_checks ();
19875 /* Skip the body of the explicit instantiation. */
19876 cp_parser_skip_to_end_of_statement (parser);
19877 }
19878 }
19879 /* We're done with the instantiation. */
19880 end_explicit_instantiation ();
19881
19882 cp_parser_consume_semicolon_at_end_of_statement (parser);
19883
19884 cp_finalize_omp_declare_simd (parser, data: &odsd);
19885}
19886
19887/* Parse an explicit-specialization.
19888
19889 explicit-specialization:
19890 template < > declaration
19891
19892 Although the standard says `declaration', what it really means is:
19893
19894 explicit-specialization:
19895 template <> decl-specifier [opt] init-declarator [opt] ;
19896 template <> function-definition
19897 template <> explicit-specialization
19898 template <> template-declaration */
19899
19900static void
19901cp_parser_explicit_specialization (cp_parser* parser)
19902{
19903 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
19904
19905 /* Look for the `template' keyword. */
19906 cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
19907 /* Look for the `<'. */
19908 cp_parser_require (parser, CPP_LESS, RT_LESS);
19909 /* Look for the `>'. */
19910 cp_parser_require (parser, CPP_GREATER, RT_GREATER);
19911 /* We have processed another parameter list. */
19912 ++parser->num_template_parameter_lists;
19913
19914 /* [temp]
19915
19916 A template ... explicit specialization ... shall not have C
19917 linkage. */
19918 bool need_lang_pop = current_lang_name == lang_name_c;
19919 if (need_lang_pop)
19920 {
19921 error_at (token->location, "template specialization with C linkage");
19922 maybe_show_extern_c_location ();
19923
19924 /* Give it C++ linkage to avoid confusing other parts of the
19925 front end. */
19926 push_lang_context (lang_name_cplusplus);
19927 }
19928
19929 /* Let the front end know that we are beginning a specialization. */
19930 if (begin_specialization ())
19931 {
19932 /* If the next keyword is `template', we need to figure out
19933 whether or not we're looking a template-declaration. */
19934 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TEMPLATE))
19935 {
19936 if (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_LESS
19937 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type != CPP_GREATER)
19938 cp_parser_template_declaration_after_export (parser,
19939 /*member_p=*/false);
19940 else
19941 cp_parser_explicit_specialization (parser);
19942 }
19943 else
19944 /* Parse the dependent declaration. */
19945 cp_parser_single_declaration (parser,
19946 /*checks=*/NULL,
19947 /*member_p=*/false,
19948 /*explicit_specialization_p=*/true,
19949 /*friend_p=*/NULL);
19950 }
19951
19952 /* We're done with the specialization. */
19953 end_specialization ();
19954
19955 /* For the erroneous case of a template with C linkage, we pushed an
19956 implicit C++ linkage scope; exit that scope now. */
19957 if (need_lang_pop)
19958 pop_lang_context ();
19959
19960 /* We're done with this parameter list. */
19961 --parser->num_template_parameter_lists;
19962}
19963
19964/* Preserve the attributes across a garbage collect (by making it a GC
19965 root), which can occur when parsing a member function. */
19966
19967static GTY(()) vec<tree, va_gc> *cp_parser_decl_specs_attrs;
19968
19969/* Parse a type-specifier.
19970
19971 type-specifier:
19972 simple-type-specifier
19973 class-specifier
19974 enum-specifier
19975 elaborated-type-specifier
19976 cv-qualifier
19977
19978 GNU Extension:
19979
19980 type-specifier:
19981 __complex__
19982
19983 Returns a representation of the type-specifier. For a
19984 class-specifier, enum-specifier, or elaborated-type-specifier, a
19985 TREE_TYPE is returned; otherwise, a TYPE_DECL is returned.
19986
19987 The parser flags FLAGS is used to control type-specifier parsing.
19988
19989 If IS_DECLARATION is TRUE, then this type-specifier is appearing
19990 in a decl-specifier-seq.
19991
19992 If DECLARES_CLASS_OR_ENUM is non-NULL, and the type-specifier is a
19993 class-specifier, enum-specifier, or elaborated-type-specifier, then
19994 *DECLARES_CLASS_OR_ENUM is set to a nonzero value. The value is 1
19995 if a type is declared; 2 if it is defined. Otherwise, it is set to
19996 zero.
19997
19998 If IS_CV_QUALIFIER is non-NULL, and the type-specifier is a
19999 cv-qualifier, then IS_CV_QUALIFIER is set to TRUE. Otherwise, it
20000 is set to FALSE. */
20001
20002static tree
20003cp_parser_type_specifier (cp_parser* parser,
20004 cp_parser_flags flags,
20005 cp_decl_specifier_seq *decl_specs,
20006 bool is_declaration,
20007 int* declares_class_or_enum,
20008 bool* is_cv_qualifier)
20009{
20010 tree type_spec = NULL_TREE;
20011 cp_token *token;
20012 enum rid keyword;
20013 cp_decl_spec ds = ds_last;
20014
20015 /* Assume this type-specifier does not declare a new type. */
20016 if (declares_class_or_enum)
20017 *declares_class_or_enum = 0;
20018 /* And that it does not specify a cv-qualifier. */
20019 if (is_cv_qualifier)
20020 *is_cv_qualifier = false;
20021 /* Peek at the next token. */
20022 token = cp_lexer_peek_token (lexer: parser->lexer);
20023
20024 /* If we're looking at a keyword, we can use that to guide the
20025 production we choose. */
20026 keyword = token->keyword;
20027 switch (keyword)
20028 {
20029 case RID_ENUM:
20030 if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
20031 goto elaborated_type_specifier;
20032
20033 /* Look for the enum-specifier. */
20034 type_spec = cp_parser_enum_specifier (parser);
20035 /* If that worked, we're done. */
20036 if (type_spec)
20037 {
20038 if (declares_class_or_enum)
20039 *declares_class_or_enum = 2;
20040 if (decl_specs)
20041 cp_parser_set_decl_spec_type (decl_specs,
20042 type_spec,
20043 token,
20044 /*type_definition_p=*/true);
20045 return type_spec;
20046 }
20047 else
20048 goto elaborated_type_specifier;
20049
20050 /* Any of these indicate either a class-specifier, or an
20051 elaborated-type-specifier. */
20052 case RID_CLASS:
20053 case RID_STRUCT:
20054 case RID_UNION:
20055 if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
20056 goto elaborated_type_specifier;
20057
20058 /* Parse tentatively so that we can back up if we don't find a
20059 class-specifier. */
20060 cp_parser_parse_tentatively (parser);
20061 if (decl_specs->attributes)
20062 vec_safe_push (v&: cp_parser_decl_specs_attrs, obj: decl_specs->attributes);
20063 /* Look for the class-specifier. */
20064 type_spec = cp_parser_class_specifier (parser);
20065 if (decl_specs->attributes)
20066 cp_parser_decl_specs_attrs->pop ();
20067 invoke_plugin_callbacks (event: PLUGIN_FINISH_TYPE, gcc_data: type_spec);
20068 /* If that worked, we're done. */
20069 if (cp_parser_parse_definitely (parser))
20070 {
20071 if (declares_class_or_enum)
20072 *declares_class_or_enum = 2;
20073 if (decl_specs)
20074 cp_parser_set_decl_spec_type (decl_specs,
20075 type_spec,
20076 token,
20077 /*type_definition_p=*/true);
20078 return type_spec;
20079 }
20080
20081 /* Fall through. */
20082 elaborated_type_specifier:
20083 /* We're declaring (not defining) a class or enum. */
20084 if (declares_class_or_enum)
20085 *declares_class_or_enum = 1;
20086
20087 /* Fall through. */
20088 case RID_TYPENAME:
20089 /* Look for an elaborated-type-specifier. */
20090 type_spec
20091 = (cp_parser_elaborated_type_specifier
20092 (parser,
20093 decl_spec_seq_has_spec_p (decl_specs, ds_friend),
20094 is_declaration));
20095 if (decl_specs)
20096 cp_parser_set_decl_spec_type (decl_specs,
20097 type_spec,
20098 token,
20099 /*type_definition_p=*/false);
20100 return type_spec;
20101
20102 case RID_CONST:
20103 ds = ds_const;
20104 if (is_cv_qualifier)
20105 *is_cv_qualifier = true;
20106 break;
20107
20108 case RID_VOLATILE:
20109 ds = ds_volatile;
20110 if (is_cv_qualifier)
20111 *is_cv_qualifier = true;
20112 break;
20113
20114 case RID_RESTRICT:
20115 ds = ds_restrict;
20116 if (is_cv_qualifier)
20117 *is_cv_qualifier = true;
20118 break;
20119
20120 case RID_COMPLEX:
20121 /* The `__complex__' keyword is a GNU extension. */
20122 ds = ds_complex;
20123 break;
20124
20125 default:
20126 break;
20127 }
20128
20129 /* Handle simple keywords. */
20130 if (ds != ds_last)
20131 {
20132 if (decl_specs)
20133 {
20134 set_and_check_decl_spec_loc (decl_specs, ds, token);
20135 decl_specs->any_specifiers_p = true;
20136 }
20137 return cp_lexer_consume_token (lexer: parser->lexer)->u.value;
20138 }
20139
20140 /* If we do not already have a type-specifier, assume we are looking
20141 at a simple-type-specifier. */
20142 type_spec = cp_parser_simple_type_specifier (parser,
20143 decl_specs,
20144 flags);
20145
20146 /* If we didn't find a type-specifier, and a type-specifier was not
20147 optional in this context, issue an error message. */
20148 if (!type_spec && !(flags & CP_PARSER_FLAGS_OPTIONAL))
20149 {
20150 cp_parser_error (parser, gmsgid: "expected type specifier");
20151 return error_mark_node;
20152 }
20153
20154 return type_spec;
20155}
20156
20157/* Parse a simple-type-specifier.
20158
20159 simple-type-specifier:
20160 :: [opt] nested-name-specifier [opt] type-name
20161 :: [opt] nested-name-specifier template template-id
20162 char
20163 wchar_t
20164 bool
20165 short
20166 int
20167 long
20168 signed
20169 unsigned
20170 float
20171 double
20172 void
20173
20174 C++11 Extension:
20175
20176 simple-type-specifier:
20177 auto
20178 decltype ( expression )
20179 char16_t
20180 char32_t
20181 __underlying_type ( type-id )
20182
20183 C++17 extension:
20184
20185 nested-name-specifier(opt) template-name
20186
20187 GNU Extension:
20188
20189 simple-type-specifier:
20190 __int128
20191 __typeof__ unary-expression
20192 __typeof__ ( type-id )
20193 __typeof__ ( type-id ) { initializer-list , [opt] }
20194
20195 Concepts Extension:
20196
20197 simple-type-specifier:
20198 constrained-type-specifier
20199
20200 Returns the indicated TYPE_DECL. If DECL_SPECS is not NULL, it is
20201 appropriately updated. */
20202
20203static tree
20204cp_parser_simple_type_specifier (cp_parser* parser,
20205 cp_decl_specifier_seq *decl_specs,
20206 cp_parser_flags flags)
20207{
20208 tree type = NULL_TREE;
20209 cp_token *token;
20210 int idx;
20211
20212 /* Peek at the next token. */
20213 token = cp_lexer_peek_token (lexer: parser->lexer);
20214
20215 /* If we're looking at a keyword, things are easy. */
20216 switch (token->keyword)
20217 {
20218 case RID_CHAR:
20219 if (decl_specs)
20220 decl_specs->explicit_char_p = true;
20221 type = char_type_node;
20222 break;
20223 case RID_CHAR8:
20224 type = char8_type_node;
20225 break;
20226 case RID_CHAR16:
20227 type = char16_type_node;
20228 break;
20229 case RID_CHAR32:
20230 type = char32_type_node;
20231 break;
20232 case RID_WCHAR:
20233 type = wchar_type_node;
20234 break;
20235 case RID_BOOL:
20236 type = boolean_type_node;
20237 break;
20238 case RID_SHORT:
20239 set_and_check_decl_spec_loc (decl_specs, ds: ds_short, token);
20240 type = short_integer_type_node;
20241 break;
20242 case RID_INT:
20243 if (decl_specs)
20244 decl_specs->explicit_int_p = true;
20245 type = integer_type_node;
20246 break;
20247 case RID_INT_N_0:
20248 case RID_INT_N_1:
20249 case RID_INT_N_2:
20250 case RID_INT_N_3:
20251 idx = token->keyword - RID_INT_N_0;
20252 if (! int_n_enabled_p [idx])
20253 break;
20254 if (decl_specs)
20255 {
20256 decl_specs->explicit_intN_p = true;
20257 decl_specs->int_n_idx = idx;
20258 /* Check if the alternate "__intN__" form has been used instead of
20259 "__intN". */
20260 if (startswith (IDENTIFIER_POINTER (token->u.value)
20261 + (IDENTIFIER_LENGTH (token->u.value) - 2), prefix: "__"))
20262 decl_specs->int_n_alt = true;
20263 }
20264 type = int_n_trees [idx].signed_type;
20265 break;
20266 case RID_LONG:
20267 if (decl_specs)
20268 set_and_check_decl_spec_loc (decl_specs, ds: ds_long, token);
20269 type = long_integer_type_node;
20270 break;
20271 case RID_SIGNED:
20272 set_and_check_decl_spec_loc (decl_specs, ds: ds_signed, token);
20273 type = integer_type_node;
20274 break;
20275 case RID_UNSIGNED:
20276 set_and_check_decl_spec_loc (decl_specs, ds: ds_unsigned, token);
20277 type = unsigned_type_node;
20278 break;
20279 case RID_FLOAT:
20280 type = float_type_node;
20281 break;
20282 case RID_DOUBLE:
20283 type = double_type_node;
20284 break;
20285 CASE_RID_FLOATN_NX:
20286 type = FLOATN_NX_TYPE_NODE (token->keyword - RID_FLOATN_NX_FIRST);
20287 if (type == NULL_TREE)
20288 error ("%<_Float%d%s%> is not supported on this target",
20289 floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].n,
20290 floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].extended
20291 ? "x" : "");
20292 break;
20293 case RID_VOID:
20294 type = void_type_node;
20295 break;
20296
20297 case RID_AUTO:
20298 maybe_warn_cpp0x (str: CPP0X_AUTO);
20299 if (parser->auto_is_implicit_function_template_parm_p)
20300 {
20301 /* The 'auto' might be the placeholder return type for a function decl
20302 with trailing return type. */
20303 bool have_trailing_return_fn_decl = false;
20304
20305 cp_parser_parse_tentatively (parser);
20306 cp_lexer_consume_token (lexer: parser->lexer);
20307 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_EQ)
20308 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA)
20309 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN)
20310 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_EOF))
20311 {
20312 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
20313 {
20314 cp_lexer_consume_token (lexer: parser->lexer);
20315 cp_parser_skip_to_closing_parenthesis (parser,
20316 /*recovering*/false,
20317 /*or_comma*/false,
20318 /*consume_paren*/true);
20319 continue;
20320 }
20321
20322 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DEREF))
20323 {
20324 have_trailing_return_fn_decl = true;
20325 break;
20326 }
20327
20328 cp_lexer_consume_token (lexer: parser->lexer);
20329 }
20330 cp_parser_abort_tentative_parse (parser);
20331
20332 if (have_trailing_return_fn_decl)
20333 {
20334 type = make_auto ();
20335 break;
20336 }
20337
20338 if (cxx_dialect >= cxx14)
20339 {
20340 type = synthesize_implicit_template_parm (parser, NULL_TREE);
20341 type = TREE_TYPE (type);
20342 }
20343 else
20344 type = error_mark_node;
20345
20346 if (current_class_type && LAMBDA_TYPE_P (current_class_type))
20347 {
20348 if (cxx_dialect < cxx14)
20349 error_at (token->location,
20350 "use of %<auto%> in lambda parameter declaration "
20351 "only available with "
20352 "%<-std=c++14%> or %<-std=gnu++14%>");
20353 }
20354 else if (!flag_concepts_ts && parser->in_template_argument_list_p)
20355 pedwarn (token->location, 0,
20356 "use of %<auto%> in template argument "
20357 "only available with %<-fconcepts-ts%>");
20358 else if (!flag_concepts)
20359 pedwarn (token->location, 0,
20360 "use of %<auto%> in parameter declaration "
20361 "only available with %<-std=c++20%> or %<-fconcepts%>");
20362 else if (cxx_dialect < cxx14)
20363 error_at (token->location,
20364 "use of %<auto%> in parameter declaration "
20365 "only available with "
20366 "%<-std=c++14%> or %<-std=gnu++14%>");
20367 }
20368 else
20369 type = make_auto ();
20370 break;
20371
20372 case RID_DECLTYPE:
20373 /* Since DR 743, decltype can either be a simple-type-specifier by
20374 itself or begin a nested-name-specifier. Parsing it will replace
20375 it with a CPP_DECLTYPE, so just rewind and let the CPP_DECLTYPE
20376 handling below decide what to do. */
20377 cp_parser_decltype (parser);
20378 cp_lexer_set_token_position (lexer: parser->lexer, pos: token);
20379 break;
20380
20381 case RID_TYPEOF:
20382 /* Consume the `typeof' token. */
20383 cp_lexer_consume_token (lexer: parser->lexer);
20384 /* Parse the operand to `typeof'. */
20385 type = cp_parser_sizeof_operand (parser, RID_TYPEOF);
20386 /* If it is not already a TYPE, take its type. */
20387 if (!TYPE_P (type))
20388 type = finish_typeof (type);
20389
20390 if (decl_specs)
20391 cp_parser_set_decl_spec_type (decl_specs, type,
20392 token,
20393 /*type_definition_p=*/false);
20394
20395 return type;
20396
20397 default:
20398 /* If token is a type-yielding built-in traits, parse it. */
20399 const cp_trait* trait = cp_lexer_peek_trait_type (lexer: parser->lexer);
20400 if (trait)
20401 {
20402 type = cp_parser_trait (parser, trait);
20403 if (decl_specs)
20404 cp_parser_set_decl_spec_type (decl_specs, type,
20405 token,
20406 /*type_definition_p=*/false);
20407
20408 return type;
20409 }
20410
20411 break;
20412 }
20413
20414 /* If token is an already-parsed decltype not followed by ::,
20415 it's a simple-type-specifier. */
20416 if (token->type == CPP_DECLTYPE
20417 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type != CPP_SCOPE)
20418 {
20419 type = saved_checks_value (check_value: token->u.tree_check_value);
20420 if (decl_specs)
20421 {
20422 cp_parser_set_decl_spec_type (decl_specs, type,
20423 token,
20424 /*type_definition_p=*/false);
20425 /* Remember that we are handling a decltype in order to
20426 implement the resolution of DR 1510 when the argument
20427 isn't instantiation dependent. */
20428 decl_specs->decltype_p = true;
20429 }
20430 cp_lexer_consume_token (lexer: parser->lexer);
20431 return type;
20432 }
20433
20434 /* If the type-specifier was for a built-in type, we're done. */
20435 if (type)
20436 {
20437 /* Record the type. */
20438 if (decl_specs
20439 && (token->keyword != RID_SIGNED
20440 && token->keyword != RID_UNSIGNED
20441 && token->keyword != RID_SHORT
20442 && token->keyword != RID_LONG))
20443 cp_parser_set_decl_spec_type (decl_specs,
20444 type,
20445 token,
20446 /*type_definition_p=*/false);
20447 if (decl_specs)
20448 decl_specs->any_specifiers_p = true;
20449
20450 /* Consume the token. */
20451 cp_lexer_consume_token (lexer: parser->lexer);
20452
20453 if (type == error_mark_node)
20454 return error_mark_node;
20455
20456 /* There is no valid C++ program where a non-template type is
20457 followed by a "<". That usually indicates that the user thought
20458 that the type was a template. */
20459 cp_parser_check_for_invalid_template_id (parser, type, tag_type: none_type,
20460 location: token->location);
20461
20462 return TYPE_NAME (type);
20463 }
20464
20465 /* The type-specifier must be a user-defined type. */
20466 if (!(flags & CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES))
20467 {
20468 bool qualified_p;
20469 bool global_p;
20470 const bool typename_p = (cxx_dialect >= cxx20
20471 && (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL));
20472
20473 /* Don't gobble tokens or issue error messages if this is an
20474 optional type-specifier. */
20475 if (flags & CP_PARSER_FLAGS_OPTIONAL)
20476 cp_parser_parse_tentatively (parser);
20477
20478 /* Remember current tentative parsing state -- if we know we need
20479 a type, we can give better diagnostics here. */
20480 bool tent = cp_parser_parsing_tentatively (parser);
20481
20482 token = cp_lexer_peek_token (lexer: parser->lexer);
20483
20484 /* Look for the optional `::' operator. */
20485 global_p
20486 = (cp_parser_global_scope_opt (parser,
20487 /*current_scope_valid_p=*/false)
20488 != NULL_TREE);
20489 /* Look for the nested-name specifier. */
20490 qualified_p
20491 = (cp_parser_nested_name_specifier_opt (parser,
20492 /*typename_keyword_p=*/false,
20493 /*check_dependency_p=*/true,
20494 /*type_p=*/false,
20495 /*is_declaration=*/false)
20496 != NULL_TREE);
20497 /* If we have seen a nested-name-specifier, and the next token
20498 is `template', then we are using the template-id production. */
20499 if (parser->scope
20500 && cp_parser_optional_template_keyword (parser))
20501 {
20502 /* Look for the template-id. */
20503 type = cp_parser_template_id (parser,
20504 /*template_keyword_p=*/true,
20505 /*check_dependency_p=*/true,
20506 tag_type: none_type,
20507 /*is_declaration=*/false);
20508 /* If the template-id did not name a type, we are out of
20509 luck. */
20510 if (TREE_CODE (type) != TYPE_DECL)
20511 {
20512 /* ...unless we pretend we have seen 'typename'. */
20513 if (typename_p)
20514 type = cp_parser_make_typename_type (parser, id: type,
20515 id_location: token->location);
20516 else
20517 {
20518 cp_parser_error (parser, gmsgid: "expected template-id for type");
20519 type = error_mark_node;
20520 }
20521 }
20522 }
20523 /* DR 1812: A < following a qualified-id in a typename-specifier
20524 could safely be assumed to begin a template argument list, so
20525 the template keyword should be optional. */
20526 else if (parser->scope
20527 && qualified_p
20528 && typename_p
20529 && cp_lexer_next_token_is (lexer: parser->lexer, CPP_TEMPLATE_ID))
20530 {
20531 cp_parser_parse_tentatively (parser);
20532
20533 type = cp_parser_template_id (parser,
20534 /*template_keyword_p=*/true,
20535 /*check_dependency_p=*/true,
20536 tag_type: none_type,
20537 /*is_declaration=*/false);
20538 /* This is handled below, so back off. */
20539 if (type && concept_check_p (t: type))
20540 cp_parser_simulate_error (parser);
20541
20542 if (!cp_parser_parse_definitely (parser))
20543 type = NULL_TREE;
20544 else if (TREE_CODE (type) == TEMPLATE_ID_EXPR)
20545 type = make_typename_type (parser->scope, type, typename_type,
20546 /*complain=*/tf_error);
20547 else if (TREE_CODE (type) != TYPE_DECL)
20548 type = NULL_TREE;
20549 }
20550
20551 /* Otherwise, look for a type-name. */
20552 if (!type)
20553 {
20554 if (cxx_dialect >= cxx17 || flag_concepts)
20555 cp_parser_parse_tentatively (parser);
20556
20557 type = cp_parser_type_name (parser, (qualified_p && typename_p));
20558
20559 if ((cxx_dialect >= cxx17 || flag_concepts)
20560 && !cp_parser_parse_definitely (parser))
20561 type = NULL_TREE;
20562 }
20563
20564 if (!type && flag_concepts && decl_specs)
20565 {
20566 /* Try for a type-constraint with template arguments. We check
20567 decl_specs here to avoid trying this for a functional cast. */
20568
20569 cp_parser_parse_tentatively (parser);
20570
20571 type = cp_parser_template_id (parser,
20572 /*template_keyword_p=*/false,
20573 /*check_dependency_p=*/true,
20574 tag_type: none_type,
20575 /*is_declaration=*/false);
20576 if (type && concept_check_p (t: type))
20577 {
20578 location_t loc = EXPR_LOCATION (type);
20579 type = cp_parser_placeholder_type_specifier (parser, loc,
20580 type, tent);
20581 if (tent && type == error_mark_node)
20582 /* Perhaps it's a concept-check expression. */
20583 cp_parser_simulate_error (parser);
20584 }
20585 else
20586 cp_parser_simulate_error (parser);
20587
20588 if (!cp_parser_parse_definitely (parser))
20589 type = NULL_TREE;
20590 }
20591
20592 if (!type && cxx_dialect >= cxx17)
20593 {
20594 /* Try class template argument deduction or type-constraint without
20595 template arguments. */
20596 tree name = cp_parser_identifier (parser);
20597 if (name && TREE_CODE (name) == IDENTIFIER_NODE
20598 && parser->scope != error_mark_node)
20599 {
20600 location_t loc
20601 = cp_lexer_previous_token (lexer: parser->lexer)->location;
20602 tree tmpl = cp_parser_lookup_name (parser, name,
20603 none_type,
20604 /*is_template=*/false,
20605 /*is_namespace=*/false,
20606 /*check_dependency=*/true,
20607 /*ambiguous_decls=*/NULL,
20608 token->location);
20609 if (tmpl && tmpl != error_mark_node
20610 && ctad_template_p (tmpl))
20611 type = make_template_placeholder (tmpl);
20612 else if (flag_concepts && tmpl && concept_definition_p (t: tmpl))
20613 type = cp_parser_placeholder_type_specifier (parser, loc,
20614 tmpl, tent);
20615 else
20616 {
20617 type = error_mark_node;
20618 if (!cp_parser_simulate_error (parser))
20619 cp_parser_name_lookup_error (parser, name, decl: tmpl,
20620 desired: NLE_TYPE, location: token->location);
20621 }
20622 }
20623 else
20624 type = error_mark_node;
20625 }
20626
20627 /* If it didn't work out, we don't have a TYPE. */
20628 if ((flags & CP_PARSER_FLAGS_OPTIONAL)
20629 && !cp_parser_parse_definitely (parser))
20630 type = NULL_TREE;
20631
20632 /* Keep track of all name-lookups performed in class scopes. */
20633 if (type
20634 && !global_p
20635 && !qualified_p
20636 && TREE_CODE (type) == TYPE_DECL
20637 && identifier_p (DECL_NAME (type)))
20638 maybe_note_name_used_in_class (DECL_NAME (type), type);
20639
20640 if (type && decl_specs)
20641 cp_parser_set_decl_spec_type (decl_specs, type,
20642 token,
20643 /*type_definition_p=*/false);
20644 }
20645
20646 /* If we didn't get a type-name, issue an error message. */
20647 if (!type && !(flags & CP_PARSER_FLAGS_OPTIONAL))
20648 {
20649 cp_parser_error (parser, gmsgid: "expected type-name");
20650 return error_mark_node;
20651 }
20652
20653 if (type && type != error_mark_node)
20654 {
20655 /* See if TYPE is an Objective-C type, and if so, parse and
20656 accept any protocol references following it. Do this before
20657 the cp_parser_check_for_invalid_template_id() call, because
20658 Objective-C types can be followed by '<...>' which would
20659 enclose protocol names rather than template arguments, and so
20660 everything is fine. */
20661 if (c_dialect_objc () && !parser->scope
20662 && (objc_is_id (type) || objc_is_class_name (type)))
20663 {
20664 tree protos = cp_parser_objc_protocol_refs_opt (parser);
20665 tree qual_type = objc_get_protocol_qualified_type (type, protos);
20666
20667 /* Clobber the "unqualified" type previously entered into
20668 DECL_SPECS with the new, improved protocol-qualified version. */
20669 if (decl_specs)
20670 decl_specs->type = qual_type;
20671
20672 return qual_type;
20673 }
20674
20675 /* There is no valid C++ program where a non-template type is
20676 followed by a "<". That usually indicates that the user
20677 thought that the type was a template. */
20678 cp_parser_check_for_invalid_template_id (parser, type,
20679 tag_type: none_type,
20680 location: token->location);
20681 }
20682
20683 return type;
20684}
20685
20686/* Parse the remainder of a placholder-type-specifier.
20687
20688 placeholder-type-specifier:
20689 type-constraint_opt auto
20690 type-constraint_opt decltype(auto)
20691
20692 The raw form of the constraint is parsed in cp_parser_simple_type_specifier
20693 and passed as TMPL. This function converts TMPL to an actual type-constraint,
20694 parses the placeholder type, and performs some contextual syntactic analysis.
20695
20696 LOC provides the location of the template name.
20697
20698 TENTATIVE is true if the type-specifier parsing is tentative; in that case,
20699 don't give an error if TMPL isn't a valid type-constraint, as the template-id
20700 might actually be a concept-check,
20701
20702 Note that the Concepts TS allows the auto or decltype(auto) to be
20703 omitted in a constrained-type-specifier. */
20704
20705static tree
20706cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
20707 tree tmpl, bool tentative)
20708{
20709 if (tmpl == error_mark_node)
20710 return error_mark_node;
20711
20712 tree orig_tmpl = tmpl;
20713
20714 /* Get the arguments as written for subsequent analysis. */
20715 tree args = NULL_TREE;
20716 if (TREE_CODE (tmpl) == TEMPLATE_ID_EXPR)
20717 {
20718 args = TREE_OPERAND (tmpl, 1);
20719 tmpl = TREE_OPERAND (tmpl, 0);
20720 }
20721 else
20722 /* A concept-name with no arguments can't be an expression. */
20723 tentative = false;
20724
20725 tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error;
20726
20727 /* Get the concept and prototype parameter for the constraint. */
20728 tree_pair info = finish_type_constraints (tmpl, args, complain);
20729 tree con = info.first;
20730 tree proto = info.second;
20731 if (con == error_mark_node)
20732 return error_mark_node;
20733
20734 /* As per the standard, require auto or decltype(auto), except in some
20735 cases (template parameter lists, -fconcepts-ts enabled). */
20736 cp_token *placeholder = NULL, *close_paren = NULL;
20737 if (cxx_dialect >= cxx20)
20738 {
20739 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_AUTO))
20740 placeholder = cp_lexer_consume_token (lexer: parser->lexer);
20741 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_DECLTYPE))
20742 {
20743 placeholder = cp_lexer_consume_token (lexer: parser->lexer);
20744 matching_parens parens;
20745 parens.require_open (parser);
20746 cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
20747 close_paren = parens.require_close (parser);
20748 }
20749 }
20750
20751 /* A type constraint constrains a contextually determined type or type
20752 parameter pack. However, the Concepts TS does allow concepts
20753 to introduce non-type and template template parameters. */
20754 if (TREE_CODE (proto) != TYPE_DECL)
20755 {
20756 if (!flag_concepts_ts
20757 || !processing_template_parmlist)
20758 {
20759 if (!tentative)
20760 {
20761 error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
20762 inform (DECL_SOURCE_LOCATION (con), "concept defined here");
20763 }
20764 return error_mark_node;
20765 }
20766 }
20767
20768 /* In a template parameter list, a type-parameter can be introduced
20769 by type-constraints alone. */
20770 if (processing_template_parmlist && !placeholder)
20771 {
20772 /* In a default argument we may not be creating new parameters. */
20773 if (parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
20774 {
20775 /* If this assert turns out to be false, do error() instead. */
20776 gcc_assert (tentative);
20777 return error_mark_node;
20778 }
20779 return build_constrained_parameter (con, proto, args);
20780 }
20781
20782 /* Diagnose issues placeholder issues. */
20783 if (!flag_concepts_ts
20784 && !parser->in_result_type_constraint_p
20785 && !placeholder)
20786 {
20787 if (tentative)
20788 /* Perhaps it's a concept-check expression (c++/91073). */
20789 return error_mark_node;
20790
20791 tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
20792 tree expr = DECL_P (orig_tmpl) ? DECL_NAME (con) : id;
20793 error_at (input_location,
20794 "expected %<auto%> or %<decltype(auto)%> after %qE", expr);
20795 /* Fall through. This is an error of omission. */
20796 }
20797 else if (parser->in_result_type_constraint_p && placeholder)
20798 {
20799 /* A trailing return type only allows type-constraints. */
20800 error_at (input_location,
20801 "unexpected placeholder in constrained result type");
20802 }
20803
20804 /* In a parameter-declaration-clause, a placeholder-type-specifier
20805 results in an invented template parameter. */
20806 if (parser->auto_is_implicit_function_template_parm_p)
20807 {
20808 if (close_paren)
20809 {
20810 location_t loc = make_location (caret: placeholder->location,
20811 start: placeholder->location,
20812 finish: close_paren->location);
20813 error_at (loc, "cannot declare a parameter with %<decltype(auto)%>");
20814 return error_mark_node;
20815 }
20816 tree parm = build_constrained_parameter (con, proto, args);
20817 return synthesize_implicit_template_parm (parser, parm);
20818 }
20819
20820 /* Determine if the type should be deduced using template argument
20821 deduction or decltype deduction. Note that the latter is always
20822 used for type-constraints in trailing return types. */
20823 bool decltype_p = placeholder
20824 ? placeholder->keyword == RID_DECLTYPE
20825 : parser->in_result_type_constraint_p;
20826
20827 /* Otherwise, this is the type of a variable or return type. */
20828 if (decltype_p)
20829 return make_constrained_decltype_auto (con, args);
20830 else
20831 return make_constrained_auto (con, args);
20832}
20833
20834/* Parse a type-name.
20835
20836 type-name:
20837 class-name
20838 enum-name
20839 typedef-name
20840 simple-template-id [in c++0x]
20841
20842 enum-name:
20843 identifier
20844
20845 typedef-name:
20846 identifier
20847
20848 Concepts:
20849
20850 type-name:
20851 concept-name
20852 partial-concept-id
20853
20854 concept-name:
20855 identifier
20856
20857 Returns a TYPE_DECL for the type. */
20858
20859static tree
20860cp_parser_type_name (cp_parser* parser, bool typename_keyword_p)
20861{
20862 tree type_decl;
20863
20864 /* We can't know yet whether it is a class-name or not. */
20865 cp_parser_parse_tentatively (parser);
20866 /* Try a class-name. */
20867 type_decl = cp_parser_class_name (parser,
20868 typename_keyword_p,
20869 /*template_keyword_p=*/false,
20870 none_type,
20871 /*check_dependency_p=*/true,
20872 /*class_head_p=*/false,
20873 /*is_declaration=*/false);
20874 /* If it's not a class-name, keep looking. */
20875 if (!cp_parser_parse_definitely (parser))
20876 {
20877 if (cxx_dialect < cxx11)
20878 /* It must be a typedef-name or an enum-name. */
20879 return cp_parser_nonclass_name (parser);
20880
20881 cp_parser_parse_tentatively (parser);
20882 /* It is either a simple-template-id representing an
20883 instantiation of an alias template... */
20884 type_decl = cp_parser_template_id (parser,
20885 /*template_keyword_p=*/false,
20886 /*check_dependency_p=*/true,
20887 tag_type: none_type,
20888 /*is_declaration=*/false);
20889 /* Note that this must be an instantiation of an alias template
20890 because [temp.names]/6 says:
20891
20892 A template-id that names an alias template specialization
20893 is a type-name.
20894
20895 Whereas [temp.names]/7 says:
20896
20897 A simple-template-id that names a class template
20898 specialization is a class-name.
20899
20900 With concepts, this could also be a partial-concept-id that
20901 declares a non-type template parameter. */
20902 if (type_decl != NULL_TREE
20903 && TREE_CODE (type_decl) == TYPE_DECL
20904 && TYPE_DECL_ALIAS_P (type_decl))
20905 gcc_assert (DECL_TEMPLATE_INSTANTIATION (type_decl));
20906 else
20907 cp_parser_simulate_error (parser);
20908
20909 if (!cp_parser_parse_definitely (parser))
20910 /* ... Or a typedef-name or an enum-name. */
20911 return cp_parser_nonclass_name (parser);
20912 }
20913
20914 return type_decl;
20915}
20916
20917/* Parse a non-class type-name, that is, either an enum-name, a typedef-name,
20918 or a concept-name.
20919
20920 enum-name:
20921 identifier
20922
20923 typedef-name:
20924 identifier
20925
20926 concept-name:
20927 identifier
20928
20929 Returns a TYPE_DECL for the type. */
20930
20931static tree
20932cp_parser_nonclass_name (cp_parser* parser)
20933{
20934 tree type_decl;
20935 tree identifier;
20936
20937 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
20938 identifier = cp_parser_identifier (parser);
20939 if (identifier == error_mark_node)
20940 return error_mark_node;
20941
20942 /* Look up the type-name. */
20943 type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
20944
20945 type_decl = strip_using_decl (type_decl);
20946
20947 if (TREE_CODE (type_decl) != TYPE_DECL
20948 && (objc_is_id (identifier) || objc_is_class_name (identifier)))
20949 {
20950 /* See if this is an Objective-C type. */
20951 tree protos = cp_parser_objc_protocol_refs_opt (parser);
20952 tree type = objc_get_protocol_qualified_type (identifier, protos);
20953 if (type)
20954 type_decl = TYPE_NAME (type);
20955 }
20956
20957 /* Issue an error if we did not find a type-name. */
20958 if (TREE_CODE (type_decl) != TYPE_DECL
20959 /* In Objective-C, we have the complication that class names are
20960 normally type names and start declarations (eg, the
20961 "NSObject" in "NSObject *object;"), but can be used in an
20962 Objective-C 2.0 dot-syntax (as in "NSObject.version") which
20963 is an expression. So, a classname followed by a dot is not a
20964 valid type-name. */
20965 || (objc_is_class_name (TREE_TYPE (type_decl))
20966 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_DOT))
20967 {
20968 if (!cp_parser_simulate_error (parser))
20969 cp_parser_name_lookup_error (parser, name: identifier, decl: type_decl,
20970 desired: NLE_TYPE, location: token->location);
20971 return error_mark_node;
20972 }
20973 /* Remember that the name was used in the definition of the
20974 current class so that we can check later to see if the
20975 meaning would have been different after the class was
20976 entirely defined. */
20977 else if (type_decl != error_mark_node
20978 && !parser->scope)
20979 maybe_note_name_used_in_class (identifier, type_decl);
20980
20981 return type_decl;
20982}
20983
20984/* Parse an elaborated-type-specifier. Note that the grammar given
20985 here incorporates the resolution to DR68.
20986
20987 elaborated-type-specifier:
20988 class-key :: [opt] nested-name-specifier [opt] identifier
20989 class-key :: [opt] nested-name-specifier [opt] template [opt] template-id
20990 enum-key :: [opt] nested-name-specifier [opt] identifier
20991 typename :: [opt] nested-name-specifier identifier
20992 typename :: [opt] nested-name-specifier template [opt]
20993 template-id
20994
20995 GNU extension:
20996
20997 elaborated-type-specifier:
20998 class-key attributes :: [opt] nested-name-specifier [opt] identifier
20999 class-key attributes :: [opt] nested-name-specifier [opt]
21000 template [opt] template-id
21001 enum attributes :: [opt] nested-name-specifier [opt] identifier
21002
21003 If IS_FRIEND is TRUE, then this elaborated-type-specifier is being
21004 declared `friend'. If IS_DECLARATION is TRUE, then this
21005 elaborated-type-specifier appears in a decl-specifiers-seq, i.e.,
21006 something is being declared.
21007
21008 Returns the TYPE specified. */
21009
21010static tree
21011cp_parser_elaborated_type_specifier (cp_parser* parser,
21012 bool is_friend,
21013 bool is_declaration)
21014{
21015 enum tag_types tag_type;
21016 tree identifier;
21017 tree type = NULL_TREE;
21018 tree attributes = NULL_TREE;
21019 tree globalscope;
21020 cp_token *token = NULL;
21021
21022 /* For class and enum types the location of the class-key or enum-key. */
21023 location_t key_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
21024 /* For a scoped enum, the 'class' or 'struct' keyword id. */
21025 rid scoped_key = RID_MAX;
21026
21027 /* See if we're looking at the `enum' keyword. */
21028 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_ENUM))
21029 {
21030 /* Consume the `enum' token. */
21031 cp_lexer_consume_token (lexer: parser->lexer);
21032 /* Remember that it's an enumeration type. */
21033 tag_type = enum_type;
21034 /* Issue a warning if the `struct' or `class' key (for C++0x scoped
21035 enums) is used here. */
21036 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
21037 if (cp_parser_is_keyword (token, keyword: scoped_key = RID_CLASS)
21038 || cp_parser_is_keyword (token, keyword: scoped_key = RID_STRUCT))
21039 {
21040 location_t loc = token->location;
21041 gcc_rich_location richloc (loc);
21042 richloc.add_range (loc: input_location);
21043 richloc.add_fixit_remove ();
21044 pedwarn (&richloc, 0, "elaborated-type-specifier for "
21045 "a scoped enum must not use the %qD keyword",
21046 token->u.value);
21047 /* Consume the `struct' or `class' and parse it anyway. */
21048 cp_lexer_consume_token (lexer: parser->lexer);
21049 /* Create a combined location for the whole scoped-enum-key. */
21050 key_loc = make_location (caret: key_loc, start: key_loc, finish: loc);
21051 }
21052 else
21053 scoped_key = RID_MAX;
21054
21055 /* Parse the attributes. */
21056 attributes = cp_parser_attributes_opt (parser);
21057 }
21058 /* Or, it might be `typename'. */
21059 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer,
21060 keyword: RID_TYPENAME))
21061 {
21062 /* Consume the `typename' token. */
21063 cp_lexer_consume_token (lexer: parser->lexer);
21064 /* Remember that it's a `typename' type. */
21065 tag_type = typename_type;
21066 }
21067 /* Otherwise it must be a class-key. */
21068 else
21069 {
21070 key_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
21071 tag_type = cp_parser_class_key (parser);
21072 if (tag_type == none_type)
21073 return error_mark_node;
21074 /* Parse the attributes. */
21075 attributes = cp_parser_attributes_opt (parser);
21076 }
21077
21078 /* Look for the `::' operator. */
21079 globalscope = cp_parser_global_scope_opt (parser,
21080 /*current_scope_valid_p=*/false);
21081 /* Look for the nested-name-specifier. */
21082 tree nested_name_specifier;
21083 if (tag_type == typename_type && !globalscope)
21084 {
21085 nested_name_specifier
21086 = cp_parser_nested_name_specifier (parser,
21087 /*typename_keyword_p=*/true,
21088 /*check_dependency_p=*/true,
21089 /*type_p=*/true,
21090 is_declaration);
21091 if (!nested_name_specifier)
21092 return error_mark_node;
21093 }
21094 else
21095 /* Even though `typename' is not present, the proposed resolution
21096 to Core Issue 180 says that in `class A<T>::B', `B' should be
21097 considered a type-name, even if `A<T>' is dependent. */
21098 nested_name_specifier
21099 = cp_parser_nested_name_specifier_opt (parser,
21100 /*typename_keyword_p=*/true,
21101 /*check_dependency_p=*/true,
21102 /*type_p=*/true,
21103 is_declaration);
21104 /* For everything but enumeration types, consider a template-id.
21105 For an enumeration type, consider only a plain identifier. */
21106 if (tag_type != enum_type)
21107 {
21108 bool template_p = false;
21109 tree decl;
21110
21111 /* Allow the `template' keyword. */
21112 template_p = cp_parser_optional_template_keyword (parser);
21113 /* If we didn't see `template', we don't know if there's a
21114 template-id or not. */
21115 if (!template_p)
21116 cp_parser_parse_tentatively (parser);
21117 /* The `template' keyword must follow a nested-name-specifier. */
21118 else if (!nested_name_specifier && !globalscope)
21119 {
21120 cp_parser_error (parser, gmsgid: "%<template%> must follow a nested-"
21121 "name-specifier");
21122 return error_mark_node;
21123 }
21124
21125 /* Parse the template-id. */
21126 token = cp_lexer_peek_token (lexer: parser->lexer);
21127 decl = cp_parser_template_id (parser, template_keyword_p: template_p,
21128 /*check_dependency_p=*/true,
21129 tag_type,
21130 is_declaration);
21131 /* If we didn't find a template-id, look for an ordinary
21132 identifier. */
21133 if (!template_p && !cp_parser_parse_definitely (parser))
21134 ;
21135 /* We can get here when cp_parser_template_id, called by
21136 cp_parser_class_name with tag_type == none_type, succeeds
21137 and caches a BASELINK. Then, when called again here,
21138 instead of failing and returning an error_mark_node
21139 returns it (see template/typename17.C in C++11).
21140 ??? Could we diagnose this earlier? */
21141 else if (tag_type == typename_type && BASELINK_P (decl))
21142 {
21143 cp_parser_diagnose_invalid_type_name (parser, id: decl, location: token->location);
21144 type = error_mark_node;
21145 }
21146 /* If DECL is a TEMPLATE_ID_EXPR, and the `typename' keyword is
21147 in effect, then we must assume that, upon instantiation, the
21148 template will correspond to a class. */
21149 else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
21150 && tag_type == typename_type)
21151 type = make_typename_type (parser->scope, decl,
21152 typename_type,
21153 /*complain=*/tf_error);
21154 /* If the `typename' keyword is in effect and DECL is not a type
21155 decl, then type is non existent. */
21156 else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
21157 ;
21158 else if (TREE_CODE (decl) == TYPE_DECL)
21159 {
21160 type = check_elaborated_type_specifier (tag_type, decl,
21161 /*allow_template_p=*/true);
21162
21163 /* If the next token is a semicolon, this must be a specialization,
21164 instantiation, or friend declaration. Check the scope while we
21165 still know whether or not we had a nested-name-specifier. */
21166 if (type != error_mark_node
21167 && !nested_name_specifier && !is_friend
21168 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
21169 check_unqualified_spec_or_inst (type, token->location);
21170 }
21171 else if (decl == error_mark_node)
21172 type = error_mark_node;
21173 }
21174
21175 if (!type)
21176 {
21177 token = cp_lexer_peek_token (lexer: parser->lexer);
21178 identifier = cp_parser_identifier (parser);
21179
21180 if (identifier == error_mark_node)
21181 {
21182 parser->scope = NULL_TREE;
21183 return error_mark_node;
21184 }
21185
21186 /* For a `typename', we needn't call xref_tag. */
21187 if (tag_type == typename_type
21188 && TREE_CODE (parser->scope) != NAMESPACE_DECL)
21189 return cp_parser_make_typename_type (parser, id: identifier,
21190 id_location: token->location);
21191
21192 /* Template parameter lists apply only if we are not within a
21193 function parameter list. */
21194 bool template_parm_lists_apply
21195 = parser->num_template_parameter_lists;
21196 if (template_parm_lists_apply)
21197 for (cp_binding_level *s = current_binding_level;
21198 s && s->kind != sk_template_parms;
21199 s = s->level_chain)
21200 if (s->kind == sk_function_parms)
21201 template_parm_lists_apply = false;
21202
21203 /* Look up a qualified name in the usual way. */
21204 if (parser->scope)
21205 {
21206 tree decl;
21207 tree ambiguous_decls;
21208
21209 decl = cp_parser_lookup_name (parser, identifier,
21210 tag_type,
21211 /*is_template=*/false,
21212 /*is_namespace=*/false,
21213 /*check_dependency=*/true,
21214 &ambiguous_decls,
21215 token->location);
21216
21217 /* If the lookup was ambiguous, an error will already have been
21218 issued. */
21219 if (ambiguous_decls)
21220 return error_mark_node;
21221
21222 /* If we are parsing friend declaration, DECL may be a
21223 TEMPLATE_DECL tree node here. However, we need to check
21224 whether this TEMPLATE_DECL results in valid code. Consider
21225 the following example:
21226
21227 namespace N {
21228 template <class T> class C {};
21229 }
21230 class X {
21231 template <class T> friend class N::C; // #1, valid code
21232 };
21233 template <class T> class Y {
21234 friend class N::C; // #2, invalid code
21235 };
21236
21237 For both case #1 and #2, we arrive at a TEMPLATE_DECL after
21238 name lookup of `N::C'. We see that friend declaration must
21239 be template for the code to be valid. Note that
21240 processing_template_decl does not work here since it is
21241 always 1 for the above two cases. */
21242
21243 decl = (cp_parser_maybe_treat_template_as_class
21244 (decl, /*tag_name_p=*/is_friend
21245 && template_parm_lists_apply));
21246
21247 if (TREE_CODE (decl) != TYPE_DECL)
21248 {
21249 cp_parser_diagnose_invalid_type_name (parser,
21250 id: identifier,
21251 location: token->location);
21252 return error_mark_node;
21253 }
21254
21255 if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
21256 {
21257 bool allow_template = (template_parm_lists_apply
21258 || DECL_SELF_REFERENCE_P (decl));
21259 type = check_elaborated_type_specifier (tag_type, decl,
21260 allow_template);
21261
21262 if (type == error_mark_node)
21263 return error_mark_node;
21264 }
21265
21266 /* Forward declarations of nested types, such as
21267
21268 class C1::C2;
21269 class C1::C2::C3;
21270
21271 are invalid unless all components preceding the final '::'
21272 are complete. If all enclosing types are complete, these
21273 declarations become merely pointless.
21274
21275 Invalid forward declarations of nested types are errors
21276 caught elsewhere in parsing. Those that are pointless arrive
21277 here. */
21278
21279 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)
21280 && !is_friend && is_declaration
21281 && !processing_explicit_instantiation)
21282 warning (0, "declaration %qD does not declare anything", decl);
21283
21284 type = TREE_TYPE (decl);
21285 }
21286 else
21287 {
21288 /* An elaborated-type-specifier sometimes introduces a new type and
21289 sometimes names an existing type. Normally, the rule is that it
21290 introduces a new type only if there is not an existing type of
21291 the same name already in scope. For example, given:
21292
21293 struct S {};
21294 void f() { struct S s; }
21295
21296 the `struct S' in the body of `f' is the same `struct S' as in
21297 the global scope; the existing definition is used. However, if
21298 there were no global declaration, this would introduce a new
21299 local class named `S'.
21300
21301 An exception to this rule applies to the following code:
21302
21303 namespace N { struct S; }
21304
21305 Here, the elaborated-type-specifier names a new type
21306 unconditionally; even if there is already an `S' in the
21307 containing scope this declaration names a new type.
21308 This exception only applies if the elaborated-type-specifier
21309 forms the complete declaration:
21310
21311 [class.name]
21312
21313 A declaration consisting solely of `class-key identifier ;' is
21314 either a redeclaration of the name in the current scope or a
21315 forward declaration of the identifier as a class name. It
21316 introduces the name into the current scope.
21317
21318 We are in this situation precisely when the next token is a `;'.
21319
21320 An exception to the exception is that a `friend' declaration does
21321 *not* name a new type; i.e., given:
21322
21323 struct S { friend struct T; };
21324
21325 `T' is not a new type in the scope of `S'.
21326
21327 Also, `new struct S' or `sizeof (struct S)' never results in the
21328 definition of a new type; a new type can only be declared in a
21329 declaration context. */
21330
21331 TAG_how how;
21332
21333 if (is_friend)
21334 /* Friends have special name lookup rules. */
21335 how = TAG_how::HIDDEN_FRIEND;
21336 else if (is_declaration
21337 && cp_lexer_next_token_is (lexer: parser->lexer,
21338 type: CPP_SEMICOLON))
21339 /* This is a `class-key identifier ;' */
21340 how = TAG_how::CURRENT_ONLY;
21341 else
21342 how = TAG_how::GLOBAL;
21343
21344 bool template_p =
21345 (template_parm_lists_apply
21346 && (cp_parser_next_token_starts_class_definition_p (parser)
21347 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)));
21348 /* An unqualified name was used to reference this type, so
21349 there were no qualifying templates. */
21350 if (template_parm_lists_apply
21351 && !cp_parser_check_template_parameters (parser,
21352 /*num_templates=*/0,
21353 /*template_id*/false,
21354 token->location,
21355 /*declarator=*/NULL))
21356 return error_mark_node;
21357
21358 type = xref_tag (tag_type, identifier, how, tpl_header_p: template_p);
21359 }
21360 }
21361
21362 if (type == error_mark_node)
21363 return error_mark_node;
21364
21365 /* Allow attributes on forward declarations of classes. */
21366 if (attributes)
21367 {
21368 if (TREE_CODE (type) == TYPENAME_TYPE)
21369 warning (OPT_Wattributes,
21370 "attributes ignored on uninstantiated type");
21371 else if (tag_type != enum_type
21372 && TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM
21373 && CLASSTYPE_TEMPLATE_INSTANTIATION (type)
21374 && ! processing_explicit_instantiation)
21375 warning (OPT_Wattributes,
21376 "attributes ignored on template instantiation");
21377 else if (is_friend && cxx11_attribute_p (attributes))
21378 {
21379 if (warning (OPT_Wattributes, "attribute ignored"))
21380 inform (input_location, "an attribute that appertains to a friend "
21381 "declaration that is not a definition is ignored");
21382 }
21383 else if (is_declaration && cp_parser_declares_only_class_p (parser))
21384 cplus_decl_attributes (&type, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
21385 else
21386 warning (OPT_Wattributes,
21387 "attributes ignored on elaborated-type-specifier that is "
21388 "not a forward declaration");
21389 }
21390
21391 if (tag_type == enum_type)
21392 cp_parser_maybe_warn_enum_key (parser, key_loc, type, scoped_key);
21393 else
21394 {
21395 /* Diagnose class/struct/union mismatches. IS_DECLARATION is false
21396 for alias definition. */
21397 bool decl_class = (is_declaration
21398 && cp_parser_declares_only_class_p (parser));
21399 cp_parser_check_class_key (parser, key_loc, tag_type, type, false,
21400 decl_class);
21401
21402 /* Indicate whether this class was declared as a `class' or as a
21403 `struct'. */
21404 if (CLASS_TYPE_P (type) && !currently_open_class (type))
21405 CLASSTYPE_DECLARED_CLASS (type) = (tag_type == class_type);
21406 }
21407
21408 /* A "<" cannot follow an elaborated type specifier. If that
21409 happens, the user was probably trying to form a template-id. */
21410 cp_parser_check_for_invalid_template_id (parser, type, tag_type,
21411 location: token->location);
21412
21413 return type;
21414}
21415
21416/* Parse an enum-specifier.
21417
21418 enum-specifier:
21419 enum-head { enumerator-list [opt] }
21420 enum-head { enumerator-list , } [C++0x]
21421
21422 enum-head:
21423 enum-key identifier [opt] enum-base [opt]
21424 enum-key nested-name-specifier identifier enum-base [opt]
21425
21426 enum-key:
21427 enum
21428 enum class [C++0x]
21429 enum struct [C++0x]
21430
21431 enum-base: [C++0x]
21432 : type-specifier-seq
21433
21434 opaque-enum-specifier:
21435 enum-key identifier enum-base [opt] ;
21436
21437 GNU Extensions:
21438 enum-key attributes[opt] identifier [opt] enum-base [opt]
21439 { enumerator-list [opt] }attributes[opt]
21440 enum-key attributes[opt] identifier [opt] enum-base [opt]
21441 { enumerator-list, }attributes[opt] [C++0x]
21442
21443 Returns an ENUM_TYPE representing the enumeration, or NULL_TREE
21444 if the token stream isn't an enum-specifier after all. */
21445
21446static tree
21447cp_parser_enum_specifier (cp_parser* parser)
21448{
21449 tree identifier;
21450 tree type = NULL_TREE;
21451 tree prev_scope;
21452 tree nested_name_specifier = NULL_TREE;
21453 tree attributes;
21454 bool scoped_enum_p = false;
21455 bool has_underlying_type = false;
21456 bool nested_being_defined = false;
21457 bool new_value_list = false;
21458 bool is_new_type = false;
21459 bool is_unnamed = false;
21460 tree underlying_type = NULL_TREE;
21461 cp_token *type_start_token = NULL;
21462 auto cleanup = make_temp_override (var&: parser->colon_corrects_to_scope_p, overrider: false);
21463
21464 /* Parse tentatively so that we can back up if we don't find a
21465 enum-specifier. */
21466 cp_parser_parse_tentatively (parser);
21467
21468 /* Caller guarantees that the current token is 'enum', an identifier
21469 possibly follows, and the token after that is an opening brace.
21470 If we don't have an identifier, fabricate an anonymous name for
21471 the enumeration being defined. */
21472 cp_lexer_consume_token (lexer: parser->lexer);
21473
21474 /* Parse the "class" or "struct", which indicates a scoped
21475 enumeration type in C++0x. */
21476 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_CLASS)
21477 || cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_STRUCT))
21478 {
21479 if (cxx_dialect < cxx11)
21480 maybe_warn_cpp0x (str: CPP0X_SCOPED_ENUMS);
21481
21482 /* Consume the `struct' or `class' token. */
21483 cp_lexer_consume_token (lexer: parser->lexer);
21484
21485 scoped_enum_p = true;
21486 }
21487
21488 attributes = cp_parser_attributes_opt (parser);
21489
21490 /* Clear the qualification. */
21491 parser->scope = NULL_TREE;
21492 parser->qualifying_scope = NULL_TREE;
21493 parser->object_scope = NULL_TREE;
21494
21495 /* Figure out in what scope the declaration is being placed. */
21496 prev_scope = current_scope ();
21497
21498 type_start_token = cp_lexer_peek_token (lexer: parser->lexer);
21499
21500 push_deferring_access_checks (dk_no_check);
21501 nested_name_specifier
21502 = cp_parser_nested_name_specifier_opt (parser,
21503 /*typename_keyword_p=*/true,
21504 /*check_dependency_p=*/false,
21505 /*type_p=*/false,
21506 /*is_declaration=*/false);
21507
21508 if (nested_name_specifier)
21509 {
21510 tree name;
21511
21512 identifier = cp_parser_identifier (parser);
21513 name = cp_parser_lookup_name (parser, identifier,
21514 enum_type,
21515 /*is_template=*/false,
21516 /*is_namespace=*/false,
21517 /*check_dependency=*/true,
21518 /*ambiguous_decls=*/NULL,
21519 input_location);
21520 if (name && name != error_mark_node)
21521 {
21522 type = TREE_TYPE (name);
21523 if (TREE_CODE (type) == TYPENAME_TYPE)
21524 {
21525 /* Are template enums allowed in ISO? */
21526 if (template_parm_scope_p ())
21527 pedwarn (type_start_token->location, OPT_Wpedantic,
21528 "%qD is an enumeration template", name);
21529 /* ignore a typename reference, for it will be solved by name
21530 in start_enum. */
21531 type = NULL_TREE;
21532 }
21533 }
21534 else if (nested_name_specifier == error_mark_node)
21535 /* We already issued an error. */;
21536 else
21537 {
21538 error_at (type_start_token->location,
21539 "%qD does not name an enumeration in %qT",
21540 identifier, nested_name_specifier);
21541 nested_name_specifier = error_mark_node;
21542 }
21543 }
21544 else
21545 {
21546 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
21547 identifier = cp_parser_identifier (parser);
21548 else
21549 {
21550 identifier = make_anon_name ();
21551 is_unnamed = true;
21552 if (scoped_enum_p)
21553 error_at (type_start_token->location,
21554 "unnamed scoped enum is not allowed");
21555 }
21556 }
21557 pop_deferring_access_checks ();
21558
21559 /* Check for the `:' that denotes a specified underlying type in C++0x.
21560 Note that a ':' could also indicate a bitfield width, however. */
21561 location_t colon_loc = UNKNOWN_LOCATION;
21562 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
21563 {
21564 cp_decl_specifier_seq type_specifiers;
21565
21566 /* Consume the `:'. */
21567 colon_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
21568 cp_lexer_consume_token (lexer: parser->lexer);
21569
21570 auto tdf
21571 = make_temp_override (var&: parser->type_definition_forbidden_message,
21572 G_("types may not be defined in enum-base"));
21573
21574 /* Parse the type-specifier-seq. */
21575 cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
21576 /*is_declaration=*/false,
21577 /*is_trailing_return=*/false,
21578 &type_specifiers);
21579
21580 /* At this point this is surely not elaborated type specifier. */
21581 if (!cp_parser_parse_definitely (parser))
21582 return NULL_TREE;
21583
21584 if (cxx_dialect < cxx11)
21585 maybe_warn_cpp0x (str: CPP0X_SCOPED_ENUMS);
21586
21587 has_underlying_type = true;
21588
21589 /* If that didn't work, stop. */
21590 if (type_specifiers.type != error_mark_node)
21591 {
21592 underlying_type = grokdeclarator (NULL, &type_specifiers, TYPENAME,
21593 /*initialized=*/0, NULL);
21594 if (underlying_type == error_mark_node
21595 || check_for_bare_parameter_packs (underlying_type))
21596 underlying_type = NULL_TREE;
21597 }
21598 }
21599
21600 /* Look for the `{' but don't consume it yet. */
21601 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
21602 {
21603 if (cxx_dialect < cxx11 || (!scoped_enum_p && !underlying_type))
21604 {
21605 if (has_underlying_type)
21606 cp_parser_commit_to_tentative_parse (parser);
21607 cp_parser_error (parser, gmsgid: "expected %<{%>");
21608 if (has_underlying_type)
21609 return error_mark_node;
21610 }
21611 /* An opaque-enum-specifier must have a ';' here. */
21612 if ((scoped_enum_p || underlying_type)
21613 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
21614 {
21615 if (has_underlying_type)
21616 pedwarn (colon_loc,
21617 OPT_Welaborated_enum_base,
21618 "declaration of enumeration with "
21619 "fixed underlying type and no enumerator list is "
21620 "only permitted as a standalone declaration");
21621 else
21622 cp_parser_error (parser, gmsgid: "expected %<;%> or %<{%>");
21623 }
21624 }
21625
21626 if (!has_underlying_type && !cp_parser_parse_definitely (parser))
21627 return NULL_TREE;
21628
21629 if (nested_name_specifier)
21630 {
21631 if (CLASS_TYPE_P (nested_name_specifier))
21632 {
21633 nested_being_defined = TYPE_BEING_DEFINED (nested_name_specifier);
21634 TYPE_BEING_DEFINED (nested_name_specifier) = 1;
21635 push_scope (nested_name_specifier);
21636 }
21637 else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
21638 push_nested_namespace (nested_name_specifier);
21639 }
21640
21641 /* Issue an error message if type-definitions are forbidden here. */
21642 if (!cp_parser_check_type_definition (parser))
21643 type = error_mark_node;
21644 else
21645 /* Create the new type. We do this before consuming the opening
21646 brace so the enum will be recorded as being on the line of its
21647 tag (or the 'enum' keyword, if there is no tag). */
21648 type = start_enum (identifier, type, underlying_type,
21649 attributes, scoped_enum_p, &is_new_type);
21650
21651 /* If the next token is not '{' it is an opaque-enum-specifier or an
21652 elaborated-type-specifier. */
21653 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
21654 {
21655 auto_timevar tv (TV_PARSE_ENUM);
21656
21657 if (nested_name_specifier
21658 && nested_name_specifier != error_mark_node)
21659 {
21660 /* The following catches invalid code such as:
21661 enum class S<int>::E { A, B, C }; */
21662 if (!processing_specialization
21663 && CLASS_TYPE_P (nested_name_specifier)
21664 && CLASSTYPE_USE_TEMPLATE (nested_name_specifier))
21665 error_at (type_start_token->location, "cannot add an enumerator "
21666 "list to a template instantiation");
21667
21668 if (TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
21669 {
21670 error_at (type_start_token->location,
21671 "%<%T::%E%> has not been declared",
21672 TYPE_CONTEXT (nested_name_specifier),
21673 nested_name_specifier);
21674 type = error_mark_node;
21675 }
21676 else if (TREE_CODE (nested_name_specifier) != NAMESPACE_DECL
21677 && !CLASS_TYPE_P (nested_name_specifier))
21678 {
21679 error_at (type_start_token->location, "nested name specifier "
21680 "%qT for enum declaration does not name a class "
21681 "or namespace", nested_name_specifier);
21682 type = error_mark_node;
21683 }
21684 /* If that scope does not contain the scope in which the
21685 class was originally declared, the program is invalid. */
21686 else if (prev_scope && !is_ancestor (ancestor: prev_scope,
21687 descendant: nested_name_specifier))
21688 {
21689 if (at_namespace_scope_p ())
21690 error_at (type_start_token->location,
21691 "declaration of %qD in namespace %qD which does not "
21692 "enclose %qD",
21693 type, prev_scope, nested_name_specifier);
21694 else
21695 error_at (type_start_token->location,
21696 "declaration of %qD in %qD which does not "
21697 "enclose %qD",
21698 type, prev_scope, nested_name_specifier);
21699 type = error_mark_node;
21700 }
21701 /* If that scope is the scope where the declaration is being placed
21702 the program is invalid. */
21703 else if (CLASS_TYPE_P (nested_name_specifier)
21704 && CLASS_TYPE_P (prev_scope)
21705 && same_type_p (nested_name_specifier, prev_scope))
21706 {
21707 permerror (type_start_token->location,
21708 "extra qualification not allowed");
21709 nested_name_specifier = NULL_TREE;
21710 }
21711 }
21712
21713 if (scoped_enum_p)
21714 begin_scope (sk_scoped_enum, type);
21715
21716 /* Consume the opening brace. */
21717 matching_braces braces;
21718 braces.consume_open (parser);
21719
21720 if (type == error_mark_node)
21721 ; /* Nothing to add */
21722 else if (OPAQUE_ENUM_P (type)
21723 || (cxx_dialect > cxx98 && processing_specialization))
21724 {
21725 new_value_list = true;
21726 SET_OPAQUE_ENUM_P (type, false);
21727 DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
21728 }
21729 else
21730 {
21731 error_at (type_start_token->location,
21732 "multiple definition of %q#T", type);
21733 inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
21734 "previous definition here");
21735 type = error_mark_node;
21736 }
21737
21738 if (type == error_mark_node)
21739 cp_parser_skip_to_end_of_block_or_statement (parser);
21740 /* If the next token is not '}', then there are some enumerators. */
21741 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
21742 {
21743 if (is_unnamed && !scoped_enum_p
21744 /* Don't warn for enum {} a; here. */
21745 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_SEMICOLON))
21746 pedwarn (type_start_token->location, OPT_Wpedantic,
21747 "ISO C++ forbids empty unnamed enum");
21748 }
21749 else
21750 {
21751 /* We've seen a '{' so we know we're in an enum-specifier.
21752 Commit to any tentative parse to get syntax errors. */
21753 cp_parser_commit_to_tentative_parse (parser);
21754 cp_parser_enumerator_list (parser, type);
21755 }
21756
21757 /* Consume the final '}'. */
21758 braces.require_close (parser);
21759
21760 if (scoped_enum_p)
21761 finish_scope ();
21762 }
21763 else
21764 {
21765 /* If a ';' follows, then it is an opaque-enum-specifier
21766 and additional restrictions apply. */
21767 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
21768 {
21769 if (is_unnamed)
21770 error_at (type_start_token->location,
21771 "opaque-enum-specifier without name");
21772 else if (nested_name_specifier)
21773 error_at (type_start_token->location,
21774 "opaque-enum-specifier must use a simple identifier");
21775 }
21776 }
21777
21778 /* Look for trailing attributes to apply to this enumeration, and
21779 apply them if appropriate. */
21780 if (cp_parser_allow_gnu_extensions_p (parser))
21781 {
21782 tree trailing_attr = cp_parser_gnu_attributes_opt (parser);
21783 cplus_decl_attributes (&type,
21784 trailing_attr,
21785 (int) ATTR_FLAG_TYPE_IN_PLACE);
21786 }
21787
21788 /* Finish up the enumeration. */
21789 if (type != error_mark_node)
21790 {
21791 if (new_value_list)
21792 finish_enum_value_list (type);
21793 if (is_new_type)
21794 finish_enum (type);
21795 }
21796
21797 if (nested_name_specifier)
21798 {
21799 if (CLASS_TYPE_P (nested_name_specifier))
21800 {
21801 TYPE_BEING_DEFINED (nested_name_specifier) = nested_being_defined;
21802 pop_scope (nested_name_specifier);
21803 }
21804 else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
21805 pop_nested_namespace (nested_name_specifier);
21806 }
21807 return type;
21808}
21809
21810/* Parse an enumerator-list. The enumerators all have the indicated
21811 TYPE.
21812
21813 enumerator-list:
21814 enumerator-definition
21815 enumerator-list , enumerator-definition */
21816
21817static void
21818cp_parser_enumerator_list (cp_parser* parser, tree type)
21819{
21820 while (true)
21821 {
21822 /* Parse an enumerator-definition. */
21823 cp_parser_enumerator_definition (parser, type);
21824
21825 /* If the next token is not a ',', we've reached the end of
21826 the list. */
21827 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
21828 break;
21829 /* Otherwise, consume the `,' and keep going. */
21830 cp_lexer_consume_token (lexer: parser->lexer);
21831 /* If the next token is a `}', there is a trailing comma. */
21832 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
21833 {
21834 if (cxx_dialect < cxx11)
21835 pedwarn (input_location, OPT_Wpedantic,
21836 "comma at end of enumerator list");
21837 break;
21838 }
21839 }
21840}
21841
21842/* Parse an enumerator-definition. The enumerator has the indicated
21843 TYPE.
21844
21845 enumerator-definition:
21846 enumerator
21847 enumerator = constant-expression
21848
21849 enumerator:
21850 identifier
21851
21852 GNU Extensions:
21853
21854 enumerator-definition:
21855 enumerator attributes [opt]
21856 enumerator attributes [opt] = constant-expression */
21857
21858static void
21859cp_parser_enumerator_definition (cp_parser* parser, tree type)
21860{
21861 tree identifier;
21862 tree value;
21863 location_t loc;
21864
21865 /* Save the input location because we are interested in the location
21866 of the identifier and not the location of the explicit value. */
21867 loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
21868
21869 /* Look for the identifier. */
21870 identifier = cp_parser_identifier (parser);
21871 if (identifier == error_mark_node)
21872 return;
21873
21874 /* Parse any specified attributes. */
21875 tree attrs = cp_parser_attributes_opt (parser);
21876
21877 /* If the next token is an '=', then there is an explicit value. */
21878 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
21879 {
21880 /* Consume the `=' token. */
21881 cp_lexer_consume_token (lexer: parser->lexer);
21882 /* Parse the value. */
21883 value = cp_parser_constant_expression (parser);
21884 }
21885 else
21886 value = NULL_TREE;
21887
21888 /* If we are processing a template, make sure the initializer of the
21889 enumerator doesn't contain any bare template parameter pack. */
21890 if (current_lambda_expr ())
21891 {
21892 /* In a lambda it should work, but doesn't currently. */
21893 if (uses_parameter_packs (value))
21894 {
21895 sorry ("unexpanded parameter pack in enumerator in lambda");
21896 value = error_mark_node;
21897 }
21898 }
21899 else if (check_for_bare_parameter_packs (value))
21900 value = error_mark_node;
21901
21902 /* Create the enumerator. */
21903 build_enumerator (identifier, value, type, attrs, loc);
21904}
21905
21906/* Parse a namespace-name.
21907
21908 namespace-name:
21909 original-namespace-name
21910 namespace-alias
21911
21912 Returns the NAMESPACE_DECL for the namespace. */
21913
21914static tree
21915cp_parser_namespace_name (cp_parser* parser)
21916{
21917 tree identifier;
21918 tree namespace_decl;
21919
21920 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
21921
21922 /* Get the name of the namespace. */
21923 identifier = cp_parser_identifier (parser);
21924 if (identifier == error_mark_node)
21925 return error_mark_node;
21926
21927 /* Look up the identifier in the currently active scope. Look only
21928 for namespaces, due to:
21929
21930 [basic.lookup.udir]
21931
21932 When looking up a namespace-name in a using-directive or alias
21933 definition, only namespace names are considered.
21934
21935 And:
21936
21937 [basic.lookup.qual]
21938
21939 During the lookup of a name preceding the :: scope resolution
21940 operator, object, function, and enumerator names are ignored.
21941
21942 (Note that cp_parser_qualifying_entity only calls this
21943 function if the token after the name is the scope resolution
21944 operator.) */
21945 namespace_decl = cp_parser_lookup_name (parser, identifier,
21946 none_type,
21947 /*is_template=*/false,
21948 /*is_namespace=*/true,
21949 /*check_dependency=*/true,
21950 /*ambiguous_decls=*/NULL,
21951 token->location);
21952 /* If it's not a namespace, issue an error. */
21953 if (namespace_decl == error_mark_node
21954 || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
21955 {
21956 if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
21957 {
21958 auto_diagnostic_group d;
21959 name_hint hint;
21960 if (namespace_decl == error_mark_node
21961 && parser->scope && TREE_CODE (parser->scope) == NAMESPACE_DECL)
21962 hint = suggest_alternative_in_explicit_scope (token->location,
21963 identifier,
21964 parser->scope);
21965 if (const char *suggestion = hint.suggestion ())
21966 {
21967 gcc_rich_location richloc (token->location);
21968 richloc.add_fixit_replace (new_content: suggestion);
21969 error_at (&richloc,
21970 "%qD is not a namespace-name; did you mean %qs?",
21971 identifier, suggestion);
21972 }
21973 else
21974 error_at (token->location, "%qD is not a namespace-name",
21975 identifier);
21976 }
21977 else
21978 cp_parser_error (parser, gmsgid: "expected namespace-name");
21979 namespace_decl = error_mark_node;
21980 }
21981
21982 return namespace_decl;
21983}
21984
21985/* Parse a namespace-definition.
21986
21987 namespace-definition:
21988 named-namespace-definition
21989 unnamed-namespace-definition
21990
21991 named-namespace-definition:
21992 original-namespace-definition
21993 extension-namespace-definition
21994
21995 original-namespace-definition:
21996 namespace identifier { namespace-body }
21997
21998 extension-namespace-definition:
21999 namespace original-namespace-name { namespace-body }
22000
22001 unnamed-namespace-definition:
22002 namespace { namespace-body } */
22003
22004static void
22005cp_parser_namespace_definition (cp_parser* parser)
22006{
22007 tree identifier;
22008 int nested_definition_count = 0;
22009
22010 cp_ensure_no_omp_declare_simd (parser);
22011 cp_ensure_no_oacc_routine (parser);
22012
22013 bool is_inline = cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_INLINE);
22014 const bool topmost_inline_p = is_inline;
22015
22016 if (is_inline)
22017 {
22018 maybe_warn_cpp0x (str: CPP0X_INLINE_NAMESPACES);
22019 cp_lexer_consume_token (lexer: parser->lexer);
22020 }
22021
22022 /* Look for the `namespace' keyword. */
22023 cp_token* token
22024 = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
22025
22026 /* Parse any specified attributes before the identifier. */
22027 tree attribs = cp_parser_attributes_opt (parser);
22028
22029 for (;;)
22030 {
22031 identifier = NULL_TREE;
22032
22033 bool nested_inline_p = cp_lexer_next_token_is_keyword (lexer: parser->lexer,
22034 keyword: RID_INLINE);
22035 if (nested_inline_p && nested_definition_count != 0)
22036 {
22037 if (pedantic && cxx_dialect < cxx20)
22038 pedwarn (cp_lexer_peek_token (lexer: parser->lexer)->location,
22039 OPT_Wc__20_extensions, "nested inline namespace "
22040 "definitions only available with %<-std=c++20%> or "
22041 "%<-std=gnu++20%>");
22042 cp_lexer_consume_token (lexer: parser->lexer);
22043 }
22044
22045 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
22046 {
22047 identifier = cp_parser_identifier (parser);
22048
22049 if (cp_next_tokens_can_be_std_attribute_p (parser))
22050 pedwarn (input_location, OPT_Wpedantic,
22051 "standard attributes on namespaces must precede "
22052 "the namespace name");
22053
22054 /* Parse any attributes specified after the identifier. */
22055 attribs = attr_chainon (attrs: attribs, attr: cp_parser_attributes_opt (parser));
22056 }
22057
22058 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SCOPE))
22059 {
22060 /* Don't forget that the innermost namespace might have been
22061 marked as inline. Use |= because we cannot overwrite
22062 IS_INLINE in case the outermost namespace is inline, but
22063 there are no nested inlines. */
22064 is_inline |= nested_inline_p;
22065 break;
22066 }
22067
22068 if (!nested_definition_count && pedantic && cxx_dialect < cxx17)
22069 pedwarn (input_location, OPT_Wc__17_extensions,
22070 "nested namespace definitions only available with "
22071 "%<-std=c++17%> or %<-std=gnu++17%>");
22072
22073 /* Nested namespace names can create new namespaces (unlike
22074 other qualified-ids). */
22075 if (int count = (identifier
22076 ? push_namespace (identifier, make_inline: nested_inline_p)
22077 : 0))
22078 nested_definition_count += count;
22079 else
22080 cp_parser_error (parser, gmsgid: "nested namespace name required");
22081 cp_lexer_consume_token (lexer: parser->lexer);
22082 }
22083
22084 if (nested_definition_count && !identifier)
22085 cp_parser_error (parser, gmsgid: "namespace name required");
22086
22087 if (nested_definition_count && attribs)
22088 error_at (token->location,
22089 "a nested namespace definition cannot have attributes");
22090 if (nested_definition_count && topmost_inline_p)
22091 error_at (token->location,
22092 "a nested namespace definition cannot be inline");
22093
22094 /* Start the namespace. */
22095 nested_definition_count += push_namespace (identifier, make_inline: is_inline);
22096
22097 bool has_visibility = handle_namespace_attrs (current_namespace, attribs);
22098
22099 warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
22100
22101 /* Look for the `{' to validate starting the namespace. */
22102 matching_braces braces;
22103 if (braces.require_open (parser))
22104 {
22105 /* Parse the body of the namespace. */
22106 cp_parser_namespace_body (parser);
22107
22108 /* Look for the final `}'. */
22109 braces.require_close (parser);
22110 }
22111
22112 if (has_visibility)
22113 pop_visibility (1);
22114
22115 /* Pop the nested namespace definitions. */
22116 while (nested_definition_count--)
22117 pop_namespace ();
22118}
22119
22120/* Parse a namespace-body.
22121
22122 namespace-body:
22123 declaration-seq [opt] */
22124
22125static void
22126cp_parser_namespace_body (cp_parser* parser)
22127{
22128 cp_parser_declaration_seq_opt (parser);
22129}
22130
22131/* Parse a namespace-alias-definition.
22132
22133 namespace-alias-definition:
22134 namespace identifier = qualified-namespace-specifier ; */
22135
22136static void
22137cp_parser_namespace_alias_definition (cp_parser* parser)
22138{
22139 tree identifier;
22140 tree namespace_specifier;
22141
22142 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
22143
22144 /* Look for the `namespace' keyword. */
22145 cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
22146 /* Look for the identifier. */
22147 identifier = cp_parser_identifier (parser);
22148 if (identifier == error_mark_node)
22149 return;
22150 /* Look for the `=' token. */
22151 if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
22152 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
22153 {
22154 error_at (token->location, "%<namespace%> definition is not allowed here");
22155 /* Skip the definition. */
22156 cp_lexer_consume_token (lexer: parser->lexer);
22157 if (cp_parser_skip_to_closing_brace (parser))
22158 cp_lexer_consume_token (lexer: parser->lexer);
22159 return;
22160 }
22161 cp_parser_require (parser, CPP_EQ, RT_EQ);
22162 /* Look for the qualified-namespace-specifier. */
22163 namespace_specifier
22164 = cp_parser_qualified_namespace_specifier (parser);
22165 cp_warn_deprecated_use_scopes (namespace_specifier);
22166 /* Look for the `;' token. */
22167 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
22168
22169 /* Register the alias in the symbol table. */
22170 do_namespace_alias (identifier, namespace_specifier);
22171}
22172
22173/* Parse a qualified-namespace-specifier.
22174
22175 qualified-namespace-specifier:
22176 :: [opt] nested-name-specifier [opt] namespace-name
22177
22178 Returns a NAMESPACE_DECL corresponding to the specified
22179 namespace. */
22180
22181static tree
22182cp_parser_qualified_namespace_specifier (cp_parser* parser)
22183{
22184 /* Look for the optional `::'. */
22185 cp_parser_global_scope_opt (parser,
22186 /*current_scope_valid_p=*/false);
22187
22188 /* Look for the optional nested-name-specifier. */
22189 cp_parser_nested_name_specifier_opt (parser,
22190 /*typename_keyword_p=*/false,
22191 /*check_dependency_p=*/true,
22192 /*type_p=*/false,
22193 /*is_declaration=*/true);
22194
22195 return cp_parser_namespace_name (parser);
22196}
22197
22198/* Subroutine of cp_parser_using_declaration. */
22199
22200static tree
22201finish_using_decl (tree qscope, tree identifier, bool typename_p = false)
22202{
22203 tree decl = NULL_TREE;
22204 if (at_class_scope_p ())
22205 {
22206 /* Create the USING_DECL. */
22207 decl = do_class_using_decl (qscope, identifier);
22208
22209 if (check_for_bare_parameter_packs (decl))
22210 return error_mark_node;
22211
22212 if (decl && typename_p)
22213 USING_DECL_TYPENAME_P (decl) = 1;
22214
22215 /* Add it to the list of members in this class. */
22216 finish_member_declaration (decl);
22217 }
22218 else
22219 finish_nonmember_using_decl (scope: qscope, name: identifier);
22220 return decl;
22221}
22222
22223/* Parse a using-declaration, or, if ACCESS_DECLARATION_P is true, an
22224 access declaration.
22225
22226 using-declaration:
22227 using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
22228 using :: unqualified-id ;
22229
22230 access-declaration:
22231 qualified-id ;
22232
22233 */
22234
22235static bool
22236cp_parser_using_declaration (cp_parser* parser,
22237 bool access_declaration_p)
22238{
22239 cp_token *token;
22240 bool typename_p = false;
22241 bool global_scope_p;
22242 tree identifier;
22243 tree qscope;
22244 int oldcount = errorcount;
22245 cp_token *diag_token = NULL;
22246
22247 if (access_declaration_p)
22248 {
22249 diag_token = cp_lexer_peek_token (lexer: parser->lexer);
22250 cp_parser_parse_tentatively (parser);
22251 }
22252 else
22253 {
22254 /* Look for the `using' keyword. */
22255 cp_parser_require_keyword (parser, RID_USING, RT_USING);
22256
22257 again:
22258 /* Peek at the next token. */
22259 token = cp_lexer_peek_token (lexer: parser->lexer);
22260 /* See if it's `typename'. */
22261 if (token->keyword == RID_TYPENAME)
22262 {
22263 /* Remember that we've seen it. */
22264 typename_p = true;
22265 /* Consume the `typename' token. */
22266 cp_lexer_consume_token (lexer: parser->lexer);
22267 }
22268 }
22269
22270 /* Look for the optional global scope qualification. */
22271 global_scope_p
22272 = (cp_parser_global_scope_opt (parser,
22273 /*current_scope_valid_p=*/false)
22274 != NULL_TREE);
22275
22276 /* If we saw `typename', or didn't see `::', then there must be a
22277 nested-name-specifier present. */
22278 if (typename_p || !global_scope_p)
22279 {
22280 qscope = cp_parser_nested_name_specifier (parser, typename_keyword_p: typename_p,
22281 /*check_dependency_p=*/true,
22282 /*type_p=*/false,
22283 /*is_declaration=*/true);
22284 if (!qscope && !cp_parser_uncommitted_to_tentative_parse_p (parser))
22285 {
22286 cp_parser_skip_to_end_of_block_or_statement (parser);
22287 return false;
22288 }
22289 }
22290 /* Otherwise, we could be in either of the two productions. In that
22291 case, treat the nested-name-specifier as optional. */
22292 else
22293 qscope = cp_parser_nested_name_specifier_opt (parser,
22294 /*typename_keyword_p=*/false,
22295 /*check_dependency_p=*/true,
22296 /*type_p=*/false,
22297 /*is_declaration=*/true);
22298 if (!qscope)
22299 qscope = global_namespace;
22300
22301 cp_warn_deprecated_use_scopes (qscope);
22302
22303 if (access_declaration_p
22304 && !MAYBE_CLASS_TYPE_P (qscope)
22305 && TREE_CODE (qscope) != ENUMERAL_TYPE)
22306 /* If the qualifying scope of an access-declaration isn't a class
22307 or enumeration type then it can't be valid. */
22308 cp_parser_simulate_error (parser);
22309
22310 if (access_declaration_p && cp_parser_error_occurred (parser))
22311 /* Something has already gone wrong; there's no need to parse
22312 further. Since an error has occurred, the return value of
22313 cp_parser_parse_definitely will be false, as required. */
22314 return cp_parser_parse_definitely (parser);
22315
22316 token = cp_lexer_peek_token (lexer: parser->lexer);
22317 /* Parse the unqualified-id. */
22318 identifier = cp_parser_unqualified_id (parser,
22319 /*template_keyword_p=*/false,
22320 /*check_dependency_p=*/true,
22321 /*declarator_p=*/true,
22322 /*optional_p=*/false);
22323
22324 if (access_declaration_p)
22325 {
22326 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
22327 cp_parser_simulate_error (parser);
22328 if (!cp_parser_parse_definitely (parser))
22329 return false;
22330 }
22331 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
22332 {
22333 cp_token *ell = cp_lexer_consume_token (lexer: parser->lexer);
22334 if (cxx_dialect < cxx17)
22335 pedwarn (ell->location, OPT_Wc__17_extensions,
22336 "pack expansion in using-declaration only available "
22337 "with %<-std=c++17%> or %<-std=gnu++17%>");
22338
22339 /* A parameter pack can appear in the qualifying scope, and/or in the
22340 terminal name (if naming a conversion function). Logically they're
22341 part of a single pack expansion of the overall USING_DECL, but we
22342 express them as separate pack expansions within the USING_DECL since
22343 we can't create a pack expansion over a USING_DECL. */
22344 bool saw_parm_pack = false;
22345 if (uses_parameter_packs (qscope))
22346 {
22347 qscope = make_pack_expansion (qscope);
22348 saw_parm_pack = true;
22349 }
22350 if (identifier_p (t: identifier)
22351 && IDENTIFIER_CONV_OP_P (identifier)
22352 && uses_parameter_packs (TREE_TYPE (identifier)))
22353 {
22354 identifier = make_conv_op_name (make_pack_expansion
22355 (TREE_TYPE (identifier)));
22356 saw_parm_pack = true;
22357 }
22358 if (!saw_parm_pack)
22359 {
22360 /* Issue an error in terms using a SCOPE_REF that includes both
22361 components. */
22362 tree name
22363 = build_qualified_name (NULL_TREE, qscope, identifier, false);
22364 make_pack_expansion (name);
22365 gcc_assert (seen_error ());
22366 qscope = identifier = error_mark_node;
22367 }
22368 }
22369
22370 /* The function we call to handle a using-declaration is different
22371 depending on what scope we are in. */
22372 if (qscope == error_mark_node || identifier == error_mark_node)
22373 ;
22374 else if (!identifier_p (t: identifier)
22375 && TREE_CODE (identifier) != BIT_NOT_EXPR)
22376 /* [namespace.udecl]
22377
22378 A using declaration shall not name a template-id. */
22379 error_at (token->location,
22380 "a template-id may not appear in a using-declaration");
22381 else
22382 {
22383 tree decl = finish_using_decl (qscope, identifier, typename_p);
22384
22385 if (decl == error_mark_node)
22386 {
22387 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
22388 return false;
22389 }
22390 }
22391
22392 if (!access_declaration_p
22393 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
22394 {
22395 cp_token *comma = cp_lexer_consume_token (lexer: parser->lexer);
22396 if (cxx_dialect < cxx17)
22397 pedwarn (comma->location, OPT_Wc__17_extensions,
22398 "comma-separated list in using-declaration only available "
22399 "with %<-std=c++17%> or %<-std=gnu++17%>");
22400 goto again;
22401 }
22402
22403 /* Look for the final `;'. */
22404 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
22405
22406 if (access_declaration_p && errorcount == oldcount)
22407 warning_at (diag_token->location, OPT_Wdeprecated,
22408 "access declarations are deprecated "
22409 "in favor of using-declarations; "
22410 "suggestion: add the %<using%> keyword");
22411
22412 return true;
22413}
22414
22415/* C++20 using enum declaration.
22416
22417 using-enum-declaration :
22418 using elaborated-enum-specifier ; */
22419
22420static void
22421cp_parser_using_enum (cp_parser *parser)
22422{
22423 cp_parser_require_keyword (parser, RID_USING, RT_USING);
22424
22425 /* Using cp_parser_elaborated_type_specifier rejects typedef-names, which
22426 breaks one of the motivating examples in using-enum-5.C.
22427 cp_parser_simple_type_specifier seems to be closer to what we actually
22428 want, though that hasn't been properly specified yet. */
22429
22430 /* Consume 'enum'. */
22431 gcc_checking_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM));
22432 cp_lexer_consume_token (lexer: parser->lexer);
22433
22434 cp_token *start = cp_lexer_peek_token (lexer: parser->lexer);
22435
22436 tree type = (cp_parser_simple_type_specifier
22437 (parser, NULL, flags: CP_PARSER_FLAGS_TYPENAME_OPTIONAL));
22438
22439 cp_token *end = cp_lexer_previous_token (lexer: parser->lexer);
22440
22441 if (type == error_mark_node
22442 || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
22443 {
22444 cp_parser_skip_to_end_of_block_or_statement (parser);
22445 return;
22446 }
22447 if (TREE_CODE (type) == TYPE_DECL)
22448 type = TREE_TYPE (type);
22449
22450 /* The elaborated-enum-specifier shall not name a dependent type and the type
22451 shall have a reachable enum-specifier. */
22452 const char *msg = nullptr;
22453 if (cxx_dialect < cxx20)
22454 msg = G_("%<using enum%> "
22455 "only available with %<-std=c++20%> or %<-std=gnu++20%>");
22456 else if (dependent_type_p (type))
22457 msg = G_("%<using enum%> of dependent type %qT");
22458 else if (TREE_CODE (type) != ENUMERAL_TYPE)
22459 msg = G_("%<using enum%> of non-enumeration type %q#T");
22460 else if (!COMPLETE_TYPE_P (type))
22461 msg = G_("%<using enum%> of incomplete type %qT");
22462 else if (OPAQUE_ENUM_P (type))
22463 msg = G_("%<using enum%> of %qT before its enum-specifier");
22464 if (msg)
22465 {
22466 location_t loc = make_location (caret: start, start, end);
22467 auto_diagnostic_group g;
22468 error_at (loc, msg, type);
22469 loc = location_of (type);
22470 if (cxx_dialect < cxx20 || loc == input_location)
22471 ;
22472 else if (OPAQUE_ENUM_P (type))
22473 inform (loc, "opaque-enum-declaration here");
22474 else
22475 inform (loc, "declared here");
22476 }
22477
22478 /* A using-enum-declaration introduces the enumerator names of the named
22479 enumeration as if by a using-declaration for each enumerator. */
22480 if (TREE_CODE (type) == ENUMERAL_TYPE)
22481 for (tree v = TYPE_VALUES (type); v; v = TREE_CHAIN (v))
22482 finish_using_decl (qscope: type, DECL_NAME (TREE_VALUE (v)));
22483}
22484
22485/* Parse an alias-declaration.
22486
22487 alias-declaration:
22488 using identifier attribute-specifier-seq [opt] = type-id */
22489
22490static tree
22491cp_parser_alias_declaration (cp_parser* parser)
22492{
22493 tree id, type, decl, pushed_scope = NULL_TREE, attributes;
22494 location_t id_location, type_location;
22495 cp_declarator *declarator;
22496 cp_decl_specifier_seq decl_specs;
22497 bool member_p;
22498 const char *saved_message = NULL;
22499
22500 /* Look for the `using' keyword. */
22501 cp_token *using_token
22502 = cp_parser_require_keyword (parser, RID_USING, RT_USING);
22503 if (using_token == NULL)
22504 return error_mark_node;
22505
22506 id_location = cp_lexer_peek_token (lexer: parser->lexer)->location;
22507 id = cp_parser_identifier (parser);
22508 if (id == error_mark_node)
22509 return error_mark_node;
22510
22511 cp_token *attrs_token = cp_lexer_peek_token (lexer: parser->lexer);
22512 attributes = cp_parser_attributes_opt (parser);
22513 if (attributes == error_mark_node)
22514 return error_mark_node;
22515
22516 cp_parser_require (parser, CPP_EQ, RT_EQ);
22517
22518 if (cp_parser_error_occurred (parser))
22519 return error_mark_node;
22520
22521 cp_parser_commit_to_tentative_parse (parser);
22522
22523 /* Now we are going to parse the type-id of the declaration. */
22524
22525 /*
22526 [dcl.type]/3 says:
22527
22528 "A type-specifier-seq shall not define a class or enumeration
22529 unless it appears in the type-id of an alias-declaration (7.1.3) that
22530 is not the declaration of a template-declaration."
22531
22532 In other words, if we currently are in an alias template, the
22533 type-id should not define a type.
22534
22535 So let's set parser->type_definition_forbidden_message in that
22536 case; cp_parser_check_type_definition (called by
22537 cp_parser_class_specifier) will then emit an error if a type is
22538 defined in the type-id. */
22539 if (parser->num_template_parameter_lists)
22540 {
22541 saved_message = parser->type_definition_forbidden_message;
22542 parser->type_definition_forbidden_message =
22543 G_("types may not be defined in alias template declarations");
22544 }
22545
22546 type = cp_parser_type_id (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
22547 &type_location);
22548
22549 /* Restore the error message if need be. */
22550 if (parser->num_template_parameter_lists)
22551 parser->type_definition_forbidden_message = saved_message;
22552
22553 if (type == error_mark_node
22554 || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
22555 {
22556 cp_parser_skip_to_end_of_block_or_statement (parser);
22557 return error_mark_node;
22558 }
22559
22560 /* A typedef-name can also be introduced by an alias-declaration. The
22561 identifier following the using keyword becomes a typedef-name. It has
22562 the same semantics as if it were introduced by the typedef
22563 specifier. In particular, it does not define a new type and it shall
22564 not appear in the type-id. */
22565
22566 clear_decl_specs (decl_specs: &decl_specs);
22567 decl_specs.type = type;
22568 if (attributes != NULL_TREE)
22569 {
22570 decl_specs.attributes = attributes;
22571 set_and_check_decl_spec_loc (decl_specs: &decl_specs,
22572 ds: ds_attribute,
22573 attrs_token);
22574 }
22575 set_and_check_decl_spec_loc (decl_specs: &decl_specs,
22576 ds: ds_typedef,
22577 using_token);
22578 set_and_check_decl_spec_loc (decl_specs: &decl_specs,
22579 ds: ds_alias,
22580 using_token);
22581 decl_specs.locations[ds_type_spec] = type_location;
22582
22583 if (parser->num_template_parameter_lists
22584 && !cp_parser_check_template_parameters (parser,
22585 /*num_templates=*/0,
22586 /*template_id*/false,
22587 id_location,
22588 /*declarator=*/NULL))
22589 return error_mark_node;
22590
22591 declarator = make_id_declarator (NULL_TREE, unqualified_name: id, sfk: sfk_none, id_location);
22592
22593 member_p = at_class_scope_p ();
22594 if (member_p)
22595 decl = grokfield (declarator, &decl_specs, NULL_TREE, false,
22596 NULL_TREE, attributes);
22597 else
22598 decl = start_decl (declarator, &decl_specs, 0,
22599 attributes, NULL_TREE, &pushed_scope);
22600 if (decl == error_mark_node)
22601 return decl;
22602
22603 cp_finish_decl (decl, NULL_TREE, 0, NULL_TREE, 0);
22604
22605 if (pushed_scope)
22606 pop_scope (pushed_scope);
22607
22608 /* If decl is a template, return its TEMPLATE_DECL so that it gets
22609 added into the symbol table; otherwise, return the TYPE_DECL. */
22610 if (DECL_LANG_SPECIFIC (decl)
22611 && DECL_TEMPLATE_INFO (decl)
22612 && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
22613 {
22614 decl = DECL_TI_TEMPLATE (decl);
22615 if (member_p)
22616 check_member_template (decl);
22617 }
22618
22619 return decl;
22620}
22621
22622/* Parse a using-directive.
22623
22624 using-directive:
22625 attribute-specifier-seq [opt] using namespace :: [opt]
22626 nested-name-specifier [opt] namespace-name ; */
22627
22628static void
22629cp_parser_using_directive (cp_parser* parser)
22630{
22631 tree namespace_decl;
22632 tree attribs = cp_parser_std_attribute_spec_seq (parser);
22633 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
22634 {
22635 /* Error during attribute parsing that resulted in skipping
22636 to next semicolon. */
22637 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
22638 return;
22639 }
22640
22641 /* Look for the `using' keyword. */
22642 cp_parser_require_keyword (parser, RID_USING, RT_USING);
22643 /* And the `namespace' keyword. */
22644 cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
22645 /* Look for the optional `::' operator. */
22646 cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
22647 /* And the optional nested-name-specifier. */
22648 cp_parser_nested_name_specifier_opt (parser,
22649 /*typename_keyword_p=*/false,
22650 /*check_dependency_p=*/true,
22651 /*type_p=*/false,
22652 /*is_declaration=*/true);
22653 /* Get the namespace being used. */
22654 namespace_decl = cp_parser_namespace_name (parser);
22655 cp_warn_deprecated_use_scopes (namespace_decl);
22656 /* And any specified GNU attributes. */
22657 if (cp_next_tokens_can_be_gnu_attribute_p (parser))
22658 attribs = chainon (attribs, cp_parser_gnu_attributes_opt (parser));
22659
22660 /* Update the symbol table. */
22661 finish_using_directive (target: namespace_decl, attribs);
22662
22663 /* Look for the final `;'. */
22664 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
22665}
22666
22667/* Parse an asm-definition.
22668
22669 asm-qualifier:
22670 volatile
22671 inline
22672 goto
22673
22674 asm-qualifier-list:
22675 asm-qualifier
22676 asm-qualifier-list asm-qualifier
22677
22678 asm-definition:
22679 asm ( string-literal ) ;
22680
22681 GNU Extension:
22682
22683 asm-definition:
22684 asm asm-qualifier-list [opt] ( string-literal ) ;
22685 asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt] ) ;
22686 asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt]
22687 : asm-operand-list [opt] ) ;
22688 asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt]
22689 : asm-operand-list [opt]
22690 : asm-clobber-list [opt] ) ;
22691 asm asm-qualifier-list [opt] ( string-literal : : asm-operand-list [opt]
22692 : asm-clobber-list [opt]
22693 : asm-goto-list ) ;
22694
22695 The form with asm-goto-list is valid if and only if the asm-qualifier-list
22696 contains goto, and is the only allowed form in that case. No duplicates are
22697 allowed in an asm-qualifier-list. */
22698
22699static void
22700cp_parser_asm_definition (cp_parser* parser)
22701{
22702 tree outputs = NULL_TREE;
22703 tree inputs = NULL_TREE;
22704 tree clobbers = NULL_TREE;
22705 tree labels = NULL_TREE;
22706 tree asm_stmt;
22707 bool extended_p = false;
22708 bool invalid_inputs_p = false;
22709 bool invalid_outputs_p = false;
22710 required_token missing = RT_NONE;
22711 tree std_attrs = cp_parser_std_attribute_spec_seq (parser);
22712 location_t asm_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
22713
22714 /* Look for the `asm' keyword. */
22715 cp_parser_require_keyword (parser, RID_ASM, RT_ASM);
22716
22717 /* In C++20, unevaluated inline assembly is permitted in constexpr
22718 functions. */
22719 if (parser->in_function_body
22720 && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
22721 && cxx_dialect < cxx20)
22722 pedwarn (asm_loc, OPT_Wc__20_extensions, "%<asm%> in %<constexpr%> "
22723 "function only available with %<-std=c++20%> or "
22724 "%<-std=gnu++20%>");
22725
22726 /* Handle the asm-qualifier-list. */
22727 location_t volatile_loc = UNKNOWN_LOCATION;
22728 location_t inline_loc = UNKNOWN_LOCATION;
22729 location_t goto_loc = UNKNOWN_LOCATION;
22730 location_t first_loc = UNKNOWN_LOCATION;
22731
22732 if (cp_parser_allow_gnu_extensions_p (parser))
22733 for (;;)
22734 {
22735 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
22736 location_t loc = token->location;
22737 switch (cp_lexer_peek_token (lexer: parser->lexer)->keyword)
22738 {
22739 case RID_VOLATILE:
22740 if (volatile_loc)
22741 {
22742 error_at (loc, "duplicate %<asm%> qualifier %qT",
22743 token->u.value);
22744 inform (volatile_loc, "first seen here");
22745 }
22746 else
22747 {
22748 if (!parser->in_function_body)
22749 warning_at (loc, 0, "%<asm%> qualifier %qT ignored "
22750 "outside of function body", token->u.value);
22751 volatile_loc = loc;
22752 }
22753 cp_lexer_consume_token (lexer: parser->lexer);
22754 continue;
22755
22756 case RID_INLINE:
22757 if (inline_loc)
22758 {
22759 error_at (loc, "duplicate %<asm%> qualifier %qT",
22760 token->u.value);
22761 inform (inline_loc, "first seen here");
22762 }
22763 else
22764 inline_loc = loc;
22765 if (!first_loc)
22766 first_loc = loc;
22767 cp_lexer_consume_token (lexer: parser->lexer);
22768 continue;
22769
22770 case RID_GOTO:
22771 if (goto_loc)
22772 {
22773 error_at (loc, "duplicate %<asm%> qualifier %qT",
22774 token->u.value);
22775 inform (goto_loc, "first seen here");
22776 }
22777 else
22778 goto_loc = loc;
22779 if (!first_loc)
22780 first_loc = loc;
22781 cp_lexer_consume_token (lexer: parser->lexer);
22782 continue;
22783
22784 case RID_CONST:
22785 case RID_RESTRICT:
22786 error_at (loc, "%qT is not an %<asm%> qualifier", token->u.value);
22787 cp_lexer_consume_token (lexer: parser->lexer);
22788 continue;
22789
22790 default:
22791 break;
22792 }
22793 break;
22794 }
22795
22796 bool volatile_p = (volatile_loc != UNKNOWN_LOCATION);
22797 bool inline_p = (inline_loc != UNKNOWN_LOCATION);
22798 bool goto_p = (goto_loc != UNKNOWN_LOCATION);
22799
22800 if (!parser->in_function_body && (inline_p || goto_p))
22801 {
22802 error_at (first_loc, "%<asm%> qualifier outside of function body");
22803 inline_p = goto_p = false;
22804 }
22805
22806 /* Look for the opening `('. */
22807 if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
22808 return;
22809 /* Look for the string. */
22810 tree string = cp_parser_string_literal (parser, /*translate=*/false,
22811 /*wide_ok=*/false);
22812 if (string == error_mark_node)
22813 {
22814 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false,
22815 /*consume_paren=*/true);
22816 return;
22817 }
22818
22819 /* If we're allowing GNU extensions, check for the extended assembly
22820 syntax. Unfortunately, the `:' tokens need not be separated by
22821 a space in C, and so, for compatibility, we tolerate that here
22822 too. Doing that means that we have to treat the `::' operator as
22823 two `:' tokens. */
22824 if (cp_parser_allow_gnu_extensions_p (parser)
22825 && parser->in_function_body
22826 && (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON)
22827 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE)))
22828 {
22829 bool inputs_p = false;
22830 bool clobbers_p = false;
22831 bool labels_p = false;
22832
22833 /* The extended syntax was used. */
22834 extended_p = true;
22835
22836 /* Look for outputs. */
22837 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
22838 {
22839 /* Consume the `:'. */
22840 cp_lexer_consume_token (lexer: parser->lexer);
22841 /* Parse the output-operands. */
22842 if (cp_lexer_next_token_is_not (lexer: parser->lexer,
22843 type: CPP_COLON)
22844 && cp_lexer_next_token_is_not (lexer: parser->lexer,
22845 type: CPP_SCOPE)
22846 && cp_lexer_next_token_is_not (lexer: parser->lexer,
22847 type: CPP_CLOSE_PAREN))
22848 {
22849 outputs = cp_parser_asm_operand_list (parser);
22850 if (outputs == error_mark_node)
22851 invalid_outputs_p = true;
22852 }
22853 }
22854 /* If the next token is `::', there are no outputs, and the
22855 next token is the beginning of the inputs. */
22856 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE))
22857 /* The inputs are coming next. */
22858 inputs_p = true;
22859
22860 /* Look for inputs. */
22861 if (inputs_p
22862 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
22863 {
22864 /* Consume the `:' or `::'. */
22865 cp_lexer_consume_token (lexer: parser->lexer);
22866 /* Parse the output-operands. */
22867 if (cp_lexer_next_token_is_not (lexer: parser->lexer,
22868 type: CPP_COLON)
22869 && cp_lexer_next_token_is_not (lexer: parser->lexer,
22870 type: CPP_SCOPE)
22871 && cp_lexer_next_token_is_not (lexer: parser->lexer,
22872 type: CPP_CLOSE_PAREN))
22873 {
22874 inputs = cp_parser_asm_operand_list (parser);
22875 if (inputs == error_mark_node)
22876 invalid_inputs_p = true;
22877 }
22878 }
22879 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE))
22880 /* The clobbers are coming next. */
22881 clobbers_p = true;
22882
22883 /* Look for clobbers. */
22884 if (clobbers_p
22885 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
22886 {
22887 clobbers_p = true;
22888 /* Consume the `:' or `::'. */
22889 cp_lexer_consume_token (lexer: parser->lexer);
22890 /* Parse the clobbers. */
22891 if (cp_lexer_next_token_is_not (lexer: parser->lexer,
22892 type: CPP_COLON)
22893 && cp_lexer_next_token_is_not (lexer: parser->lexer,
22894 type: CPP_CLOSE_PAREN))
22895 clobbers = cp_parser_asm_clobber_list (parser);
22896 }
22897 else if (goto_p && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE))
22898 /* The labels are coming next. */
22899 labels_p = true;
22900
22901 /* Look for labels. */
22902 if (labels_p
22903 || (goto_p && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON)))
22904 {
22905 labels_p = true;
22906 /* Consume the `:' or `::'. */
22907 cp_lexer_consume_token (lexer: parser->lexer);
22908 /* Parse the labels. */
22909 labels = cp_parser_asm_label_list (parser);
22910 }
22911
22912 if (goto_p && !labels_p)
22913 missing = clobbers_p ? RT_COLON : RT_COLON_SCOPE;
22914 }
22915 else if (goto_p)
22916 missing = RT_COLON_SCOPE;
22917
22918 /* Look for the closing `)'. */
22919 if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN,
22920 missing ? missing : RT_CLOSE_PAREN))
22921 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false,
22922 /*consume_paren=*/true);
22923 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
22924
22925 if (!invalid_inputs_p && !invalid_outputs_p)
22926 {
22927 /* Create the ASM_EXPR. */
22928 if (parser->in_function_body)
22929 {
22930 asm_stmt = finish_asm_stmt (asm_loc, volatile_p, string, outputs,
22931 inputs, clobbers, labels, inline_p);
22932 /* If the extended syntax was not used, mark the ASM_EXPR. */
22933 if (!extended_p)
22934 {
22935 tree temp = asm_stmt;
22936 if (TREE_CODE (temp) == CLEANUP_POINT_EXPR)
22937 temp = TREE_OPERAND (temp, 0);
22938
22939 ASM_INPUT_P (temp) = 1;
22940 }
22941 }
22942 else
22943 symtab->finalize_toplevel_asm (asm_str: string);
22944 }
22945
22946 if (std_attrs && any_nonignored_attribute_p (std_attrs))
22947 warning_at (asm_loc, OPT_Wattributes,
22948 "attributes ignored on %<asm%> declaration");
22949}
22950
22951/* Given the type TYPE of a declaration with declarator DECLARATOR, return the
22952 type that comes from the decl-specifier-seq. */
22953
22954static tree
22955strip_declarator_types (tree type, cp_declarator *declarator)
22956{
22957 for (cp_declarator *d = declarator; d;)
22958 switch (d->kind)
22959 {
22960 case cdk_id:
22961 case cdk_decomp:
22962 case cdk_error:
22963 d = NULL;
22964 break;
22965
22966 default:
22967 if (TYPE_PTRMEMFUNC_P (type))
22968 type = TYPE_PTRMEMFUNC_FN_TYPE (type);
22969 type = TREE_TYPE (type);
22970 d = d->declarator;
22971 break;
22972 }
22973
22974 return type;
22975}
22976
22977/* Warn about the most vexing parse syntactic ambiguity, i.e., warn when
22978 a construct looks like a variable definition but is actually a function
22979 declaration. DECL_SPECIFIERS is the decl-specifier-seq and DECLARATOR
22980 is the declarator for this function declaration. */
22981
22982static void
22983warn_about_ambiguous_parse (const cp_decl_specifier_seq *decl_specifiers,
22984 const cp_declarator *declarator)
22985{
22986 /* Only warn if we are declaring a function at block scope. */
22987 if (!at_function_scope_p ())
22988 return;
22989
22990 /* And only if there is no storage class specified. */
22991 if (decl_specifiers->storage_class != sc_none
22992 || decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
22993 return;
22994
22995 if (declarator->kind != cdk_function
22996 || !declarator->declarator
22997 || declarator->declarator->kind != cdk_id
22998 || !identifier_p (t: get_unqualified_id
22999 (declarator: const_cast<cp_declarator *>(declarator))))
23000 return;
23001
23002 /* Don't warn when the whole declarator (not just the declarator-id!)
23003 was parenthesized. That is, don't warn for int(n()) but do warn
23004 for int(f)(). */
23005 if (declarator->parenthesized != UNKNOWN_LOCATION)
23006 return;
23007
23008 tree type;
23009 if (decl_specifiers->type)
23010 {
23011 type = decl_specifiers->type;
23012 if (TREE_CODE (type) == TYPE_DECL)
23013 type = TREE_TYPE (type);
23014
23015 /* If the return type is void there is no ambiguity. */
23016 if (same_type_p (type, void_type_node))
23017 return;
23018 }
23019 else if (decl_specifiers->any_type_specifiers_p)
23020 /* Code like long f(); will have null ->type. If we have any
23021 type-specifiers, pretend we've seen int. */
23022 type = integer_type_node;
23023 else
23024 return;
23025
23026 auto_diagnostic_group d;
23027 location_t loc = declarator->u.function.parens_loc;
23028 tree params = declarator->u.function.parameters;
23029 const bool has_list_ctor_p = CLASS_TYPE_P (type) && TYPE_HAS_LIST_CTOR (type);
23030
23031 /* The T t() case. */
23032 if (params == void_list_node)
23033 {
23034 if (warning_at (loc, OPT_Wvexing_parse,
23035 "empty parentheses were disambiguated as a function "
23036 "declaration"))
23037 {
23038 /* () means value-initialization (C++03 and up); {} (C++11 and up)
23039 means value-initialization or aggregate-initialization, nothing
23040 means default-initialization. We can only suggest removing the
23041 parentheses/adding {} if T has a default constructor. */
23042 if (!CLASS_TYPE_P (type) || TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
23043 {
23044 gcc_rich_location iloc (loc);
23045 iloc.add_fixit_remove ();
23046 inform (&iloc, "remove parentheses to default-initialize "
23047 "a variable");
23048 if (cxx_dialect >= cxx11 && !has_list_ctor_p)
23049 {
23050 if (CP_AGGREGATE_TYPE_P (type))
23051 inform (loc, "or replace parentheses with braces to "
23052 "aggregate-initialize a variable");
23053 else
23054 inform (loc, "or replace parentheses with braces to "
23055 "value-initialize a variable");
23056 }
23057 }
23058 }
23059 return;
23060 }
23061
23062 /* If we had (...) or the parameter-list wasn't parenthesized,
23063 we're done. */
23064 if (params == NULL_TREE || !PARENTHESIZED_LIST_P (params))
23065 return;
23066
23067 /* The T t(X()) case. */
23068 if (list_length (params) == 2)
23069 {
23070 if (warning_at (loc, OPT_Wvexing_parse,
23071 "parentheses were disambiguated as a function "
23072 "declaration"))
23073 {
23074 gcc_rich_location iloc (loc);
23075 /* {}-initialization means that we can use an initializer-list
23076 constructor if no default constructor is available, so don't
23077 suggest using {} for classes that have an initializer_list
23078 constructor. */
23079 if (cxx_dialect >= cxx11 && !has_list_ctor_p)
23080 {
23081 iloc.add_fixit_replace (where: get_start (loc), new_content: "{");
23082 iloc.add_fixit_replace (where: get_finish (loc), new_content: "}");
23083 inform (&iloc, "replace parentheses with braces to declare a "
23084 "variable");
23085 }
23086 else
23087 {
23088 iloc.add_fixit_insert_after (where: get_start (loc), new_content: "(");
23089 iloc.add_fixit_insert_before (where: get_finish (loc), new_content: ")");
23090 inform (&iloc, "add parentheses to declare a variable");
23091 }
23092 }
23093 }
23094 /* The T t(X(), X()) case. */
23095 else if (warning_at (loc, OPT_Wvexing_parse,
23096 "parentheses were disambiguated as a function "
23097 "declaration"))
23098 {
23099 gcc_rich_location iloc (loc);
23100 if (cxx_dialect >= cxx11 && !has_list_ctor_p)
23101 {
23102 iloc.add_fixit_replace (where: get_start (loc), new_content: "{");
23103 iloc.add_fixit_replace (where: get_finish (loc), new_content: "}");
23104 inform (&iloc, "replace parentheses with braces to declare a "
23105 "variable");
23106 }
23107 }
23108}
23109
23110/* If DECLARATOR with DECL_SPECS is a function declarator that has
23111 the form of a deduction guide, tag it as such. CTOR_DTOR_OR_CONV_P
23112 has the same meaning as in cp_parser_declarator. */
23113
23114static void
23115cp_parser_maybe_adjust_declarator_for_dguide (cp_parser *parser,
23116 cp_decl_specifier_seq *decl_specs,
23117 cp_declarator *declarator,
23118 int *ctor_dtor_or_conv_p)
23119{
23120 if (cxx_dialect >= cxx17
23121 && *ctor_dtor_or_conv_p <= 0
23122 && !decl_specs->type
23123 && !decl_specs->any_type_specifiers_p
23124 && function_declarator_p (declarator))
23125 {
23126 cp_declarator *id = get_id_declarator (declarator);
23127 tree name = id->u.id.unqualified_name;
23128 parser->scope = id->u.id.qualifying_scope;
23129 tree tmpl = cp_parser_lookup_name_simple (parser, name, id->id_loc);
23130 if (tmpl
23131 && (DECL_CLASS_TEMPLATE_P (tmpl)
23132 || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)))
23133 {
23134 id->u.id.unqualified_name = dguide_name (tmpl);
23135 id->u.id.sfk = sfk_deduction_guide;
23136 *ctor_dtor_or_conv_p = 1;
23137 }
23138 }
23139}
23140
23141/* Declarators [gram.dcl.decl] */
23142
23143/* Parse an init-declarator.
23144
23145 init-declarator:
23146 declarator initializer [opt]
23147
23148 GNU Extension:
23149
23150 init-declarator:
23151 declarator asm-specification [opt] attributes [opt] initializer [opt]
23152
23153 function-definition:
23154 decl-specifier-seq [opt] declarator ctor-initializer [opt]
23155 function-body
23156 decl-specifier-seq [opt] declarator function-try-block
23157
23158 GNU Extension:
23159
23160 function-definition:
23161 __extension__ function-definition
23162
23163 TM Extension:
23164
23165 function-definition:
23166 decl-specifier-seq [opt] declarator function-transaction-block
23167
23168 The parser flags FLAGS is used to control type-specifier parsing.
23169
23170 The DECL_SPECIFIERS apply to this declarator. Returns a
23171 representation of the entity declared. If MEMBER_P is TRUE, then
23172 this declarator appears in a class scope. The new DECL created by
23173 this declarator is returned.
23174
23175 The CHECKS are access checks that should be performed once we know
23176 what entity is being declared (and, therefore, what classes have
23177 befriended it).
23178
23179 If FUNCTION_DEFINITION_ALLOWED_P then we handle the declarator and
23180 for a function-definition here as well. If the declarator is a
23181 declarator for a function-definition, *FUNCTION_DEFINITION_P will
23182 be TRUE upon return. By that point, the function-definition will
23183 have been completely parsed.
23184
23185 FUNCTION_DEFINITION_P may be NULL if FUNCTION_DEFINITION_ALLOWED_P
23186 is FALSE.
23187
23188 If MAYBE_RANGE_FOR_DECL is not NULL, the pointed tree will be set to the
23189 parsed declaration if it is an uninitialized single declarator not followed
23190 by a `;', or to error_mark_node otherwise. Either way, the trailing `;',
23191 if present, will not be consumed. If returned, this declarator will be
23192 created with SD_INITIALIZED but will not call cp_finish_decl.
23193
23194 If INIT_LOC is not NULL, and *INIT_LOC is equal to UNKNOWN_LOCATION,
23195 and there is an initializer, the pointed location_t is set to the
23196 location of the '=' or `(', or '{' in C++11 token introducing the
23197 initializer. */
23198
23199static tree
23200cp_parser_init_declarator (cp_parser* parser,
23201 cp_parser_flags flags,
23202 cp_decl_specifier_seq *decl_specifiers,
23203 vec<deferred_access_check, va_gc> *checks,
23204 bool function_definition_allowed_p,
23205 bool member_p,
23206 int declares_class_or_enum,
23207 bool* function_definition_p,
23208 tree* maybe_range_for_decl,
23209 location_t* init_loc,
23210 tree* auto_result)
23211{
23212 cp_token *token = NULL, *asm_spec_start_token = NULL,
23213 *attributes_start_token = NULL;
23214 cp_declarator *declarator;
23215 tree prefix_attributes;
23216 tree attributes = NULL;
23217 tree asm_specification;
23218 tree initializer;
23219 tree decl = NULL_TREE;
23220 tree scope;
23221 int is_initialized;
23222 /* Only valid if IS_INITIALIZED is true. In that case, CPP_EQ if
23223 initialized with "= ..", CPP_OPEN_PAREN if initialized with
23224 "(...)". */
23225 enum cpp_ttype initialization_kind;
23226 bool is_direct_init = false;
23227 bool is_non_constant_init;
23228 int ctor_dtor_or_conv_p;
23229 bool friend_p = cp_parser_friend_p (decl_specifiers);
23230 bool static_p = decl_specifiers->storage_class == sc_static;
23231 tree pushed_scope = NULL_TREE;
23232 bool range_for_decl_p = false;
23233 bool saved_default_arg_ok_p = parser->default_arg_ok_p;
23234 location_t tmp_init_loc = UNKNOWN_LOCATION;
23235
23236 if (decl_spec_seq_has_spec_p (decl_specifiers, ds_consteval))
23237 flags |= CP_PARSER_FLAGS_CONSTEVAL;
23238
23239 /* Assume that this is not the declarator for a function
23240 definition. */
23241 if (function_definition_p)
23242 *function_definition_p = false;
23243
23244 /* Default arguments are only permitted for function parameters. */
23245 if (decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
23246 parser->default_arg_ok_p = false;
23247
23248 /* Defer access checks while parsing the declarator; we cannot know
23249 what names are accessible until we know what is being
23250 declared. */
23251 resume_deferring_access_checks ();
23252
23253 token = cp_lexer_peek_token (lexer: parser->lexer);
23254
23255 /* Parse the declarator. */
23256 declarator
23257 = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
23258 flags, &ctor_dtor_or_conv_p,
23259 /*parenthesized_p=*/NULL,
23260 member_p, friend_p, static_p);
23261 /* Gather up the deferred checks. */
23262 stop_deferring_access_checks ();
23263
23264 parser->default_arg_ok_p = saved_default_arg_ok_p;
23265
23266 /* If the DECLARATOR was erroneous, there's no need to go
23267 further. */
23268 if (declarator == cp_error_declarator)
23269 return error_mark_node;
23270
23271 /* Check that the number of template-parameter-lists is OK. */
23272 if (!cp_parser_check_declarator_template_parameters (parser, declarator,
23273 token->location))
23274 return error_mark_node;
23275
23276 if (declares_class_or_enum & 2)
23277 cp_parser_check_for_definition_in_return_type (declarator,
23278 type: decl_specifiers->type,
23279 type_location: decl_specifiers->locations[ds_type_spec]);
23280
23281 /* Figure out what scope the entity declared by the DECLARATOR is
23282 located in. `grokdeclarator' sometimes changes the scope, so
23283 we compute it now. */
23284 scope = get_scope_of_declarator (declarator);
23285
23286 /* Perform any lookups in the declared type which were thought to be
23287 dependent, but are not in the scope of the declarator. */
23288 decl_specifiers->type
23289 = maybe_update_decl_type (decl_specifiers->type, scope);
23290
23291 /* If we're allowing GNU extensions, look for an
23292 asm-specification. */
23293 if (cp_parser_allow_gnu_extensions_p (parser))
23294 {
23295 /* Look for an asm-specification. */
23296 asm_spec_start_token = cp_lexer_peek_token (lexer: parser->lexer);
23297 asm_specification = cp_parser_asm_specification_opt (parser);
23298 }
23299 else
23300 asm_specification = NULL_TREE;
23301
23302 /* Gather the attributes that were provided with the
23303 decl-specifiers. */
23304 prefix_attributes = decl_specifiers->attributes;
23305
23306 /* Look for attributes. */
23307 attributes_start_token = cp_lexer_peek_token (lexer: parser->lexer);
23308 attributes = cp_parser_attributes_opt (parser);
23309
23310 /* Peek at the next token. */
23311 token = cp_lexer_peek_token (lexer: parser->lexer);
23312
23313 bool bogus_implicit_tmpl = false;
23314
23315 if (function_declarator_p (declarator))
23316 {
23317 /* Handle C++17 deduction guides. Note that class-scope
23318 non-template deduction guides are instead handled in
23319 cp_parser_member_declaration. */
23320 cp_parser_maybe_adjust_declarator_for_dguide (parser,
23321 decl_specs: decl_specifiers,
23322 declarator,
23323 ctor_dtor_or_conv_p: &ctor_dtor_or_conv_p);
23324
23325 if (!member_p && !cp_parser_error_occurred (parser))
23326 warn_about_ambiguous_parse (decl_specifiers, declarator);
23327
23328 /* Check to see if the token indicates the start of a
23329 function-definition. */
23330 if (cp_parser_token_starts_function_definition_p (token))
23331 {
23332 if (!function_definition_allowed_p)
23333 {
23334 /* If a function-definition should not appear here, issue an
23335 error message. */
23336 cp_parser_error (parser,
23337 gmsgid: "a function-definition is not allowed here");
23338 return error_mark_node;
23339 }
23340
23341 location_t func_brace_location
23342 = cp_lexer_peek_token (lexer: parser->lexer)->location;
23343
23344 /* Neither attributes nor an asm-specification are allowed
23345 on a function-definition. */
23346 if (asm_specification)
23347 error_at (asm_spec_start_token->location,
23348 "an %<asm%> specification is not allowed "
23349 "on a function-definition");
23350 if (attributes)
23351 error_at (attributes_start_token->location,
23352 "attributes are not allowed "
23353 "on a function-definition");
23354 /* This is a function-definition. */
23355 *function_definition_p = true;
23356
23357 /* Parse the function definition. */
23358 if (member_p)
23359 decl = cp_parser_save_member_function_body (parser,
23360 decl_specifiers,
23361 declarator,
23362 prefix_attributes);
23363 else
23364 decl =
23365 (cp_parser_function_definition_from_specifiers_and_declarator
23366 (parser, decl_specifiers, prefix_attributes, declarator));
23367
23368 if (decl != error_mark_node && DECL_STRUCT_FUNCTION (decl))
23369 {
23370 /* This is where the prologue starts... */
23371 DECL_STRUCT_FUNCTION (decl)->function_start_locus
23372 = func_brace_location;
23373 }
23374
23375 return decl;
23376 }
23377 }
23378 else if (parser->fully_implicit_function_template_p)
23379 {
23380 /* A non-template declaration involving a function parameter list
23381 containing an implicit template parameter will be made into a
23382 template. If the resulting declaration is not going to be an
23383 actual function then finish the template scope here to prevent it.
23384 An error message will be issued once we have a decl to talk about.
23385
23386 FIXME probably we should do type deduction rather than create an
23387 implicit template, but the standard currently doesn't allow it. */
23388 bogus_implicit_tmpl = true;
23389 finish_fully_implicit_template (parser, NULL_TREE);
23390 }
23391
23392 /* [dcl.dcl]
23393
23394 Only in function declarations for constructors, destructors, type
23395 conversions, and deduction guides can the decl-specifier-seq be omitted.
23396
23397 We explicitly postpone this check past the point where we handle
23398 function-definitions because we tolerate function-definitions
23399 that are missing their return types in some modes. */
23400 if (!decl_specifiers->any_specifiers_p && ctor_dtor_or_conv_p <= 0)
23401 {
23402 cp_parser_error (parser,
23403 gmsgid: "expected constructor, destructor, or type conversion");
23404 return error_mark_node;
23405 }
23406
23407 /* An `=' or an '{' in C++11, indicate an initializer. An '(' may indicate
23408 an initializer as well. */
23409 if (token->type == CPP_EQ
23410 || token->type == CPP_OPEN_PAREN
23411 || token->type == CPP_OPEN_BRACE)
23412 {
23413 /* Don't get fooled into thinking that F(i)(1)(2) is an initializer.
23414 It isn't; it's an expression. (Here '(i)' would have already been
23415 parsed as a declarator.) */
23416 if (token->type == CPP_OPEN_PAREN
23417 && cp_parser_uncommitted_to_tentative_parse_p (parser))
23418 {
23419 cp_lexer_save_tokens (lexer: parser->lexer);
23420 cp_lexer_consume_token (lexer: parser->lexer);
23421 cp_parser_skip_to_closing_parenthesis (parser,
23422 /*recovering*/false,
23423 /*or_comma*/false,
23424 /*consume_paren*/true);
23425 /* If this is an initializer, only a ',' or ';' can follow: either
23426 we have another init-declarator, or we're at the end of an
23427 init-declarator-list which can only be followed by a ';'. */
23428 bool ok = (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)
23429 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA));
23430 cp_lexer_rollback_tokens (lexer: parser->lexer);
23431 if (UNLIKELY (!ok))
23432 /* Not an init-declarator. */
23433 return error_mark_node;
23434 }
23435 is_initialized = SD_INITIALIZED;
23436 initialization_kind = token->type;
23437 declarator->init_loc = token->location;
23438 if (maybe_range_for_decl)
23439 *maybe_range_for_decl = error_mark_node;
23440 tmp_init_loc = token->location;
23441 if (init_loc && *init_loc == UNKNOWN_LOCATION)
23442 *init_loc = tmp_init_loc;
23443
23444 if (token->type == CPP_EQ
23445 && function_declarator_p (declarator))
23446 {
23447 cp_token *t2 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
23448 if (t2->keyword == RID_DEFAULT)
23449 is_initialized = SD_DEFAULTED;
23450 else if (t2->keyword == RID_DELETE)
23451 is_initialized = SD_DELETED;
23452 }
23453 }
23454 else
23455 {
23456 /* If the init-declarator isn't initialized and isn't followed by a
23457 `,' or `;', it's not a valid init-declarator. */
23458 if (token->type != CPP_COMMA
23459 && token->type != CPP_SEMICOLON)
23460 {
23461 if (maybe_range_for_decl && *maybe_range_for_decl != error_mark_node)
23462 range_for_decl_p = true;
23463 else
23464 {
23465 if (!maybe_range_for_decl)
23466 cp_parser_error (parser, gmsgid: "expected initializer");
23467 return error_mark_node;
23468 }
23469 }
23470 is_initialized = SD_UNINITIALIZED;
23471 initialization_kind = CPP_EOF;
23472 }
23473
23474 /* Because start_decl has side-effects, we should only call it if we
23475 know we're going ahead. By this point, we know that we cannot
23476 possibly be looking at any other construct. */
23477 cp_parser_commit_to_tentative_parse (parser);
23478
23479 /* Enter the newly declared entry in the symbol table. If we're
23480 processing a declaration in a class-specifier, we wait until
23481 after processing the initializer. */
23482 if (!member_p)
23483 {
23484 if (parser->in_unbraced_linkage_specification_p)
23485 decl_specifiers->storage_class = sc_extern;
23486 decl = start_decl (declarator, decl_specifiers,
23487 range_for_decl_p? SD_INITIALIZED : is_initialized,
23488 attributes, prefix_attributes, &pushed_scope);
23489 cp_finalize_omp_declare_simd (parser, fndecl: decl);
23490 cp_finalize_oacc_routine (parser, decl, false);
23491 /* Adjust location of decl if declarator->id_loc is more appropriate:
23492 set, and decl wasn't merged with another decl, in which case its
23493 location would be different from input_location, and more accurate. */
23494 if (DECL_P (decl)
23495 && declarator->id_loc != UNKNOWN_LOCATION
23496 && DECL_SOURCE_LOCATION (decl) == input_location)
23497 DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
23498 }
23499 else if (scope)
23500 /* Enter the SCOPE. That way unqualified names appearing in the
23501 initializer will be looked up in SCOPE. */
23502 pushed_scope = push_scope (scope);
23503
23504 /* Perform deferred access control checks, now that we know in which
23505 SCOPE the declared entity resides. */
23506 if (!member_p && decl)
23507 {
23508 tree saved_current_function_decl = NULL_TREE;
23509
23510 /* If the entity being declared is a function, pretend that we
23511 are in its scope. If it is a `friend', it may have access to
23512 things that would not otherwise be accessible. */
23513 if (TREE_CODE (decl) == FUNCTION_DECL)
23514 {
23515 saved_current_function_decl = current_function_decl;
23516 current_function_decl = decl;
23517 }
23518
23519 /* Perform access checks for template parameters. */
23520 cp_parser_perform_template_parameter_access_checks (checks);
23521
23522 /* Perform the access control checks for the declarator and the
23523 decl-specifiers. */
23524 perform_deferred_access_checks (tf_warning_or_error);
23525
23526 /* Restore the saved value. */
23527 if (TREE_CODE (decl) == FUNCTION_DECL)
23528 current_function_decl = saved_current_function_decl;
23529 }
23530
23531 /* Parse the initializer. */
23532 initializer = NULL_TREE;
23533 is_direct_init = false;
23534 is_non_constant_init = true;
23535 if (is_initialized)
23536 {
23537 if (function_declarator_p (declarator))
23538 {
23539 if (initialization_kind == CPP_EQ)
23540 initializer = cp_parser_pure_specifier (parser);
23541 else
23542 {
23543 /* If the declaration was erroneous, we don't really
23544 know what the user intended, so just silently
23545 consume the initializer. */
23546 if (decl != error_mark_node)
23547 error_at (tmp_init_loc, "initializer provided for function");
23548 cp_parser_skip_to_closing_parenthesis (parser,
23549 /*recovering=*/true,
23550 /*or_comma=*/false,
23551 /*consume_paren=*/true);
23552 }
23553 }
23554 else
23555 {
23556 /* We want to record the extra mangling scope for in-class
23557 initializers of class members and initializers of static
23558 data member templates and namespace-scope initializers.
23559 The former involves deferring parsing of the initializer
23560 until end of class as with default arguments. So right
23561 here we only handle the latter two. */
23562 bool has_lambda_scope = false;
23563
23564 if (decl != error_mark_node
23565 && !member_p
23566 && (processing_template_decl || DECL_NAMESPACE_SCOPE_P (decl)))
23567 has_lambda_scope = true;
23568
23569 if (has_lambda_scope)
23570 start_lambda_scope (decl);
23571 initializer = cp_parser_initializer (parser,
23572 &is_direct_init,
23573 &is_non_constant_init);
23574 if (has_lambda_scope)
23575 finish_lambda_scope ();
23576 if (initializer == error_mark_node)
23577 cp_parser_skip_to_end_of_statement (parser);
23578 }
23579 }
23580
23581 /* The old parser allows attributes to appear after a parenthesized
23582 initializer. Mark Mitchell proposed removing this functionality
23583 on the GCC mailing lists on 2002-08-13. This parser accepts the
23584 attributes -- but ignores them. Made a permerror in GCC 8. */
23585 if (cp_parser_allow_gnu_extensions_p (parser)
23586 && initialization_kind == CPP_OPEN_PAREN
23587 && cp_parser_attributes_opt (parser)
23588 && permerror (input_location,
23589 "attributes after parenthesized initializer ignored"))
23590 {
23591 static bool hint;
23592 if (flag_permissive && !hint)
23593 {
23594 hint = true;
23595 inform (input_location,
23596 "this flexibility is deprecated and will be removed");
23597 }
23598 }
23599
23600 /* And now complain about a non-function implicit template. */
23601 if (bogus_implicit_tmpl && decl != error_mark_node)
23602 error_at (DECL_SOURCE_LOCATION (decl),
23603 "non-function %qD declared as implicit template", decl);
23604
23605 /* For an in-class declaration, use `grokfield' to create the
23606 declaration. */
23607 if (member_p)
23608 {
23609 if (pushed_scope)
23610 {
23611 pop_scope (pushed_scope);
23612 pushed_scope = NULL_TREE;
23613 }
23614 decl = grokfield (declarator, decl_specifiers,
23615 initializer, !is_non_constant_init,
23616 /*asmspec=*/NULL_TREE,
23617 attr_chainon (attrs: attributes, attr: prefix_attributes));
23618 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
23619 cp_parser_save_default_args (parser, decl);
23620 cp_finalize_omp_declare_simd (parser, fndecl: decl);
23621 cp_finalize_oacc_routine (parser, decl, false);
23622 }
23623
23624 /* Finish processing the declaration. But, skip member
23625 declarations. */
23626 if (!member_p && decl && decl != error_mark_node && !range_for_decl_p)
23627 {
23628 cp_finish_decl (decl,
23629 initializer, !is_non_constant_init,
23630 asm_specification,
23631 /* If the initializer is in parentheses, then this is
23632 a direct-initialization, which means that an
23633 `explicit' constructor is OK. Otherwise, an
23634 `explicit' constructor cannot be used. */
23635 ((is_direct_init || !is_initialized)
23636 ? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
23637 }
23638 else if ((cxx_dialect != cxx98) && friend_p
23639 && decl && TREE_CODE (decl) == FUNCTION_DECL)
23640 /* Core issue #226 (C++0x only): A default template-argument
23641 shall not be specified in a friend class template
23642 declaration. */
23643 check_default_tmpl_args (decl, current_template_parms, /*is_primary=*/true,
23644 /*is_partial=*/false, /*is_friend_decl=*/1);
23645
23646 if (!friend_p && pushed_scope)
23647 pop_scope (pushed_scope);
23648
23649 if (function_declarator_p (declarator)
23650 && parser->fully_implicit_function_template_p)
23651 {
23652 if (member_p)
23653 decl = finish_fully_implicit_template (parser, decl);
23654 else
23655 finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
23656 }
23657
23658 if (auto_result && is_initialized && decl_specifiers->type
23659 && type_uses_auto (decl_specifiers->type))
23660 *auto_result = strip_declarator_types (TREE_TYPE (decl), declarator);
23661
23662 return decl;
23663}
23664
23665/* Parse a declarator.
23666
23667 declarator:
23668 direct-declarator
23669 ptr-operator declarator
23670
23671 abstract-declarator:
23672 ptr-operator abstract-declarator [opt]
23673 direct-abstract-declarator
23674
23675 GNU Extensions:
23676
23677 declarator:
23678 attributes [opt] direct-declarator
23679 attributes [opt] ptr-operator declarator
23680
23681 abstract-declarator:
23682 attributes [opt] ptr-operator abstract-declarator [opt]
23683 attributes [opt] direct-abstract-declarator
23684
23685 The parser flags FLAGS is used to control type-specifier parsing.
23686
23687 If CTOR_DTOR_OR_CONV_P is not NULL, *CTOR_DTOR_OR_CONV_P is used to
23688 detect constructors, destructors, deduction guides, or conversion operators.
23689 It is set to -1 if the declarator is a name, and +1 if it is a
23690 function. Otherwise it is set to zero. Usually you just want to
23691 test for >0, but internally the negative value is used.
23692
23693 (The reason for CTOR_DTOR_OR_CONV_P is that a declaration must have
23694 a decl-specifier-seq unless it declares a constructor, destructor,
23695 or conversion. It might seem that we could check this condition in
23696 semantic analysis, rather than parsing, but that makes it difficult
23697 to handle something like `f()'. We want to notice that there are
23698 no decl-specifiers, and therefore realize that this is an
23699 expression, not a declaration.)
23700
23701 If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
23702 the declarator is a direct-declarator of the form "(...)".
23703
23704 MEMBER_P is true iff this declarator is a member-declarator.
23705
23706 FRIEND_P is true iff this declarator is a friend.
23707
23708 STATIC_P is true iff the keyword static was seen. */
23709
23710static cp_declarator *
23711cp_parser_declarator (cp_parser* parser,
23712 cp_parser_declarator_kind dcl_kind,
23713 cp_parser_flags flags,
23714 int* ctor_dtor_or_conv_p,
23715 bool* parenthesized_p,
23716 bool member_p, bool friend_p, bool static_p)
23717{
23718 cp_declarator *declarator;
23719 enum tree_code code;
23720 cp_cv_quals cv_quals;
23721 tree class_type;
23722 tree gnu_attributes = NULL_TREE, std_attributes = NULL_TREE;
23723
23724 /* Assume this is not a constructor, destructor, or type-conversion
23725 operator. */
23726 if (ctor_dtor_or_conv_p)
23727 *ctor_dtor_or_conv_p = 0;
23728
23729 if (cp_parser_allow_gnu_extensions_p (parser))
23730 gnu_attributes = cp_parser_gnu_attributes_opt (parser);
23731
23732 /* Check for the ptr-operator production. */
23733 cp_parser_parse_tentatively (parser);
23734 /* Parse the ptr-operator. */
23735 code = cp_parser_ptr_operator (parser,
23736 &class_type,
23737 &cv_quals,
23738 &std_attributes);
23739
23740 /* If that worked, then we have a ptr-operator. */
23741 if (cp_parser_parse_definitely (parser))
23742 {
23743 /* If a ptr-operator was found, then this declarator was not
23744 parenthesized. */
23745 if (parenthesized_p)
23746 *parenthesized_p = false;
23747 /* The dependent declarator is optional if we are parsing an
23748 abstract-declarator. */
23749 if (dcl_kind != CP_PARSER_DECLARATOR_NAMED)
23750 cp_parser_parse_tentatively (parser);
23751
23752 /* Parse the dependent declarator. */
23753 declarator = cp_parser_declarator (parser, dcl_kind, flags,
23754 /*ctor_dtor_or_conv_p=*/NULL,
23755 /*parenthesized_p=*/NULL,
23756 member_p, friend_p, static_p);
23757
23758 /* If we are parsing an abstract-declarator, we must handle the
23759 case where the dependent declarator is absent. */
23760 if (dcl_kind != CP_PARSER_DECLARATOR_NAMED
23761 && !cp_parser_parse_definitely (parser))
23762 declarator = NULL;
23763
23764 declarator = cp_parser_make_indirect_declarator
23765 (code, class_type, cv_qualifiers: cv_quals, target: declarator, attributes: std_attributes);
23766 }
23767 /* Everything else is a direct-declarator. */
23768 else
23769 {
23770 if (parenthesized_p)
23771 *parenthesized_p = cp_lexer_next_token_is (lexer: parser->lexer,
23772 type: CPP_OPEN_PAREN);
23773 declarator = cp_parser_direct_declarator (parser, dcl_kind,
23774 flags, ctor_dtor_or_conv_p,
23775 member_p, friend_p, static_p);
23776 }
23777
23778 if (gnu_attributes && declarator && declarator != cp_error_declarator)
23779 declarator->attributes = gnu_attributes;
23780 return declarator;
23781}
23782
23783/* Parse a direct-declarator or direct-abstract-declarator.
23784
23785 direct-declarator:
23786 declarator-id
23787 direct-declarator ( parameter-declaration-clause )
23788 cv-qualifier-seq [opt]
23789 ref-qualifier [opt]
23790 exception-specification [opt]
23791 direct-declarator [ constant-expression [opt] ]
23792 ( declarator )
23793
23794 direct-abstract-declarator:
23795 direct-abstract-declarator [opt]
23796 ( parameter-declaration-clause )
23797 cv-qualifier-seq [opt]
23798 ref-qualifier [opt]
23799 exception-specification [opt]
23800 direct-abstract-declarator [opt] [ constant-expression [opt] ]
23801 ( abstract-declarator )
23802
23803 Returns a representation of the declarator. DCL_KIND is
23804 CP_PARSER_DECLARATOR_ABSTRACT, if we are parsing a
23805 direct-abstract-declarator. It is CP_PARSER_DECLARATOR_NAMED, if
23806 we are parsing a direct-declarator. It is
23807 CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
23808 of ambiguity we prefer an abstract declarator, as per
23809 [dcl.ambig.res].
23810 The parser flags FLAGS is used to control type-specifier parsing.
23811 CTOR_DTOR_OR_CONV_P, MEMBER_P, FRIEND_P, and STATIC_P are
23812 as for cp_parser_declarator. */
23813
23814static cp_declarator *
23815cp_parser_direct_declarator (cp_parser* parser,
23816 cp_parser_declarator_kind dcl_kind,
23817 cp_parser_flags flags,
23818 int* ctor_dtor_or_conv_p,
23819 bool member_p, bool friend_p, bool static_p)
23820{
23821 cp_token *token;
23822 cp_declarator *declarator = NULL;
23823 tree scope = NULL_TREE;
23824 bool saved_default_arg_ok_p = parser->default_arg_ok_p;
23825 bool saved_in_declarator_p = parser->in_declarator_p;
23826 bool first = true;
23827 tree pushed_scope = NULL_TREE;
23828 cp_token *open_paren = NULL, *close_paren = NULL;
23829
23830 while (true)
23831 {
23832 /* Peek at the next token. */
23833 token = cp_lexer_peek_token (lexer: parser->lexer);
23834 if (token->type == CPP_OPEN_PAREN)
23835 {
23836 /* This is either a parameter-declaration-clause, or a
23837 parenthesized declarator. When we know we are parsing a
23838 named declarator, it must be a parenthesized declarator
23839 if FIRST is true. For instance, `(int)' is a
23840 parameter-declaration-clause, with an omitted
23841 direct-abstract-declarator. But `((*))', is a
23842 parenthesized abstract declarator. Finally, when T is a
23843 template parameter `(T)' is a
23844 parameter-declaration-clause, and not a parenthesized
23845 named declarator.
23846
23847 We first try and parse a parameter-declaration-clause,
23848 and then try a nested declarator (if FIRST is true).
23849
23850 It is not an error for it not to be a
23851 parameter-declaration-clause, even when FIRST is
23852 false. Consider,
23853
23854 int i (int);
23855 int i (3);
23856
23857 The first is the declaration of a function while the
23858 second is the definition of a variable, including its
23859 initializer.
23860
23861 Having seen only the parenthesis, we cannot know which of
23862 these two alternatives should be selected. Even more
23863 complex are examples like:
23864
23865 int i (int (a));
23866 int i (int (3));
23867
23868 The former is a function-declaration; the latter is a
23869 variable initialization.
23870
23871 Thus again, we try a parameter-declaration-clause, and if
23872 that fails, we back out and return. */
23873
23874 if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
23875 {
23876 tree params;
23877 bool is_declarator = false;
23878
23879 open_paren = NULL;
23880
23881 /* In a member-declarator, the only valid interpretation
23882 of a parenthesis is the start of a
23883 parameter-declaration-clause. (It is invalid to
23884 initialize a static data member with a parenthesized
23885 initializer; only the "=" form of initialization is
23886 permitted.) */
23887 if (!member_p)
23888 cp_parser_parse_tentatively (parser);
23889
23890 /* Consume the `('. */
23891 const location_t parens_start = token->location;
23892 matching_parens parens;
23893 parens.consume_open (parser);
23894 if (first)
23895 {
23896 /* If this is going to be an abstract declarator, we're
23897 in a declarator and we can't have default args. */
23898 parser->default_arg_ok_p = false;
23899 parser->in_declarator_p = true;
23900 }
23901
23902 begin_scope (sk_function_parms, NULL_TREE);
23903
23904 /* Parse the parameter-declaration-clause. */
23905 params
23906 = cp_parser_parameter_declaration_clause (parser, flags);
23907 const location_t parens_end
23908 = cp_lexer_peek_token (lexer: parser->lexer)->location;
23909
23910 /* Consume the `)'. */
23911 parens.require_close (parser);
23912
23913 /* For code like
23914 int x(auto(42));
23915 A a(auto(i), 42);
23916 we have synthesized an implicit template parameter and marked
23917 what we thought was a function as an implicit function template.
23918 But now, having seen the whole parameter list, we know it's not
23919 a function declaration, so undo that. */
23920 if (cp_parser_error_occurred (parser)
23921 && parser->fully_implicit_function_template_p
23922 /* Don't do this for the inner (). */
23923 && parser->default_arg_ok_p)
23924 abort_fully_implicit_template (parser);
23925
23926 /* If all went well, parse the cv-qualifier-seq,
23927 ref-qualifier and the exception-specification. */
23928 if (member_p || cp_parser_parse_definitely (parser))
23929 {
23930 cp_cv_quals cv_quals;
23931 cp_virt_specifiers virt_specifiers;
23932 cp_ref_qualifier ref_qual;
23933 tree exception_specification;
23934 tree late_return;
23935 tree attrs;
23936 bool memfn = (member_p || (pushed_scope
23937 && CLASS_TYPE_P (pushed_scope)));
23938 unsigned char local_variables_forbidden_p
23939 = parser->local_variables_forbidden_p;
23940 /* 'this' is not allowed in static member functions. */
23941 if (static_p || friend_p)
23942 parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
23943
23944 is_declarator = true;
23945
23946 if (ctor_dtor_or_conv_p)
23947 *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
23948 first = false;
23949
23950 /* Parse the cv-qualifier-seq. */
23951 cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
23952 /* Parse the ref-qualifier. */
23953 ref_qual = cp_parser_ref_qualifier_opt (parser);
23954 /* Parse the tx-qualifier. */
23955 tree tx_qual = cp_parser_tx_qualifier_opt (parser);
23956
23957 tree save_ccp = current_class_ptr;
23958 tree save_ccr = current_class_ref;
23959 if (memfn && !friend_p && !static_p)
23960 /* DR 1207: 'this' is in scope after the cv-quals. */
23961 inject_this_parameter (current_class_type, cv_quals);
23962
23963 /* If it turned out that this is e.g. a pointer to a
23964 function, we don't want to delay noexcept parsing. */
23965 if (declarator == NULL || declarator->kind != cdk_id)
23966 flags &= ~CP_PARSER_FLAGS_DELAY_NOEXCEPT;
23967
23968 /* Parse the exception-specification. */
23969 exception_specification
23970 = cp_parser_exception_specification_opt (parser,
23971 flags);
23972
23973 attrs = cp_parser_std_attribute_spec_seq (parser);
23974
23975 cp_omp_declare_simd_data odsd;
23976 if ((flag_openmp || flag_openmp_simd)
23977 && declarator
23978 && declarator->std_attributes
23979 && declarator->kind == cdk_id)
23980 {
23981 tree *pa = &declarator->std_attributes;
23982 cp_parser_handle_directive_omp_attributes (parser, pattrs: pa,
23983 data: &odsd, start: false);
23984 }
23985
23986 /* In here, we handle cases where attribute is used after
23987 the function declaration. For example:
23988 void func (int x) __attribute__((vector(..))); */
23989 tree gnu_attrs = NULL_TREE;
23990 tree requires_clause = NULL_TREE;
23991 late_return
23992 = cp_parser_late_return_type_opt (parser, declarator,
23993 requires_clause);
23994
23995 cp_finalize_omp_declare_simd (parser, data: &odsd);
23996
23997 /* Parse the virt-specifier-seq. */
23998 virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
23999
24000 location_t parens_loc = make_location (caret: parens_start,
24001 start: parens_start,
24002 finish: parens_end);
24003 /* Create the function-declarator. */
24004 declarator = make_call_declarator (target: declarator,
24005 parms: params,
24006 cv_qualifiers: cv_quals,
24007 virt_specifiers,
24008 ref_qualifier: ref_qual,
24009 tx_qualifier: tx_qual,
24010 exception_specification,
24011 late_return_type: late_return,
24012 requires_clause,
24013 std_attrs: attrs,
24014 parens_loc);
24015 declarator->attributes = gnu_attrs;
24016 /* Any subsequent parameter lists are to do with
24017 return type, so are not those of the declared
24018 function. */
24019 parser->default_arg_ok_p = false;
24020
24021 current_class_ptr = save_ccp;
24022 current_class_ref = save_ccr;
24023
24024 /* Restore the state of local_variables_forbidden_p. */
24025 parser->local_variables_forbidden_p
24026 = local_variables_forbidden_p;
24027 }
24028
24029 /* Remove the function parms from scope. */
24030 pop_bindings_and_leave_scope ();
24031
24032 if (is_declarator)
24033 /* Repeat the main loop. */
24034 continue;
24035 }
24036
24037 /* If this is the first, we can try a parenthesized
24038 declarator. */
24039 if (first)
24040 {
24041 bool saved_in_type_id_in_expr_p;
24042
24043 parser->default_arg_ok_p = saved_default_arg_ok_p;
24044 parser->in_declarator_p = saved_in_declarator_p;
24045
24046 open_paren = token;
24047 /* Consume the `('. */
24048 matching_parens parens;
24049 parens.consume_open (parser);
24050 /* Parse the nested declarator. */
24051 saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
24052 parser->in_type_id_in_expr_p = true;
24053 declarator
24054 = cp_parser_declarator (parser, dcl_kind, flags,
24055 ctor_dtor_or_conv_p,
24056 /*parenthesized_p=*/NULL,
24057 member_p, friend_p,
24058 /*static_p=*/false);
24059 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
24060 first = false;
24061 /* Expect a `)'. */
24062 close_paren = cp_lexer_peek_token (lexer: parser->lexer);
24063 if (!parens.require_close (parser))
24064 declarator = cp_error_declarator;
24065 if (declarator == cp_error_declarator)
24066 break;
24067
24068 goto handle_declarator;
24069 }
24070 /* Otherwise, we must be done. */
24071 else
24072 break;
24073 }
24074 else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
24075 && token->type == CPP_OPEN_SQUARE
24076 && !cp_next_tokens_can_be_attribute_p (parser))
24077 {
24078 /* Parse an array-declarator. */
24079 tree bounds, attrs;
24080
24081 if (ctor_dtor_or_conv_p)
24082 *ctor_dtor_or_conv_p = 0;
24083
24084 open_paren = NULL;
24085 first = false;
24086 parser->default_arg_ok_p = false;
24087 parser->in_declarator_p = true;
24088 /* Consume the `['. */
24089 cp_lexer_consume_token (lexer: parser->lexer);
24090 /* Peek at the next token. */
24091 token = cp_lexer_peek_token (lexer: parser->lexer);
24092 /* If the next token is `]', then there is no
24093 constant-expression. */
24094 if (token->type != CPP_CLOSE_SQUARE)
24095 {
24096 bool non_constant_p;
24097 bounds
24098 = cp_parser_constant_expression (parser,
24099 /*allow_non_constant=*/allow_non_constant_p: true,
24100 non_constant_p: &non_constant_p);
24101 if (!non_constant_p)
24102 /* OK */;
24103 else if (error_operand_p (t: bounds))
24104 /* Already gave an error. */;
24105 else if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
24106 /* Let compute_array_index_type diagnose this. */;
24107 else if (!parser->in_function_body
24108 || parsing_function_declarator ())
24109 {
24110 /* Normally, the array bound must be an integral constant
24111 expression. However, as an extension, we allow VLAs
24112 in function scopes as long as they aren't part of a
24113 parameter declaration. */
24114 cp_parser_error (parser,
24115 gmsgid: "array bound is not an integer constant");
24116 bounds = error_mark_node;
24117 }
24118 else if (processing_template_decl
24119 && !type_dependent_expression_p (bounds))
24120 {
24121 /* Remember this wasn't a constant-expression. */
24122 bounds = build_nop (TREE_TYPE (bounds), bounds);
24123 TREE_SIDE_EFFECTS (bounds) = 1;
24124 }
24125 }
24126 else
24127 bounds = NULL_TREE;
24128 /* Look for the closing `]'. */
24129 if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
24130 {
24131 declarator = cp_error_declarator;
24132 break;
24133 }
24134
24135 attrs = cp_parser_std_attribute_spec_seq (parser);
24136 declarator = make_array_declarator (element: declarator, bounds);
24137 declarator->std_attributes = attrs;
24138 }
24139 else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
24140 {
24141 {
24142 tree qualifying_scope;
24143 tree unqualified_name;
24144 tree attrs;
24145 special_function_kind sfk;
24146 bool abstract_ok;
24147 bool pack_expansion_p = false;
24148 cp_token *declarator_id_start_token;
24149
24150 /* Parse a declarator-id */
24151 abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
24152 if (abstract_ok)
24153 {
24154 cp_parser_parse_tentatively (parser);
24155
24156 /* If we see an ellipsis, we should be looking at a
24157 parameter pack. */
24158 if (token->type == CPP_ELLIPSIS)
24159 {
24160 /* Consume the `...' */
24161 cp_lexer_consume_token (lexer: parser->lexer);
24162
24163 pack_expansion_p = true;
24164 }
24165 }
24166
24167 declarator_id_start_token = cp_lexer_peek_token (lexer: parser->lexer);
24168 unqualified_name
24169 = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
24170 qualifying_scope = parser->scope;
24171 if (abstract_ok)
24172 {
24173 bool okay = false;
24174
24175 if (!unqualified_name && pack_expansion_p)
24176 {
24177 /* Check whether an error occurred. */
24178 okay = !cp_parser_error_occurred (parser);
24179
24180 /* We already consumed the ellipsis to mark a
24181 parameter pack, but we have no way to report it,
24182 so abort the tentative parse. We will be exiting
24183 immediately anyway. */
24184 cp_parser_abort_tentative_parse (parser);
24185 }
24186 else
24187 okay = cp_parser_parse_definitely (parser);
24188
24189 if (!okay)
24190 unqualified_name = error_mark_node;
24191 else if (unqualified_name
24192 && (qualifying_scope
24193 || (!identifier_p (t: unqualified_name))))
24194 {
24195 cp_parser_error (parser, gmsgid: "expected unqualified-id");
24196 unqualified_name = error_mark_node;
24197 }
24198 }
24199
24200 if (!unqualified_name)
24201 return NULL;
24202 if (unqualified_name == error_mark_node)
24203 {
24204 declarator = cp_error_declarator;
24205 pack_expansion_p = false;
24206 declarator->parameter_pack_p = false;
24207 break;
24208 }
24209
24210 attrs = cp_parser_std_attribute_spec_seq (parser);
24211
24212 if (qualifying_scope && at_namespace_scope_p ()
24213 && TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
24214 {
24215 /* In the declaration of a member of a template class
24216 outside of the class itself, the SCOPE will sometimes
24217 be a TYPENAME_TYPE. For example, given:
24218
24219 template <typename T>
24220 int S<T>::R::i = 3;
24221
24222 the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In
24223 this context, we must resolve S<T>::R to an ordinary
24224 type, rather than a typename type.
24225
24226 The reason we normally avoid resolving TYPENAME_TYPEs
24227 is that a specialization of `S' might render
24228 `S<T>::R' not a type. However, if `S' is
24229 specialized, then this `i' will not be used, so there
24230 is no harm in resolving the types here. */
24231 tree type;
24232
24233 /* Resolve the TYPENAME_TYPE. */
24234 type = resolve_typename_type (qualifying_scope,
24235 /*only_current_p=*/false);
24236 /* If that failed, the declarator is invalid. */
24237 if (TREE_CODE (type) == TYPENAME_TYPE)
24238 {
24239 if (typedef_variant_p (type))
24240 error_at (declarator_id_start_token->location,
24241 "cannot define member of dependent typedef "
24242 "%qT", type);
24243 else
24244 error_at (declarator_id_start_token->location,
24245 "%<%T::%E%> is not a type",
24246 TYPE_CONTEXT (qualifying_scope),
24247 TYPE_IDENTIFIER (qualifying_scope));
24248 }
24249 qualifying_scope = type;
24250 }
24251
24252 sfk = sfk_none;
24253
24254 if (unqualified_name)
24255 {
24256 tree class_type;
24257
24258 if (qualifying_scope
24259 && CLASS_TYPE_P (qualifying_scope))
24260 class_type = qualifying_scope;
24261 else
24262 class_type = current_class_type;
24263
24264 if (TREE_CODE (unqualified_name) == TYPE_DECL)
24265 {
24266 tree name_type = TREE_TYPE (unqualified_name);
24267
24268 if (!class_type || !same_type_p (name_type, class_type))
24269 {
24270 /* We do not attempt to print the declarator
24271 here because we do not have enough
24272 information about its original syntactic
24273 form. */
24274 cp_parser_error (parser, gmsgid: "invalid declarator");
24275 declarator = cp_error_declarator;
24276 break;
24277 }
24278 else if (qualifying_scope
24279 && CLASSTYPE_USE_TEMPLATE (name_type))
24280 {
24281 error_at (declarator_id_start_token->location,
24282 "invalid use of constructor as a template");
24283 inform (declarator_id_start_token->location,
24284 "use %<%T::%D%> instead of %<%T::%D%> to "
24285 "name the constructor in a qualified name",
24286 class_type,
24287 DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
24288 class_type, name_type);
24289 declarator = cp_error_declarator;
24290 break;
24291 }
24292 unqualified_name = constructor_name (class_type);
24293 }
24294
24295 if (class_type)
24296 {
24297 if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
24298 sfk = sfk_destructor;
24299 else if (identifier_p (t: unqualified_name)
24300 && IDENTIFIER_CONV_OP_P (unqualified_name))
24301 sfk = sfk_conversion;
24302 else if (/* There's no way to declare a constructor
24303 for an unnamed type, even if the type
24304 got a name for linkage purposes. */
24305 !TYPE_WAS_UNNAMED (class_type)
24306 /* Handle correctly (c++/19200):
24307
24308 struct S {
24309 struct T{};
24310 friend void S(T);
24311 };
24312
24313 and also:
24314
24315 namespace N {
24316 void S();
24317 }
24318
24319 struct S {
24320 friend void N::S();
24321 }; */
24322 && (!friend_p || class_type == qualifying_scope)
24323 && constructor_name_p (unqualified_name,
24324 class_type))
24325 sfk = sfk_constructor;
24326 else if (is_overloaded_fn (unqualified_name)
24327 && DECL_CONSTRUCTOR_P (get_first_fn
24328 (unqualified_name)))
24329 sfk = sfk_constructor;
24330
24331 if (ctor_dtor_or_conv_p && sfk != sfk_none)
24332 *ctor_dtor_or_conv_p = -1;
24333 }
24334 }
24335 declarator = make_id_declarator (qualifying_scope,
24336 unqualified_name,
24337 sfk, id_location: token->location);
24338 declarator->std_attributes = attrs;
24339 declarator->parameter_pack_p = pack_expansion_p;
24340
24341 if (pack_expansion_p)
24342 maybe_warn_variadic_templates ();
24343
24344 /* We're looking for this case in [temp.res]:
24345 A qualified-id is assumed to name a type if [...]
24346 - it is a decl-specifier of the decl-specifier-seq of a
24347 parameter-declaration in a declarator of a function or
24348 function template declaration, ... */
24349 if (cxx_dialect >= cxx20
24350 && (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL)
24351 && declarator->kind == cdk_id
24352 && !at_class_scope_p ()
24353 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
24354 {
24355 /* ...whose declarator-id is qualified. If it isn't, never
24356 assume the parameters to refer to types. */
24357 if (qualifying_scope == NULL_TREE)
24358 flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
24359 else
24360 {
24361 /* Now we have something like
24362 template <typename T> int C::x(S::p);
24363 which can be a function template declaration or a
24364 variable template definition. If name lookup for
24365 the declarator-id C::x finds one or more function
24366 templates, assume S::p to name a type. Otherwise,
24367 don't. */
24368 tree decl
24369 = cp_parser_lookup_name (parser, unqualified_name,
24370 none_type,
24371 /*is_template=*/false,
24372 /*is_namespace=*/false,
24373 /*check_dependency=*/false,
24374 /*ambiguous_decls=*/NULL,
24375 token->location);
24376
24377 if (!is_overloaded_fn (decl)
24378 /* Allow
24379 template<typename T>
24380 A<T>::A(T::type) { } */
24381 && !(MAYBE_CLASS_TYPE_P (qualifying_scope)
24382 && constructor_name_p (unqualified_name,
24383 qualifying_scope)))
24384 flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
24385 }
24386 }
24387 }
24388
24389 handle_declarator:;
24390 scope = get_scope_of_declarator (declarator);
24391 if (scope)
24392 {
24393 /* Any names that appear after the declarator-id for a
24394 member are looked up in the containing scope. */
24395 if (at_function_scope_p ())
24396 {
24397 /* But declarations with qualified-ids can't appear in a
24398 function. */
24399 cp_parser_error (parser, gmsgid: "qualified-id in declaration");
24400 declarator = cp_error_declarator;
24401 break;
24402 }
24403 pushed_scope = push_scope (scope);
24404 }
24405 parser->in_declarator_p = true;
24406 if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
24407 || (declarator && declarator->kind == cdk_id))
24408 /* Default args are only allowed on function
24409 declarations. */
24410 parser->default_arg_ok_p = saved_default_arg_ok_p;
24411 else
24412 parser->default_arg_ok_p = false;
24413
24414 first = false;
24415 }
24416 /* We're done. */
24417 else
24418 break;
24419 }
24420
24421 /* For an abstract declarator, we might wind up with nothing at this
24422 point. That's an error; the declarator is not optional. */
24423 if (!declarator)
24424 cp_parser_error (parser, gmsgid: "expected declarator");
24425 else if (open_paren)
24426 {
24427 /* Record overly parenthesized declarator so we can give a
24428 diagnostic about confusing decl/expr disambiguation. */
24429 if (declarator->kind == cdk_array)
24430 {
24431 /* If the open and close parens are on different lines, this
24432 is probably a formatting thing, so ignore. */
24433 expanded_location open = expand_location (open_paren->location);
24434 expanded_location close = expand_location (close_paren->location);
24435 if (open.line != close.line || open.file != close.file)
24436 open_paren = NULL;
24437 }
24438 if (open_paren)
24439 declarator->parenthesized = make_location (caret: open_paren->location,
24440 start: open_paren->location,
24441 finish: close_paren->location);
24442 }
24443
24444 /* If we entered a scope, we must exit it now. */
24445 if (pushed_scope)
24446 pop_scope (pushed_scope);
24447
24448 parser->default_arg_ok_p = saved_default_arg_ok_p;
24449 parser->in_declarator_p = saved_in_declarator_p;
24450
24451 return declarator;
24452}
24453
24454/* Parse a ptr-operator.
24455
24456 ptr-operator:
24457 * attribute-specifier-seq [opt] cv-qualifier-seq [opt] (C++11)
24458 * cv-qualifier-seq [opt]
24459 &
24460 :: [opt] nested-name-specifier * cv-qualifier-seq [opt]
24461 nested-name-specifier * attribute-specifier-seq [opt] cv-qualifier-seq [opt] (C++11)
24462
24463 GNU Extension:
24464
24465 ptr-operator:
24466 & cv-qualifier-seq [opt]
24467
24468 Returns INDIRECT_REF if a pointer, or pointer-to-member, was used.
24469 Returns ADDR_EXPR if a reference was used, or NON_LVALUE_EXPR for
24470 an rvalue reference. In the case of a pointer-to-member, *TYPE is
24471 filled in with the TYPE containing the member. *CV_QUALS is
24472 filled in with the cv-qualifier-seq, or TYPE_UNQUALIFIED, if there
24473 are no cv-qualifiers. Returns ERROR_MARK if an error occurred.
24474 Note that the tree codes returned by this function have nothing
24475 to do with the types of trees that will be eventually be created
24476 to represent the pointer or reference type being parsed. They are
24477 just constants with suggestive names. */
24478static enum tree_code
24479cp_parser_ptr_operator (cp_parser* parser,
24480 tree* type,
24481 cp_cv_quals *cv_quals,
24482 tree *attributes)
24483{
24484 enum tree_code code = ERROR_MARK;
24485 cp_token *token;
24486 tree attrs = NULL_TREE;
24487
24488 /* Assume that it's not a pointer-to-member. */
24489 *type = NULL_TREE;
24490 /* And that there are no cv-qualifiers. */
24491 *cv_quals = TYPE_UNQUALIFIED;
24492
24493 /* Peek at the next token. */
24494 token = cp_lexer_peek_token (lexer: parser->lexer);
24495
24496 /* If it's a `*', `&' or `&&' we have a pointer or reference. */
24497 if (token->type == CPP_MULT)
24498 code = INDIRECT_REF;
24499 else if (token->type == CPP_AND)
24500 code = ADDR_EXPR;
24501 else if ((cxx_dialect != cxx98) &&
24502 token->type == CPP_AND_AND) /* C++0x only */
24503 code = NON_LVALUE_EXPR;
24504
24505 if (code != ERROR_MARK)
24506 {
24507 /* Consume the `*', `&' or `&&'. */
24508 cp_lexer_consume_token (lexer: parser->lexer);
24509
24510 /* A `*' can be followed by a cv-qualifier-seq, and so can a
24511 `&', if we are allowing GNU extensions. (The only qualifier
24512 that can legally appear after `&' is `restrict', but that is
24513 enforced during semantic analysis. */
24514 if (code == INDIRECT_REF
24515 || cp_parser_allow_gnu_extensions_p (parser))
24516 *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
24517
24518 attrs = cp_parser_std_attribute_spec_seq (parser);
24519 if (attributes != NULL)
24520 *attributes = attrs;
24521 }
24522 else
24523 {
24524 /* Try the pointer-to-member case. */
24525 cp_parser_parse_tentatively (parser);
24526 /* Look for the optional `::' operator. */
24527 cp_parser_global_scope_opt (parser,
24528 /*current_scope_valid_p=*/false);
24529 /* Look for the nested-name specifier. */
24530 token = cp_lexer_peek_token (lexer: parser->lexer);
24531 cp_parser_nested_name_specifier (parser,
24532 /*typename_keyword_p=*/false,
24533 /*check_dependency_p=*/true,
24534 /*type_p=*/false,
24535 /*is_declaration=*/false);
24536 /* If we found it, and the next token is a `*', then we are
24537 indeed looking at a pointer-to-member operator. */
24538 if (!cp_parser_error_occurred (parser)
24539 && cp_parser_require (parser, CPP_MULT, RT_MULT))
24540 {
24541 /* Indicate that the `*' operator was used. */
24542 code = INDIRECT_REF;
24543
24544 if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
24545 error_at (token->location, "%qD is a namespace", parser->scope);
24546 else if (TREE_CODE (parser->scope) == ENUMERAL_TYPE)
24547 error_at (token->location, "cannot form pointer to member of "
24548 "non-class %q#T", parser->scope);
24549 else
24550 {
24551 /* The type of which the member is a member is given by the
24552 current SCOPE. */
24553 *type = parser->scope;
24554 /* The next name will not be qualified. */
24555 parser->scope = NULL_TREE;
24556 parser->qualifying_scope = NULL_TREE;
24557 parser->object_scope = NULL_TREE;
24558 /* Look for optional c++11 attributes. */
24559 attrs = cp_parser_std_attribute_spec_seq (parser);
24560 if (attributes != NULL)
24561 *attributes = attrs;
24562 /* Look for the optional cv-qualifier-seq. */
24563 *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
24564 }
24565 }
24566 /* If that didn't work we don't have a ptr-operator. */
24567 if (!cp_parser_parse_definitely (parser))
24568 cp_parser_error (parser, gmsgid: "expected ptr-operator");
24569 }
24570
24571 return code;
24572}
24573
24574/* Parse an (optional) cv-qualifier-seq.
24575
24576 cv-qualifier-seq:
24577 cv-qualifier cv-qualifier-seq [opt]
24578
24579 cv-qualifier:
24580 const
24581 volatile
24582
24583 GNU Extension:
24584
24585 cv-qualifier:
24586 __restrict__
24587
24588 Returns a bitmask representing the cv-qualifiers. */
24589
24590static cp_cv_quals
24591cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
24592{
24593 cp_cv_quals cv_quals = TYPE_UNQUALIFIED;
24594
24595 while (true)
24596 {
24597 cp_token *token;
24598 cp_cv_quals cv_qualifier;
24599
24600 /* Peek at the next token. */
24601 token = cp_lexer_peek_token (lexer: parser->lexer);
24602 /* See if it's a cv-qualifier. */
24603 switch (token->keyword)
24604 {
24605 case RID_CONST:
24606 cv_qualifier = TYPE_QUAL_CONST;
24607 break;
24608
24609 case RID_VOLATILE:
24610 cv_qualifier = TYPE_QUAL_VOLATILE;
24611 break;
24612
24613 case RID_RESTRICT:
24614 cv_qualifier = TYPE_QUAL_RESTRICT;
24615 break;
24616
24617 default:
24618 cv_qualifier = TYPE_UNQUALIFIED;
24619 break;
24620 }
24621
24622 if (!cv_qualifier)
24623 break;
24624
24625 if (cv_quals & cv_qualifier)
24626 {
24627 gcc_rich_location richloc (token->location);
24628 richloc.add_fixit_remove ();
24629 error_at (&richloc, "duplicate cv-qualifier");
24630 cp_lexer_purge_token (lexer: parser->lexer);
24631 }
24632 else
24633 {
24634 cp_lexer_consume_token (lexer: parser->lexer);
24635 cv_quals |= cv_qualifier;
24636 }
24637 }
24638
24639 return cv_quals;
24640}
24641
24642/* Parse an (optional) ref-qualifier
24643
24644 ref-qualifier:
24645 &
24646 &&
24647
24648 Returns cp_ref_qualifier representing ref-qualifier. */
24649
24650static cp_ref_qualifier
24651cp_parser_ref_qualifier_opt (cp_parser* parser)
24652{
24653 cp_ref_qualifier ref_qual = REF_QUAL_NONE;
24654
24655 /* Don't try to parse bitwise '&' as a ref-qualifier (c++/57532). */
24656 if (cxx_dialect < cxx11 && cp_parser_parsing_tentatively (parser))
24657 return ref_qual;
24658
24659 while (true)
24660 {
24661 cp_ref_qualifier curr_ref_qual = REF_QUAL_NONE;
24662 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
24663
24664 switch (token->type)
24665 {
24666 case CPP_AND:
24667 curr_ref_qual = REF_QUAL_LVALUE;
24668 break;
24669
24670 case CPP_AND_AND:
24671 curr_ref_qual = REF_QUAL_RVALUE;
24672 break;
24673
24674 default:
24675 curr_ref_qual = REF_QUAL_NONE;
24676 break;
24677 }
24678
24679 if (!curr_ref_qual)
24680 break;
24681 else if (ref_qual)
24682 {
24683 error_at (token->location, "multiple ref-qualifiers");
24684 cp_lexer_purge_token (lexer: parser->lexer);
24685 }
24686 else
24687 {
24688 ref_qual = curr_ref_qual;
24689 cp_lexer_consume_token (lexer: parser->lexer);
24690 }
24691 }
24692
24693 return ref_qual;
24694}
24695
24696/* Parse an optional tx-qualifier.
24697
24698 tx-qualifier:
24699 transaction_safe
24700 transaction_safe_dynamic */
24701
24702static tree
24703cp_parser_tx_qualifier_opt (cp_parser *parser)
24704{
24705 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
24706 if (token->type == CPP_NAME)
24707 {
24708 tree name = token->u.value;
24709 const char *p = IDENTIFIER_POINTER (name);
24710 const int len = strlen (s: "transaction_safe");
24711 if (startswith (str: p, prefix: "transaction_safe"))
24712 {
24713 p += len;
24714 if (*p == '\0'
24715 || !strcmp (s1: p, s2: "_dynamic"))
24716 {
24717 cp_lexer_consume_token (lexer: parser->lexer);
24718 if (!flag_tm)
24719 {
24720 error ("%qE requires %<-fgnu-tm%>", name);
24721 return NULL_TREE;
24722 }
24723 else
24724 return name;
24725 }
24726 }
24727 }
24728 return NULL_TREE;
24729}
24730
24731/* Parse an (optional) virt-specifier-seq.
24732
24733 virt-specifier-seq:
24734 virt-specifier virt-specifier-seq [opt]
24735
24736 virt-specifier:
24737 override
24738 final
24739
24740 Returns a bitmask representing the virt-specifiers. */
24741
24742static cp_virt_specifiers
24743cp_parser_virt_specifier_seq_opt (cp_parser* parser)
24744{
24745 cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
24746
24747 while (true)
24748 {
24749 cp_token *token;
24750 cp_virt_specifiers virt_specifier;
24751
24752 /* Peek at the next token. */
24753 token = cp_lexer_peek_token (lexer: parser->lexer);
24754 /* See if it's a virt-specifier-qualifier. */
24755 if (token->type != CPP_NAME)
24756 break;
24757 if (id_equal (id: token->u.value, str: "override"))
24758 {
24759 maybe_warn_cpp0x (str: CPP0X_OVERRIDE_CONTROLS);
24760 virt_specifier = VIRT_SPEC_OVERRIDE;
24761 }
24762 else if (id_equal (id: token->u.value, str: "final"))
24763 {
24764 maybe_warn_cpp0x (str: CPP0X_OVERRIDE_CONTROLS);
24765 virt_specifier = VIRT_SPEC_FINAL;
24766 }
24767 else if (id_equal (id: token->u.value, str: "__final"))
24768 {
24769 virt_specifier = VIRT_SPEC_FINAL;
24770 }
24771 else
24772 break;
24773
24774 if (virt_specifiers & virt_specifier)
24775 {
24776 gcc_rich_location richloc (token->location);
24777 richloc.add_fixit_remove ();
24778 error_at (&richloc, "duplicate virt-specifier");
24779 cp_lexer_purge_token (lexer: parser->lexer);
24780 }
24781 else
24782 {
24783 cp_lexer_consume_token (lexer: parser->lexer);
24784 virt_specifiers |= virt_specifier;
24785 }
24786 }
24787 return virt_specifiers;
24788}
24789
24790/* Used by handling of trailing-return-types and NSDMI, in which 'this'
24791 is in scope even though it isn't real. */
24792
24793void
24794inject_this_parameter (tree ctype, cp_cv_quals quals)
24795{
24796 tree this_parm;
24797
24798 if (current_class_ptr)
24799 {
24800 /* We don't clear this between NSDMIs. Is it already what we want? */
24801 tree type = TREE_TYPE (TREE_TYPE (current_class_ptr));
24802 if (DECL_P (current_class_ptr)
24803 && DECL_CONTEXT (current_class_ptr) == NULL_TREE
24804 && same_type_ignoring_top_level_qualifiers_p (ctype, type)
24805 && cp_type_quals (type) == quals)
24806 return;
24807 }
24808
24809 this_parm = build_this_parm (NULL_TREE, ctype, quals);
24810 /* Clear this first to avoid shortcut in cp_build_indirect_ref. */
24811 current_class_ptr = NULL_TREE;
24812 current_class_ref
24813 = cp_build_fold_indirect_ref (this_parm);
24814 current_class_ptr = this_parm;
24815}
24816
24817/* Return true iff our current scope is a non-static data member
24818 initializer. */
24819
24820bool
24821parsing_nsdmi (void)
24822{
24823 /* We recognize NSDMI context by the context-less 'this' pointer set up
24824 by the function above. */
24825 if (current_class_ptr
24826 && TREE_CODE (current_class_ptr) == PARM_DECL
24827 && DECL_CONTEXT (current_class_ptr) == NULL_TREE)
24828 return true;
24829 return false;
24830}
24831
24832/* True if we're parsing a function declarator. */
24833
24834bool
24835parsing_function_declarator ()
24836{
24837 /* this_entity is NULL for a function parameter scope while parsing the
24838 declarator; it is set when parsing the body of the function. */
24839 return (current_binding_level->kind == sk_function_parms
24840 && !current_binding_level->this_entity);
24841}
24842
24843/* Parse a late-specified return type, if any. This is not a separate
24844 non-terminal, but part of a function declarator, which looks like
24845
24846 -> trailing-type-specifier-seq abstract-declarator(opt)
24847
24848 Returns the type indicated by the type-id.
24849
24850 In addition to this, parse any queued up #pragma omp declare simd
24851 clauses, and #pragma acc routine clauses.
24852
24853 QUALS is either a bitmask of cv_qualifiers or -1 for a non-member
24854 function. */
24855
24856static tree
24857cp_parser_late_return_type_opt (cp_parser* parser, cp_declarator *declarator,
24858 tree& requires_clause)
24859{
24860 cp_token *token;
24861 tree type = NULL_TREE;
24862 bool declare_simd_p = (parser->omp_declare_simd
24863 && declarator
24864 && declarator->kind == cdk_id);
24865
24866 bool oacc_routine_p = (parser->oacc_routine
24867 && declarator
24868 && declarator->kind == cdk_id);
24869
24870 /* Peek at the next token. */
24871 token = cp_lexer_peek_token (lexer: parser->lexer);
24872 /* A late-specified return type is indicated by an initial '->'. */
24873 if (token->type != CPP_DEREF
24874 && token->keyword != RID_REQUIRES
24875 && !(token->type == CPP_NAME
24876 && token->u.value == ridpointers[RID_REQUIRES])
24877 && !(declare_simd_p || oacc_routine_p))
24878 return NULL_TREE;
24879
24880 if (token->type == CPP_DEREF)
24881 {
24882 /* Consume the ->. */
24883 cp_lexer_consume_token (lexer: parser->lexer);
24884
24885 type = cp_parser_trailing_type_id (parser);
24886 }
24887
24888 /* Function declarations may be followed by a trailing
24889 requires-clause. */
24890 requires_clause = cp_parser_requires_clause_opt (parser, false);
24891
24892 if (declare_simd_p)
24893 declarator->attributes
24894 = cp_parser_late_parsing_omp_declare_simd (parser,
24895 declarator->attributes);
24896 if (oacc_routine_p)
24897 declarator->attributes
24898 = cp_parser_late_parsing_oacc_routine (parser,
24899 declarator->attributes);
24900
24901 return type;
24902}
24903
24904/* Parse a declarator-id.
24905
24906 declarator-id:
24907 id-expression
24908 :: [opt] nested-name-specifier [opt] type-name
24909
24910 In the `id-expression' case, the value returned is as for
24911 cp_parser_id_expression if the id-expression was an unqualified-id.
24912 If the id-expression was a qualified-id, then a SCOPE_REF is
24913 returned. The first operand is the scope (either a NAMESPACE_DECL
24914 or TREE_TYPE), but the second is still just a representation of an
24915 unqualified-id. */
24916
24917static tree
24918cp_parser_declarator_id (cp_parser* parser, bool optional_p)
24919{
24920 tree id;
24921 /* The expression must be an id-expression. Assume that qualified
24922 names are the names of types so that:
24923
24924 template <class T>
24925 int S<T>::R::i = 3;
24926
24927 will work; we must treat `S<T>::R' as the name of a type.
24928 Similarly, assume that qualified names are templates, where
24929 required, so that:
24930
24931 template <class T>
24932 int S<T>::R<T>::i = 3;
24933
24934 will work, too. */
24935 id = cp_parser_id_expression (parser,
24936 /*template_keyword_p=*/false,
24937 /*check_dependency_p=*/false,
24938 /*template_p=*/NULL,
24939 /*declarator_p=*/true,
24940 optional_p);
24941 if (id && BASELINK_P (id))
24942 id = BASELINK_FUNCTIONS (id);
24943 return id;
24944}
24945
24946/* Parse a type-id.
24947
24948 type-id:
24949 type-specifier-seq abstract-declarator [opt]
24950
24951 The parser flags FLAGS is used to control type-specifier parsing.
24952
24953 If IS_TEMPLATE_ARG is true, we are parsing a template argument.
24954
24955 If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
24956 i.e. we've just seen "->".
24957
24958 Returns the TYPE specified. */
24959
24960static tree
24961cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
24962 bool is_template_arg, bool is_trailing_return,
24963 location_t *type_location)
24964{
24965 cp_decl_specifier_seq type_specifier_seq;
24966 cp_declarator *abstract_declarator;
24967
24968 /* Parse the type-specifier-seq. */
24969 cp_parser_type_specifier_seq (parser, flags,
24970 /*is_declaration=*/false,
24971 is_trailing_return,
24972 &type_specifier_seq);
24973 if (type_location)
24974 *type_location = type_specifier_seq.locations[ds_type_spec];
24975
24976 if (is_template_arg && type_specifier_seq.type
24977 && TREE_CODE (type_specifier_seq.type) == TEMPLATE_TYPE_PARM
24978 && CLASS_PLACEHOLDER_TEMPLATE (type_specifier_seq.type))
24979 /* A bare template name as a template argument is a template template
24980 argument, not a placeholder, so fail parsing it as a type argument. */
24981 {
24982 gcc_assert (cp_parser_uncommitted_to_tentative_parse_p (parser));
24983 cp_parser_simulate_error (parser);
24984 return error_mark_node;
24985 }
24986 if (type_specifier_seq.type == error_mark_node)
24987 return error_mark_node;
24988
24989 /* There might or might not be an abstract declarator. */
24990 cp_parser_parse_tentatively (parser);
24991 /* Look for the declarator. */
24992 abstract_declarator
24993 = cp_parser_declarator (parser, dcl_kind: CP_PARSER_DECLARATOR_ABSTRACT,
24994 flags: CP_PARSER_FLAGS_NONE, NULL,
24995 /*parenthesized_p=*/NULL,
24996 /*member_p=*/false,
24997 /*friend_p=*/false,
24998 /*static_p=*/false);
24999 /* Check to see if there really was a declarator. */
25000 if (!cp_parser_parse_definitely (parser))
25001 abstract_declarator = NULL;
25002
25003 bool auto_typeid_ok = false;
25004 /* The concepts TS allows 'auto' as a type-id. */
25005 if (flag_concepts_ts)
25006 auto_typeid_ok = !parser->in_type_id_in_expr_p;
25007 /* DR 625 prohibits use of auto as a template-argument. We allow 'auto'
25008 outside the template-argument-list context here only for the sake of
25009 diagnostic: grokdeclarator then can emit a better error message for
25010 e.g. using T = auto. */
25011 else if (flag_concepts)
25012 auto_typeid_ok = (!parser->in_type_id_in_expr_p
25013 && !parser->in_template_argument_list_p);
25014
25015 if (type_specifier_seq.type
25016 && !auto_typeid_ok
25017 /* None of the valid uses of 'auto' in C++14 involve the type-id
25018 nonterminal, but it is valid in a trailing-return-type. */
25019 && !(cxx_dialect >= cxx14 && is_trailing_return))
25020 if (tree auto_node = type_uses_auto (type_specifier_seq.type))
25021 {
25022 /* A type-id with type 'auto' is only ok if the abstract declarator
25023 is a function declarator with a late-specified return type.
25024
25025 A type-id with 'auto' is also valid in a trailing-return-type
25026 in a compound-requirement. */
25027 if (abstract_declarator
25028 && abstract_declarator->kind == cdk_function
25029 && abstract_declarator->u.function.late_return_type)
25030 /* OK */;
25031 else if (parser->in_result_type_constraint_p)
25032 /* OK */;
25033 else
25034 {
25035 if (!cp_parser_simulate_error (parser))
25036 {
25037 location_t loc = type_specifier_seq.locations[ds_type_spec];
25038 if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
25039 {
25040 auto_diagnostic_group g;
25041 gcc_rich_location richloc (loc);
25042 richloc.add_fixit_insert_after (new_content: "<>");
25043 error_at (&richloc, "missing template arguments after %qE",
25044 tmpl);
25045 inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
25046 tmpl);
25047 }
25048 else if (parser->in_template_argument_list_p)
25049 error_at (loc, "%qT not permitted in template argument",
25050 auto_node);
25051 else
25052 error_at (loc, "invalid use of %qT", auto_node);
25053 }
25054 return error_mark_node;
25055 }
25056 }
25057
25058 return groktypename (&type_specifier_seq, abstract_declarator,
25059 is_template_arg);
25060}
25061
25062/* Wrapper for cp_parser_type_id_1. */
25063
25064static tree
25065cp_parser_type_id (cp_parser *parser, cp_parser_flags flags,
25066 location_t *type_location)
25067{
25068 return cp_parser_type_id_1 (parser, flags, is_template_arg: false, is_trailing_return: false, type_location);
25069}
25070
25071/* Wrapper for cp_parser_type_id_1. */
25072
25073static tree
25074cp_parser_template_type_arg (cp_parser *parser)
25075{
25076 const char *saved_message = parser->type_definition_forbidden_message;
25077 parser->type_definition_forbidden_message
25078 = G_("types may not be defined in template arguments");
25079 tree r = cp_parser_type_id_1 (parser, flags: CP_PARSER_FLAGS_NONE,
25080 /*is_template_arg=*/true,
25081 /*is_trailing_return=*/false, type_location: nullptr);
25082 parser->type_definition_forbidden_message = saved_message;
25083 /* cp_parser_type_id_1 checks for auto, but only for
25084 ->auto_is_implicit_function_template_parm_p. */
25085 if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r))
25086 {
25087 error ("invalid use of %<auto%> in template argument");
25088 r = error_mark_node;
25089 }
25090 return r;
25091}
25092
25093/* Wrapper for cp_parser_type_id_1. */
25094
25095static tree
25096cp_parser_trailing_type_id (cp_parser *parser)
25097{
25098 return cp_parser_type_id_1 (parser, flags: CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
25099 is_template_arg: false, is_trailing_return: true, NULL);
25100}
25101
25102/* Parse a type-specifier-seq.
25103
25104 type-specifier-seq:
25105 type-specifier type-specifier-seq [opt]
25106
25107 GNU extension:
25108
25109 type-specifier-seq:
25110 attributes type-specifier-seq [opt]
25111
25112 The parser flags FLAGS is used to control type-specifier parsing.
25113
25114 If IS_DECLARATION is true, we are at the start of a "condition" or
25115 exception-declaration, so we might be followed by a declarator-id.
25116
25117 If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
25118 i.e. we've just seen "->".
25119
25120 Sets *TYPE_SPECIFIER_SEQ to represent the sequence. */
25121
25122static void
25123cp_parser_type_specifier_seq (cp_parser* parser,
25124 cp_parser_flags flags,
25125 bool is_declaration,
25126 bool is_trailing_return,
25127 cp_decl_specifier_seq *type_specifier_seq)
25128{
25129 bool seen_type_specifier = false;
25130 cp_token *start_token = NULL;
25131
25132 /* Clear the TYPE_SPECIFIER_SEQ. */
25133 clear_decl_specs (decl_specs: type_specifier_seq);
25134
25135 flags |= CP_PARSER_FLAGS_OPTIONAL;
25136 /* In the context of a trailing return type, enum E { } is an
25137 elaborated-type-specifier followed by a function-body, not an
25138 enum-specifier. */
25139 if (is_trailing_return)
25140 flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
25141
25142 /* Parse the type-specifiers and attributes. */
25143 while (true)
25144 {
25145 tree type_specifier;
25146 bool is_cv_qualifier;
25147
25148 /* Check for attributes first. */
25149 if (cp_next_tokens_can_be_attribute_p (parser))
25150 {
25151 /* GNU attributes at the end of a declaration apply to the
25152 declaration as a whole, not to the trailing return type. So look
25153 ahead to see if these attributes are at the end. */
25154 if (seen_type_specifier && is_trailing_return
25155 && cp_next_tokens_can_be_gnu_attribute_p (parser))
25156 {
25157 size_t n = cp_parser_skip_attributes_opt (parser, 1);
25158 cp_token *tok = cp_lexer_peek_nth_token (lexer: parser->lexer, n);
25159 if (tok->type == CPP_SEMICOLON || tok->type == CPP_COMMA
25160 || tok->type == CPP_EQ || tok->type == CPP_OPEN_BRACE)
25161 break;
25162 }
25163 type_specifier_seq->attributes
25164 = attr_chainon (attrs: type_specifier_seq->attributes,
25165 attr: cp_parser_attributes_opt (parser));
25166 continue;
25167 }
25168
25169 /* record the token of the beginning of the type specifier seq,
25170 for error reporting purposes*/
25171 if (!start_token)
25172 start_token = cp_lexer_peek_token (lexer: parser->lexer);
25173
25174 /* Look for the type-specifier. */
25175 type_specifier = cp_parser_type_specifier (parser,
25176 flags,
25177 decl_specs: type_specifier_seq,
25178 /*is_declaration=*/false,
25179 NULL,
25180 is_cv_qualifier: &is_cv_qualifier);
25181 if (!type_specifier)
25182 {
25183 /* If the first type-specifier could not be found, this is not a
25184 type-specifier-seq at all. */
25185 if (!seen_type_specifier)
25186 {
25187 /* Set in_declarator_p to avoid skipping to the semicolon. */
25188 int in_decl = parser->in_declarator_p;
25189 parser->in_declarator_p = true;
25190
25191 if (cp_parser_uncommitted_to_tentative_parse_p (parser)
25192 || !cp_parser_parse_and_diagnose_invalid_type_name (parser))
25193 cp_parser_error (parser, gmsgid: "expected type-specifier");
25194
25195 parser->in_declarator_p = in_decl;
25196
25197 type_specifier_seq->type = error_mark_node;
25198 return;
25199 }
25200 /* If subsequent type-specifiers could not be found, the
25201 type-specifier-seq is complete. */
25202 break;
25203 }
25204
25205 seen_type_specifier = true;
25206 /* The standard says that a condition can be:
25207
25208 type-specifier-seq declarator = assignment-expression
25209
25210 However, given:
25211
25212 struct S {};
25213 if (int S = ...)
25214
25215 we should treat the "S" as a declarator, not as a
25216 type-specifier. The standard doesn't say that explicitly for
25217 type-specifier-seq, but it does say that for
25218 decl-specifier-seq in an ordinary declaration. Perhaps it
25219 would be clearer just to allow a decl-specifier-seq here, and
25220 then add a semantic restriction that if any decl-specifiers
25221 that are not type-specifiers appear, the program is invalid. */
25222 if (is_declaration && !is_cv_qualifier)
25223 flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
25224 }
25225}
25226
25227/* Return whether the function currently being declared has an associated
25228 template parameter list. */
25229
25230static bool
25231function_being_declared_is_template_p (cp_parser* parser)
25232{
25233 if (!current_template_parms || processing_template_parmlist)
25234 return false;
25235
25236 if (parser->implicit_template_scope)
25237 return true;
25238
25239 if (at_class_scope_p ()
25240 && TYPE_BEING_DEFINED (current_class_type))
25241 return parser->num_template_parameter_lists != 0;
25242
25243 return ((int) parser->num_template_parameter_lists > template_class_depth
25244 (current_class_type));
25245}
25246
25247/* Parse a parameter-declaration-clause.
25248
25249 parameter-declaration-clause:
25250 parameter-declaration-list [opt] ... [opt]
25251 parameter-declaration-list , ...
25252
25253 The parser flags FLAGS is used to control type-specifier parsing.
25254
25255 Returns a representation for the parameter declarations. A return
25256 value of NULL indicates a parameter-declaration-clause consisting
25257 only of an ellipsis. */
25258
25259static tree
25260cp_parser_parameter_declaration_clause (cp_parser* parser,
25261 cp_parser_flags flags)
25262{
25263 tree parameters;
25264 cp_token *token;
25265 bool ellipsis_p;
25266
25267 auto cleanup = make_temp_override
25268 (var&: parser->auto_is_implicit_function_template_parm_p);
25269
25270 if (!processing_specialization
25271 && !processing_template_parmlist
25272 && !processing_explicit_instantiation
25273 /* default_arg_ok_p tracks whether this is a parameter-clause for an
25274 actual function or a random abstract declarator. */
25275 && parser->default_arg_ok_p)
25276 if (!current_function_decl
25277 || (current_class_type && LAMBDA_TYPE_P (current_class_type)))
25278 parser->auto_is_implicit_function_template_parm_p = true;
25279
25280 /* Peek at the next token. */
25281 token = cp_lexer_peek_token (lexer: parser->lexer);
25282 /* Check for trivial parameter-declaration-clauses. */
25283 if (token->type == CPP_ELLIPSIS)
25284 {
25285 /* Consume the `...' token. */
25286 cp_lexer_consume_token (lexer: parser->lexer);
25287 return NULL_TREE;
25288 }
25289 else if (token->type == CPP_CLOSE_PAREN)
25290 /* There are no parameters. */
25291 return void_list_node;
25292 /* Check for `(void)', too, which is a special case. */
25293 else if (token->keyword == RID_VOID
25294 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
25295 == CPP_CLOSE_PAREN))
25296 {
25297 /* Consume the `void' token. */
25298 cp_lexer_consume_token (lexer: parser->lexer);
25299 /* There are no parameters. */
25300 return explicit_void_list_node;
25301 }
25302
25303 /* A vector of parameters that haven't been pushed yet. */
25304 auto_vec<tree> pending_decls;
25305
25306 /* Parse the parameter-declaration-list. */
25307 parameters = cp_parser_parameter_declaration_list (parser, flags,
25308 &pending_decls);
25309 /* If a parse error occurred while parsing the
25310 parameter-declaration-list, then the entire
25311 parameter-declaration-clause is erroneous. */
25312 if (parameters == error_mark_node)
25313 return NULL_TREE;
25314
25315 /* Peek at the next token. */
25316 token = cp_lexer_peek_token (lexer: parser->lexer);
25317 /* If it's a `,', the clause should terminate with an ellipsis. */
25318 if (token->type == CPP_COMMA)
25319 {
25320 /* Consume the `,'. */
25321 cp_lexer_consume_token (lexer: parser->lexer);
25322 /* Expect an ellipsis. */
25323 ellipsis_p
25324 = (cp_parser_require (parser, CPP_ELLIPSIS, RT_ELLIPSIS) != NULL);
25325 }
25326 /* It might also be `...' if the optional trailing `,' was
25327 omitted. */
25328 else if (token->type == CPP_ELLIPSIS)
25329 {
25330 /* Consume the `...' token. */
25331 cp_lexer_consume_token (lexer: parser->lexer);
25332 /* And remember that we saw it. */
25333 ellipsis_p = true;
25334 }
25335 else
25336 ellipsis_p = false;
25337
25338 /* A valid parameter-declaration-clause can only be followed by a ')'.
25339 So it's time to push all the parameters we have seen now that we
25340 know we have a valid declaration. Note that here we may not have
25341 committed yet, nor should we. Pushing here will detect the error
25342 of redefining a parameter. */
25343 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
25344 {
25345 for (tree p : pending_decls)
25346 pushdecl (p);
25347
25348 /* Delayed checking of auto parameters. */
25349 if (!parser->auto_is_implicit_function_template_parm_p
25350 && cxx_dialect >= cxx14)
25351 for (tree p = parameters; p; p = TREE_CHAIN (p))
25352 if (type_uses_auto (TREE_TYPE (TREE_VALUE (p))))
25353 {
25354 error_at (location_of (TREE_VALUE (p)),
25355 "%<auto%> parameter not permitted in this context");
25356 TREE_TYPE (TREE_VALUE (p)) = error_mark_node;
25357 }
25358 }
25359
25360 /* Finish the parameter list. */
25361 if (!ellipsis_p)
25362 parameters = chainon (parameters, void_list_node);
25363
25364 return parameters;
25365}
25366
25367/* Parse a parameter-declaration-list.
25368
25369 parameter-declaration-list:
25370 parameter-declaration
25371 parameter-declaration-list , parameter-declaration
25372
25373 The parser flags FLAGS is used to control type-specifier parsing.
25374 PENDING_DECLS is a vector of parameters that haven't been pushed yet.
25375
25376 Returns a representation of the parameter-declaration-list, as for
25377 cp_parser_parameter_declaration_clause. However, the
25378 `void_list_node' is never appended to the list. */
25379
25380static tree
25381cp_parser_parameter_declaration_list (cp_parser* parser,
25382 cp_parser_flags flags,
25383 auto_vec<tree> *pending_decls)
25384{
25385 tree parameters = NULL_TREE;
25386 tree *tail = &parameters;
25387 bool saved_in_unbraced_linkage_specification_p;
25388 int index = 0;
25389
25390 /* The special considerations that apply to a function within an
25391 unbraced linkage specifications do not apply to the parameters
25392 to the function. */
25393 saved_in_unbraced_linkage_specification_p
25394 = parser->in_unbraced_linkage_specification_p;
25395 parser->in_unbraced_linkage_specification_p = false;
25396
25397 /* Look for more parameters. */
25398 while (true)
25399 {
25400 cp_parameter_declarator *parameter;
25401 tree decl = error_mark_node;
25402 bool parenthesized_p = false;
25403
25404 /* Parse the parameter. */
25405 parameter
25406 = cp_parser_parameter_declaration (parser, flags,
25407 /*template_parm_p=*/false,
25408 &parenthesized_p);
25409
25410 /* We don't know yet if the enclosing context is unavailable or deprecated,
25411 so wait and deal with it in grokparms if appropriate. */
25412 deprecated_state = UNAVAILABLE_DEPRECATED_SUPPRESS;
25413
25414 if (parameter && !cp_parser_error_occurred (parser))
25415 {
25416 decl = grokdeclarator (parameter->declarator,
25417 &parameter->decl_specifiers,
25418 PARM,
25419 parameter->default_argument != NULL_TREE,
25420 &parameter->decl_specifiers.attributes);
25421 if (decl != error_mark_node && parameter->loc != UNKNOWN_LOCATION)
25422 DECL_SOURCE_LOCATION (decl) = parameter->loc;
25423 }
25424
25425 deprecated_state = DEPRECATED_NORMAL;
25426
25427 /* If a parse error occurred parsing the parameter declaration,
25428 then the entire parameter-declaration-list is erroneous. */
25429 if (decl == error_mark_node)
25430 {
25431 parameters = error_mark_node;
25432 break;
25433 }
25434
25435 if (parameter->decl_specifiers.attributes)
25436 cplus_decl_attributes (&decl,
25437 parameter->decl_specifiers.attributes,
25438 0);
25439 if (DECL_NAME (decl))
25440 {
25441 /* We cannot always pushdecl while parsing tentatively because
25442 it may have side effects and we can't be sure yet if we're
25443 parsing a declaration, e.g.:
25444
25445 S foo(int(x), int(x), int{x});
25446
25447 where it's not clear if we're dealing with a constructor call
25448 or a function declaration until we've seen the last argument
25449 which breaks it up.
25450 It's safe to pushdecl so long as it doesn't result in a clash
25451 with an already-pushed parameter. But we don't delay pushing
25452 different parameters to handle
25453
25454 S foo(int(i), decltype(i) j = 42);
25455
25456 which is valid. */
25457 if (pending_decls
25458 && cp_parser_uncommitted_to_tentative_parse_p (parser)
25459 /* See if PARAMETERS already contains a parameter with the same
25460 DECL_NAME as DECL. */
25461 && [parameters, decl] {
25462 for (tree p = parameters; p; p = TREE_CHAIN (p))
25463 if (DECL_NAME (decl) == DECL_NAME (TREE_VALUE (p)))
25464 return true;
25465 return false;
25466 }())
25467 pending_decls->safe_push (obj: decl);
25468 else
25469 decl = pushdecl (decl);
25470 }
25471
25472 if (decl != error_mark_node)
25473 {
25474 retrofit_lang_decl (decl);
25475 DECL_PARM_INDEX (decl) = ++index;
25476 DECL_PARM_LEVEL (decl) = function_parm_depth ();
25477 }
25478
25479 /* Add the new parameter to the list. */
25480 *tail = build_tree_list (parameter->default_argument, decl);
25481 tail = &TREE_CHAIN (*tail);
25482
25483 /* If the parameters were parenthesized, it's the case of
25484 T foo(X(x)) which looks like a variable definition but
25485 is a function declaration. */
25486 if (index == 1 || PARENTHESIZED_LIST_P (parameters))
25487 PARENTHESIZED_LIST_P (parameters) = parenthesized_p;
25488
25489 /* Peek at the next token. */
25490 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN)
25491 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS)
25492 /* These are for Objective-C++ */
25493 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)
25494 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
25495 /* The parameter-declaration-list is complete. */
25496 break;
25497 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
25498 {
25499 cp_token *token;
25500
25501 /* Peek at the next token. */
25502 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
25503 /* If it's an ellipsis, then the list is complete. */
25504 if (token->type == CPP_ELLIPSIS)
25505 break;
25506 /* Otherwise, there must be more parameters. Consume the
25507 `,'. */
25508 cp_lexer_consume_token (lexer: parser->lexer);
25509 /* When parsing something like:
25510
25511 int i(float f, double d)
25512
25513 we can tell after seeing the declaration for "f" that we
25514 are not looking at an initialization of a variable "i",
25515 but rather at the declaration of a function "i".
25516
25517 Due to the fact that the parsing of template arguments
25518 (as specified to a template-id) requires backtracking we
25519 cannot use this technique when inside a template argument
25520 list. */
25521 if (!parser->in_template_argument_list_p
25522 && !parser->in_type_id_in_expr_p
25523 && cp_parser_uncommitted_to_tentative_parse_p (parser)
25524 /* However, a parameter-declaration of the form
25525 "float(f)" (which is a valid declaration of a
25526 parameter "f") can also be interpreted as an
25527 expression (the conversion of "f" to "float"). */
25528 && !parenthesized_p)
25529 cp_parser_commit_to_tentative_parse (parser);
25530 }
25531 else
25532 {
25533 cp_parser_error (parser, gmsgid: "expected %<,%> or %<...%>");
25534 if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
25535 cp_parser_skip_to_closing_parenthesis (parser,
25536 /*recovering=*/true,
25537 /*or_comma=*/false,
25538 /*consume_paren=*/false);
25539 break;
25540 }
25541 }
25542
25543 parser->in_unbraced_linkage_specification_p
25544 = saved_in_unbraced_linkage_specification_p;
25545
25546 /* Reset implicit_template_scope if we are about to leave the function
25547 parameter list that introduced it. Note that for out-of-line member
25548 definitions, there will be one or more class scopes before we get to
25549 the template parameter scope. */
25550
25551 if (cp_binding_level *its = parser->implicit_template_scope)
25552 if (cp_binding_level *maybe_its = current_binding_level->level_chain)
25553 {
25554 while (maybe_its->kind == sk_class)
25555 maybe_its = maybe_its->level_chain;
25556 if (maybe_its == its)
25557 {
25558 parser->implicit_template_parms = 0;
25559 parser->implicit_template_scope = 0;
25560 }
25561 }
25562
25563 return parameters;
25564}
25565
25566/* Parse a parameter declaration.
25567
25568 parameter-declaration:
25569 decl-specifier-seq ... [opt] declarator
25570 decl-specifier-seq declarator = assignment-expression
25571 decl-specifier-seq ... [opt] abstract-declarator [opt]
25572 decl-specifier-seq abstract-declarator [opt] = assignment-expression
25573
25574 The parser flags FLAGS is used to control type-specifier parsing.
25575
25576 If TEMPLATE_PARM_P is TRUE, then this parameter-declaration
25577 declares a template parameter. (In that case, a non-nested `>'
25578 token encountered during the parsing of the assignment-expression
25579 is not interpreted as a greater-than operator.)
25580
25581 Returns a representation of the parameter, or NULL if an error
25582 occurs. If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to
25583 true iff the declarator is of the form "(p)". */
25584
25585static cp_parameter_declarator *
25586cp_parser_parameter_declaration (cp_parser *parser,
25587 cp_parser_flags flags,
25588 bool template_parm_p,
25589 bool *parenthesized_p)
25590{
25591 int declares_class_or_enum;
25592 cp_decl_specifier_seq decl_specifiers;
25593 cp_declarator *declarator;
25594 tree default_argument;
25595 cp_token *token = NULL, *declarator_token_start = NULL;
25596 const char *saved_message;
25597 bool template_parameter_pack_p = false;
25598
25599 /* In a template parameter, `>' is not an operator.
25600
25601 [temp.param]
25602
25603 When parsing a default template-argument for a non-type
25604 template-parameter, the first non-nested `>' is taken as the end
25605 of the template parameter-list rather than a greater-than
25606 operator. */
25607
25608 /* Type definitions may not appear in parameter types. */
25609 saved_message = parser->type_definition_forbidden_message;
25610 parser->type_definition_forbidden_message
25611 = G_("types may not be defined in parameter types");
25612
25613 int template_parm_idx = (function_being_declared_is_template_p (parser) ?
25614 TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
25615 (current_template_parms)) : 0);
25616
25617 /* Parse the declaration-specifiers. */
25618 cp_token *decl_spec_token_start = cp_lexer_peek_token (lexer: parser->lexer);
25619 cp_parser_decl_specifier_seq (parser,
25620 flags: flags | CP_PARSER_FLAGS_PARAMETER,
25621 decl_specs: &decl_specifiers,
25622 declares_class_or_enum: &declares_class_or_enum);
25623
25624 /* [dcl.spec.auto.general]: "A placeholder-type-specifier of the form
25625 type-constraint opt auto can be used as a decl-specifier of the
25626 decl-specifier-seq of a parameter-declaration of a function declaration
25627 or lambda-expression..." but we must not synthesize an implicit template
25628 type parameter in its declarator. That is, in "void f(auto[auto{10}]);"
25629 we want to synthesize only the first auto. */
25630 auto cleanup = make_temp_override
25631 (var&: parser->auto_is_implicit_function_template_parm_p, overrider: false);
25632
25633 /* Complain about missing 'typename' or other invalid type names. */
25634 if (!decl_specifiers.any_type_specifiers_p
25635 && cp_parser_parse_and_diagnose_invalid_type_name (parser))
25636 decl_specifiers.type = error_mark_node;
25637
25638 /* If an error occurred, there's no reason to attempt to parse the
25639 rest of the declaration. */
25640 if (cp_parser_error_occurred (parser))
25641 {
25642 parser->type_definition_forbidden_message = saved_message;
25643 return NULL;
25644 }
25645
25646 /* Peek at the next token. */
25647 token = cp_lexer_peek_token (lexer: parser->lexer);
25648
25649 /* If the next token is a `)', `,', `=', `>', or `...', then there
25650 is no declarator. However, when variadic templates are enabled,
25651 there may be a declarator following `...'. */
25652 if (token->type == CPP_CLOSE_PAREN
25653 || token->type == CPP_COMMA
25654 || token->type == CPP_EQ
25655 || token->type == CPP_GREATER)
25656 {
25657 declarator = NULL;
25658 if (parenthesized_p)
25659 *parenthesized_p = false;
25660 }
25661 /* Otherwise, there should be a declarator. */
25662 else
25663 {
25664 bool saved_default_arg_ok_p = parser->default_arg_ok_p;
25665 parser->default_arg_ok_p = false;
25666
25667 /* After seeing a decl-specifier-seq, if the next token is not a
25668 "(" or "{", there is no possibility that the code is a valid
25669 expression. Therefore, if parsing tentatively, we commit at
25670 this point. */
25671 if (!parser->in_template_argument_list_p
25672 /* In an expression context, having seen:
25673
25674 (int((char ...
25675
25676 we cannot be sure whether we are looking at a
25677 function-type (taking a "char" as a parameter) or a cast
25678 of some object of type "char" to "int". */
25679 && !parser->in_type_id_in_expr_p
25680 && cp_parser_uncommitted_to_tentative_parse_p (parser)
25681 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_PAREN))
25682 {
25683 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
25684 {
25685 if (decl_specifiers.type
25686 && template_placeholder_p (decl_specifiers.type))
25687 /* This is a CTAD expression, not a parameter declaration. */
25688 cp_parser_simulate_error (parser);
25689 }
25690 else
25691 cp_parser_commit_to_tentative_parse (parser);
25692 }
25693 /* Parse the declarator. */
25694 declarator_token_start = token;
25695 declarator = cp_parser_declarator (parser,
25696 dcl_kind: CP_PARSER_DECLARATOR_EITHER,
25697 flags: CP_PARSER_FLAGS_NONE,
25698 /*ctor_dtor_or_conv_p=*/NULL,
25699 parenthesized_p,
25700 /*member_p=*/false,
25701 /*friend_p=*/false,
25702 /*static_p=*/false);
25703 parser->default_arg_ok_p = saved_default_arg_ok_p;
25704 /* After the declarator, allow more attributes. */
25705 decl_specifiers.attributes
25706 = attr_chainon (attrs: decl_specifiers.attributes,
25707 attr: cp_parser_attributes_opt (parser));
25708
25709 /* If the declarator is a template parameter pack, remember that and
25710 clear the flag in the declarator itself so we don't get errors
25711 from grokdeclarator. */
25712 if (template_parm_p && declarator && declarator->parameter_pack_p)
25713 {
25714 declarator->parameter_pack_p = false;
25715 template_parameter_pack_p = true;
25716 }
25717 }
25718
25719 /* If the next token is an ellipsis, and we have not seen a declarator
25720 name, and if either the type of the declarator contains parameter
25721 packs but it is not a TYPE_PACK_EXPANSION or is null (this happens
25722 for, eg, abbreviated integral type names), then we actually have a
25723 parameter pack expansion expression. Otherwise, leave the ellipsis
25724 for a C-style variadic function. */
25725 token = cp_lexer_peek_token (lexer: parser->lexer);
25726
25727 bool xobj_param_p
25728 = decl_spec_seq_has_spec_p (&decl_specifiers, ds_this);
25729 if (xobj_param_p && template_parm_p)
25730 {
25731 error_at (decl_specifiers.locations[ds_this],
25732 "%<this%> specifier in template parameter declaration");
25733 xobj_param_p = false;
25734 decl_specifiers.locations[ds_this] = 0;
25735 }
25736
25737 /* If a function parameter pack was specified and an implicit template
25738 parameter was introduced during cp_parser_parameter_declaration,
25739 change any implicit parameters introduced into packs. */
25740 if (parser->implicit_template_parms
25741 && ((token->type == CPP_ELLIPSIS
25742 && declarator_can_be_parameter_pack (declarator))
25743 || (declarator && declarator->parameter_pack_p)))
25744 {
25745 int latest_template_parm_idx = TREE_VEC_LENGTH
25746 (INNERMOST_TEMPLATE_PARMS (current_template_parms));
25747
25748 if (latest_template_parm_idx != template_parm_idx)
25749 decl_specifiers.type
25750 = convert_generic_types_to_packs (decl_specifiers.type,
25751 template_parm_idx,
25752 latest_template_parm_idx);
25753 }
25754
25755 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
25756 {
25757 tree type = decl_specifiers.type;
25758
25759 if (type && DECL_P (type))
25760 type = TREE_TYPE (type);
25761
25762 if (((type
25763 && TREE_CODE (type) != TYPE_PACK_EXPANSION
25764 && (template_parm_p || uses_parameter_packs (type)))
25765 || (!type && template_parm_p))
25766 && declarator_can_be_parameter_pack (declarator))
25767 {
25768 /* Consume the `...'. */
25769 cp_lexer_consume_token (lexer: parser->lexer);
25770 maybe_warn_variadic_templates ();
25771
25772 /* Build a pack expansion type */
25773 if (template_parm_p)
25774 template_parameter_pack_p = true;
25775 else if (declarator)
25776 declarator->parameter_pack_p = true;
25777 else
25778 decl_specifiers.type = make_pack_expansion (type);
25779 }
25780 }
25781
25782 if (xobj_param_p
25783 && ((declarator && declarator->parameter_pack_p)
25784 || (decl_specifiers.type
25785 && PACK_EXPANSION_P (decl_specifiers.type))))
25786 {
25787 location_t xobj_param
25788 = make_location (caret: decl_specifiers.locations[ds_this],
25789 start: decl_spec_token_start->location,
25790 finish: input_location);
25791 error_at (xobj_param,
25792 "an explicit object parameter cannot "
25793 "be a function parameter pack");
25794 xobj_param_p = false;
25795 decl_specifiers.locations[ds_this] = 0;
25796 }
25797
25798 /* The restriction on defining new types applies only to the type
25799 of the parameter, not to the default argument. */
25800 parser->type_definition_forbidden_message = saved_message;
25801 cp_token *eq_token = NULL;
25802 /* If the next token is `=', then process a default argument. */
25803 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
25804 {
25805 tree type = decl_specifiers.type;
25806 token = cp_lexer_peek_token (lexer: parser->lexer);
25807 /* Used for diagnostics with an xobj parameter. */
25808 eq_token = token;
25809 if (declarator)
25810 declarator->init_loc = token->location;
25811 /* If we are defining a class, then the tokens that make up the
25812 default argument must be saved and processed later. */
25813 if (!template_parm_p && at_class_scope_p ()
25814 && TYPE_BEING_DEFINED (current_class_type)
25815 && !LAMBDA_TYPE_P (current_class_type))
25816 default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false);
25817
25818 /* A constrained-type-specifier may declare a type
25819 template-parameter. */
25820 else if (declares_constrained_type_template_parameter (type))
25821 default_argument
25822 = cp_parser_default_type_template_argument (parser);
25823
25824 /* A constrained-type-specifier may declare a
25825 template-template-parameter. */
25826 else if (declares_constrained_template_template_parameter (type))
25827 default_argument
25828 = cp_parser_default_template_template_argument (parser);
25829
25830 /* Outside of a class definition, we can just parse the
25831 assignment-expression. */
25832 else
25833 default_argument
25834 = cp_parser_default_argument (parser, template_parm_p);
25835
25836 if (!parser->default_arg_ok_p)
25837 {
25838 permerror (token->location,
25839 "default arguments are only "
25840 "permitted for function parameters");
25841 }
25842 else if ((declarator && declarator->parameter_pack_p)
25843 || template_parameter_pack_p
25844 || (decl_specifiers.type
25845 && PACK_EXPANSION_P (decl_specifiers.type)))
25846 {
25847 /* Find the name of the parameter pack. */
25848 cp_declarator *id_declarator = declarator;
25849 while (id_declarator && id_declarator->kind != cdk_id)
25850 id_declarator = id_declarator->declarator;
25851
25852 if (id_declarator && id_declarator->kind == cdk_id)
25853 error_at (declarator_token_start->location,
25854 template_parm_p
25855 ? G_("template parameter pack %qD "
25856 "cannot have a default argument")
25857 : G_("parameter pack %qD cannot have "
25858 "a default argument"),
25859 id_declarator->u.id.unqualified_name);
25860 else
25861 error_at (declarator_token_start->location,
25862 template_parm_p
25863 ? G_("template parameter pack cannot have "
25864 "a default argument")
25865 : G_("parameter pack cannot have a "
25866 "default argument"));
25867
25868 default_argument = NULL_TREE;
25869 }
25870 }
25871 else
25872 default_argument = NULL_TREE;
25873
25874 if (default_argument)
25875 STRIP_ANY_LOCATION_WRAPPER (default_argument);
25876
25877 if (xobj_param_p)
25878 {
25879 if (default_argument)
25880 {
25881 /* If there is a default_argument, eq_token should always be set. */
25882 gcc_assert (eq_token);
25883 location_t param_with_init_loc
25884 = make_location (caret: eq_token->location,
25885 start: decl_spec_token_start->location,
25886 finish: input_location);
25887 error_at (param_with_init_loc,
25888 "an explicit object parameter "
25889 "may not have a default argument");
25890 }
25891 /* Xobj parameters can not have default arguments, thus
25892 we can reuse the default argument field to flag the param as such. */
25893 default_argument = this_identifier;
25894 }
25895
25896 /* Generate a location for the parameter, ranging from the start of the
25897 initial token to the end of the final token (using input_location for
25898 the latter, set up by cp_lexer_set_source_position_from_token when
25899 consuming tokens).
25900
25901 If we have a identifier, then use it for the caret location, e.g.
25902
25903 extern int callee (int one, int (*two)(int, int), float three);
25904 ~~~~~~^~~~~~~~~~~~~~
25905
25906 otherwise, reuse the start location for the caret location e.g.:
25907
25908 extern int callee (int one, int (*)(int, int), float three);
25909 ^~~~~~~~~~~~~~~~~
25910
25911 */
25912 location_t caret_loc = (declarator && declarator->id_loc != UNKNOWN_LOCATION
25913 ? declarator->id_loc
25914 : decl_spec_token_start->location);
25915 location_t param_loc = make_location (caret: caret_loc,
25916 start: decl_spec_token_start->location,
25917 finish: input_location);
25918
25919 return make_parameter_declarator (decl_specifiers: &decl_specifiers,
25920 declarator,
25921 default_argument,
25922 loc: param_loc,
25923 template_parameter_pack_p);
25924}
25925
25926/* Parse a default argument and return it.
25927
25928 TEMPLATE_PARM_P is true if this is a default argument for a
25929 non-type template parameter. */
25930static tree
25931cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
25932{
25933 tree default_argument = NULL_TREE;
25934 bool saved_greater_than_is_operator_p;
25935 unsigned char saved_local_variables_forbidden_p;
25936
25937 /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
25938 set correctly. */
25939 saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
25940 parser->greater_than_is_operator_p = !template_parm_p;
25941 auto odsd = make_temp_override (var&: parser->omp_declare_simd, NULL);
25942 auto ord = make_temp_override (var&: parser->oacc_routine, NULL);
25943 auto oafp = make_temp_override (var&: parser->omp_attrs_forbidden_p, overrider: false);
25944
25945 /* Local variable names (and the `this' keyword) may not
25946 appear in a default argument. */
25947 saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
25948 parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
25949 /* Parse the assignment-expression. */
25950 if (template_parm_p)
25951 push_deferring_access_checks (dk_no_deferred);
25952 tree saved_class_ptr = NULL_TREE;
25953 tree saved_class_ref = NULL_TREE;
25954 /* The "this" pointer is not valid in a default argument. */
25955 if (cfun)
25956 {
25957 saved_class_ptr = current_class_ptr;
25958 cp_function_chain->x_current_class_ptr = NULL_TREE;
25959 saved_class_ref = current_class_ref;
25960 cp_function_chain->x_current_class_ref = NULL_TREE;
25961 }
25962 default_argument = cp_parser_initializer (parser);
25963 /* Restore the "this" pointer. */
25964 if (cfun)
25965 {
25966 cp_function_chain->x_current_class_ptr = saved_class_ptr;
25967 cp_function_chain->x_current_class_ref = saved_class_ref;
25968 }
25969 if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
25970 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
25971 if (template_parm_p)
25972 pop_deferring_access_checks ();
25973 parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
25974 parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
25975
25976 return default_argument;
25977}
25978
25979/* Parse a function-body.
25980
25981 function-body:
25982 compound_statement */
25983
25984static void
25985cp_parser_function_body (cp_parser *parser, bool in_function_try_block)
25986{
25987 cp_parser_compound_statement (parser, NULL, bcs_flags: (in_function_try_block
25988 ? BCS_TRY_BLOCK : BCS_NORMAL),
25989 function_body: true);
25990}
25991
25992/* Parse a ctor-initializer-opt followed by a function-body. Return
25993 true if a ctor-initializer was present. When IN_FUNCTION_TRY_BLOCK
25994 is true we are parsing a function-try-block. */
25995
25996static void
25997cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
25998 bool in_function_try_block)
25999{
26000 tree body, list;
26001 const bool check_body_p
26002 = (DECL_CONSTRUCTOR_P (current_function_decl)
26003 && DECL_DECLARED_CONSTEXPR_P (current_function_decl));
26004 tree last = NULL;
26005
26006 if (in_function_try_block
26007 && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
26008 && cxx_dialect < cxx20)
26009 {
26010 if (DECL_CONSTRUCTOR_P (current_function_decl))
26011 pedwarn (input_location, OPT_Wc__20_extensions,
26012 "function-try-block body of %<constexpr%> constructor only "
26013 "available with %<-std=c++20%> or %<-std=gnu++20%>");
26014 else
26015 pedwarn (input_location, OPT_Wc__20_extensions,
26016 "function-try-block body of %<constexpr%> function only "
26017 "available with %<-std=c++20%> or %<-std=gnu++20%>");
26018 }
26019
26020 /* Begin the function body. */
26021 body = begin_function_body ();
26022 /* Parse the optional ctor-initializer. */
26023 cp_parser_ctor_initializer_opt (parser);
26024
26025 /* If we're parsing a constexpr constructor definition, we need
26026 to check that the constructor body is indeed empty. However,
26027 before we get to cp_parser_function_body lot of junk has been
26028 generated, so we can't just check that we have an empty block.
26029 Rather we take a snapshot of the outermost block, and check whether
26030 cp_parser_function_body changed its state. */
26031 if (check_body_p)
26032 {
26033 list = cur_stmt_list;
26034 if (STATEMENT_LIST_TAIL (list))
26035 last = STATEMENT_LIST_TAIL (list)->stmt;
26036 }
26037 /* Parse the function-body. */
26038 cp_parser_function_body (parser, in_function_try_block);
26039 if (check_body_p)
26040 check_constexpr_ctor_body (last, list, /*complain=*/true);
26041 /* Finish the function body. */
26042 finish_function_body (body);
26043}
26044
26045/* Parse an initializer.
26046
26047 initializer:
26048 = initializer-clause
26049 ( expression-list )
26050
26051 Returns an expression representing the initializer. If no
26052 initializer is present, NULL_TREE is returned.
26053
26054 *IS_DIRECT_INIT is set to FALSE if the `= initializer-clause'
26055 production is used, and TRUE otherwise. *IS_DIRECT_INIT is
26056 set to TRUE if there is no initializer present. If there is an
26057 initializer, and it is not a constant-expression, *NON_CONSTANT_P
26058 is set to true; otherwise it is set to false. */
26059
26060static tree
26061cp_parser_initializer (cp_parser *parser, bool *is_direct_init /*=nullptr*/,
26062 bool *non_constant_p /*=nullptr*/, bool subexpression_p)
26063{
26064 cp_token *token;
26065 tree init;
26066
26067 /* Peek at the next token. */
26068 token = cp_lexer_peek_token (lexer: parser->lexer);
26069
26070 /* Let our caller know whether or not this initializer was
26071 parenthesized. */
26072 if (is_direct_init)
26073 *is_direct_init = (token->type != CPP_EQ);
26074 /* Assume that the initializer is constant. */
26075 if (non_constant_p)
26076 *non_constant_p = false;
26077
26078 if (token->type == CPP_EQ)
26079 {
26080 /* Consume the `='. */
26081 cp_lexer_consume_token (lexer: parser->lexer);
26082 /* Parse the initializer-clause. */
26083 init = cp_parser_initializer_clause (parser, non_constant_p);
26084 }
26085 else if (token->type == CPP_OPEN_PAREN)
26086 {
26087 vec<tree, va_gc> *vec;
26088 vec = cp_parser_parenthesized_expression_list (parser, is_attribute_list: non_attr,
26089 /*cast_p=*/false,
26090 /*allow_expansion_p=*/true,
26091 non_constant_p);
26092 if (vec == NULL)
26093 return error_mark_node;
26094 init = build_tree_list_vec (vec);
26095 release_tree_vector (vec);
26096 }
26097 else if (token->type == CPP_OPEN_BRACE)
26098 {
26099 cp_lexer_set_source_position (lexer: parser->lexer);
26100 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
26101 init = cp_parser_braced_list (parser, non_constant_p);
26102 CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
26103 }
26104 else
26105 {
26106 /* Anything else is an error. */
26107 cp_parser_error (parser, gmsgid: "expected initializer");
26108 init = error_mark_node;
26109 }
26110
26111 if (!subexpression_p && check_for_bare_parameter_packs (init))
26112 init = error_mark_node;
26113
26114 return init;
26115}
26116
26117/* Parse an initializer-clause.
26118
26119 initializer-clause:
26120 assignment-expression
26121 braced-init-list
26122
26123 Returns an expression representing the initializer.
26124
26125 If the `assignment-expression' production is used the value
26126 returned is simply a representation for the expression.
26127
26128 Otherwise, calls cp_parser_braced_list. */
26129
26130static cp_expr
26131cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
26132{
26133 cp_expr initializer;
26134
26135 /* Assume the expression is constant. */
26136 if (non_constant_p)
26137 *non_constant_p = false;
26138
26139 /* If it is not a `{', then we are looking at an
26140 assignment-expression. */
26141 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_BRACE))
26142 {
26143 initializer
26144 = cp_parser_constant_expression (parser,
26145 /*allow_non_constant_p=*/2,
26146 non_constant_p);
26147 }
26148 else
26149 initializer = cp_parser_braced_list (parser, non_constant_p);
26150
26151 return initializer;
26152}
26153
26154/* Parse a brace-enclosed initializer list.
26155
26156 braced-init-list:
26157 { initializer-list , [opt] }
26158 { designated-initializer-list , [opt] }
26159 { }
26160
26161 Returns a CONSTRUCTOR. The CONSTRUCTOR_ELTS will be
26162 the elements of the initializer-list (or NULL, if the last
26163 production is used). The TREE_TYPE for the CONSTRUCTOR will be
26164 NULL_TREE. There is no way to detect whether or not the optional
26165 trailing `,' was provided. NON_CONSTANT_P is as for
26166 cp_parser_initializer. */
26167
26168static cp_expr
26169cp_parser_braced_list (cp_parser *parser, bool *non_constant_p /*=nullptr*/)
26170{
26171 tree initializer;
26172 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
26173 auto oas = make_temp_override (var&: parser->omp_array_section_p, overrider: false);
26174
26175 /* Consume the `{' token. */
26176 matching_braces braces;
26177 braces.require_open (parser);
26178 /* Create a CONSTRUCTOR to represent the braced-initializer. */
26179 initializer = make_node (CONSTRUCTOR);
26180 /* If it's not a `}', then there is a non-trivial initializer. */
26181 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
26182 {
26183 bool designated;
26184 /* Parse the initializer list. */
26185 CONSTRUCTOR_ELTS (initializer)
26186 = cp_parser_initializer_list (parser, non_constant_p, &designated);
26187 CONSTRUCTOR_IS_DESIGNATED_INIT (initializer) = designated;
26188 /* A trailing `,' token is allowed. */
26189 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
26190 cp_lexer_consume_token (lexer: parser->lexer);
26191 }
26192 else if (non_constant_p)
26193 *non_constant_p = false;
26194 /* Now, there should be a trailing `}'. */
26195 location_t finish_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
26196 braces.require_close (parser);
26197 TREE_TYPE (initializer) = init_list_type_node;
26198 recompute_constructor_flags (initializer);
26199
26200 cp_expr result (initializer);
26201 /* Build a location of the form:
26202 { ... }
26203 ^~~~~~~
26204 with caret==start at the open brace, finish at the close brace. */
26205 location_t combined_loc = make_location (caret: start_loc, start: start_loc, finish: finish_loc);
26206 result.set_location (combined_loc);
26207 return result;
26208}
26209
26210/* Consume tokens up to, but not including, the next non-nested closing `]'.
26211 Returns true iff we found a closing `]'. */
26212
26213static bool
26214cp_parser_skip_up_to_closing_square_bracket (cp_parser *parser)
26215{
26216 unsigned square_depth = 0;
26217
26218 while (true)
26219 {
26220 cp_token * token = cp_lexer_peek_token (lexer: parser->lexer);
26221
26222 switch (token->type)
26223 {
26224 case CPP_PRAGMA_EOL:
26225 if (!parser->lexer->in_pragma)
26226 break;
26227 /* FALLTHRU */
26228
26229 case CPP_EOF:
26230 /* If we've run out of tokens, then there is no closing `]'. */
26231 return false;
26232
26233 case CPP_OPEN_SQUARE:
26234 ++square_depth;
26235 break;
26236
26237 case CPP_CLOSE_SQUARE:
26238 if (!square_depth--)
26239 return true;
26240 break;
26241
26242 default:
26243 break;
26244 }
26245
26246 /* Consume the current token, skipping it. */
26247 cp_lexer_consume_token (lexer: parser->lexer);
26248 }
26249}
26250
26251/* Consume tokens up to, and including, the next non-nested closing `]'.
26252 Returns true iff we found a closing `]'. */
26253
26254static bool
26255cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
26256{
26257 bool found = cp_parser_skip_up_to_closing_square_bracket (parser);
26258 if (found)
26259 cp_lexer_consume_token (lexer: parser->lexer);
26260 return found;
26261}
26262
26263/* Return true if we are looking at an array-designator, false otherwise. */
26264
26265static bool
26266cp_parser_array_designator_p (cp_parser *parser)
26267{
26268 /* Consume the `['. */
26269 cp_lexer_consume_token (lexer: parser->lexer);
26270
26271 cp_lexer_save_tokens (lexer: parser->lexer);
26272
26273 /* Skip tokens until the next token is a closing square bracket.
26274 If we find the closing `]', and the next token is a `=', then
26275 we are looking at an array designator. */
26276 bool array_designator_p
26277 = (cp_parser_skip_to_closing_square_bracket (parser)
26278 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ));
26279
26280 /* Roll back the tokens we skipped. */
26281 cp_lexer_rollback_tokens (lexer: parser->lexer);
26282
26283 return array_designator_p;
26284}
26285
26286/* Parse an initializer-list.
26287
26288 initializer-list:
26289 initializer-clause ... [opt]
26290 initializer-list , initializer-clause ... [opt]
26291
26292 C++20 Extension:
26293
26294 designated-initializer-list:
26295 designated-initializer-clause
26296 designated-initializer-list , designated-initializer-clause
26297
26298 designated-initializer-clause:
26299 designator brace-or-equal-initializer
26300
26301 designator:
26302 . identifier
26303
26304 GNU Extension:
26305
26306 initializer-list:
26307 designation initializer-clause ...[opt]
26308 initializer-list , designation initializer-clause ...[opt]
26309
26310 designation:
26311 . identifier =
26312 identifier :
26313 [ constant-expression ] =
26314
26315 Returns a vec of constructor_elt. The VALUE of each elt is an expression
26316 for the initializer. If the INDEX of the elt is non-NULL, it is the
26317 IDENTIFIER_NODE naming the field to initialize. NON_CONSTANT_P is
26318 as for cp_parser_initializer. Set *DESIGNATED to a boolean whether there
26319 are any designators. */
26320
26321static vec<constructor_elt, va_gc> *
26322cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
26323 bool *designated)
26324{
26325 vec<constructor_elt, va_gc> *v = NULL;
26326 bool first_p = true;
26327 tree first_designator = NULL_TREE;
26328
26329 /* Assume all of the expressions are constant. */
26330 if (non_constant_p)
26331 *non_constant_p = false;
26332
26333 unsigned nelts = 0;
26334 int suppress = suppress_location_wrappers;
26335
26336 /* Parse the rest of the list. */
26337 while (true)
26338 {
26339 cp_token *token;
26340 tree designator;
26341 tree initializer;
26342 bool clause_non_constant_p;
26343 bool direct_p = false;
26344 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
26345
26346 /* Handle the C++20 syntax, '. id ='. */
26347 if ((cxx_dialect >= cxx20
26348 || cp_parser_allow_gnu_extensions_p (parser))
26349 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DOT)
26350 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_NAME
26351 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type == CPP_EQ
26352 || (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type
26353 == CPP_OPEN_BRACE)))
26354 {
26355 if (pedantic && cxx_dialect < cxx20)
26356 pedwarn (loc, OPT_Wc__20_extensions,
26357 "C++ designated initializers only available with "
26358 "%<-std=c++20%> or %<-std=gnu++20%>");
26359 /* Consume the `.'. */
26360 cp_lexer_consume_token (lexer: parser->lexer);
26361 /* Consume the identifier. */
26362 designator = cp_lexer_consume_token (lexer: parser->lexer)->u.value;
26363 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
26364 /* Consume the `='. */
26365 cp_lexer_consume_token (lexer: parser->lexer);
26366 else
26367 direct_p = true;
26368 }
26369 /* Also, if the next token is an identifier and the following one is a
26370 colon, we are looking at the GNU designated-initializer
26371 syntax. */
26372 else if (cp_parser_allow_gnu_extensions_p (parser)
26373 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
26374 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
26375 == CPP_COLON))
26376 {
26377 /* Warn the user that they are using an extension. */
26378 pedwarn (loc, OPT_Wpedantic,
26379 "ISO C++ does not allow GNU designated initializers");
26380 /* Consume the identifier. */
26381 designator = cp_lexer_consume_token (lexer: parser->lexer)->u.value;
26382 /* Consume the `:'. */
26383 cp_lexer_consume_token (lexer: parser->lexer);
26384 }
26385 /* Also handle C99 array designators, '[ const ] ='. */
26386 else if (cp_parser_allow_gnu_extensions_p (parser)
26387 && !c_dialect_objc ()
26388 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
26389 {
26390 /* In C++11, [ could start a lambda-introducer. */
26391 bool non_const = false;
26392
26393 cp_parser_parse_tentatively (parser);
26394
26395 if (!cp_parser_array_designator_p (parser))
26396 {
26397 cp_parser_simulate_error (parser);
26398 designator = NULL_TREE;
26399 }
26400 else
26401 {
26402 designator = cp_parser_constant_expression (parser, allow_non_constant_p: true,
26403 non_constant_p: &non_const);
26404 cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
26405 cp_parser_require (parser, CPP_EQ, RT_EQ);
26406 }
26407
26408 if (!cp_parser_parse_definitely (parser))
26409 designator = NULL_TREE;
26410 else if (non_const
26411 && (!require_potential_rvalue_constant_expression
26412 (designator)))
26413 designator = NULL_TREE;
26414 if (designator)
26415 /* Warn the user that they are using an extension. */
26416 pedwarn (loc, OPT_Wpedantic,
26417 "ISO C++ does not allow C99 designated initializers");
26418 }
26419 else
26420 designator = NULL_TREE;
26421
26422 if (first_p)
26423 {
26424 first_designator = designator;
26425 first_p = false;
26426 }
26427 else if (cxx_dialect >= cxx20
26428 && first_designator != error_mark_node
26429 && (!first_designator != !designator))
26430 {
26431 error_at (loc, "either all initializer clauses should be designated "
26432 "or none of them should be");
26433 first_designator = error_mark_node;
26434 }
26435 else if (cxx_dialect < cxx20 && !first_designator)
26436 first_designator = designator;
26437
26438 /* Parse the initializer. */
26439 initializer = cp_parser_initializer_clause (parser,
26440 non_constant_p: (non_constant_p != nullptr
26441 ? &clause_non_constant_p
26442 : nullptr));
26443 /* If any clause is non-constant, so is the entire initializer. */
26444 if (non_constant_p && clause_non_constant_p)
26445 *non_constant_p = true;
26446
26447 if (TREE_CODE (initializer) == CONSTRUCTOR)
26448 /* This uses |= rather than = because C_I_D_I could have been set in
26449 cp_parser_functional_cast so we must be careful not to clear the
26450 flag. */
26451 CONSTRUCTOR_IS_DIRECT_INIT (initializer) |= direct_p;
26452
26453 /* If we have an ellipsis, this is an initializer pack
26454 expansion. */
26455 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
26456 {
26457 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
26458
26459 /* Consume the `...'. */
26460 cp_lexer_consume_token (lexer: parser->lexer);
26461
26462 if (designator && cxx_dialect >= cxx20)
26463 error_at (loc,
26464 "%<...%> not allowed in designated initializer list");
26465
26466 /* Turn the initializer into an initializer expansion. */
26467 initializer = make_pack_expansion (initializer);
26468 }
26469
26470 /* Add it to the vector. */
26471 CONSTRUCTOR_APPEND_ELT (v, designator, initializer);
26472
26473 /* If the next token is not a comma, we have reached the end of
26474 the list. */
26475 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
26476 break;
26477
26478 /* Peek at the next token. */
26479 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
26480 /* If the next token is a `}', then we're still done. An
26481 initializer-clause can have a trailing `,' after the
26482 initializer-list and before the closing `}'. */
26483 if (token->type == CPP_CLOSE_BRACE)
26484 break;
26485
26486 /* Suppress location wrappers in a long initializer to save memory
26487 (14179). The cutoff is chosen arbitrarily. */
26488 const unsigned loc_max = 256;
26489 unsigned incr = 1;
26490 if (TREE_CODE (initializer) == CONSTRUCTOR)
26491 /* Look one level down because it's easy. Looking deeper would require
26492 passing down a nelts pointer, and I don't think multi-level massive
26493 initializers are common enough to justify this. */
26494 incr = CONSTRUCTOR_NELTS (initializer);
26495 nelts += incr;
26496 if (nelts >= loc_max && (nelts - incr) < loc_max)
26497 ++suppress_location_wrappers;
26498
26499 /* Consume the `,' token. */
26500 cp_lexer_consume_token (lexer: parser->lexer);
26501 }
26502
26503 /* The same identifier shall not appear in multiple designators
26504 of a designated-initializer-list. */
26505 if (first_designator)
26506 {
26507 unsigned int i;
26508 tree designator, val;
26509 FOR_EACH_CONSTRUCTOR_ELT (v, i, designator, val)
26510 if (designator && TREE_CODE (designator) == IDENTIFIER_NODE)
26511 {
26512 if (IDENTIFIER_MARKED (designator))
26513 {
26514 error_at (cp_expr_loc_or_input_loc (t: val),
26515 "%<.%s%> designator used multiple times in "
26516 "the same initializer list",
26517 IDENTIFIER_POINTER (designator));
26518 (*v)[i].index = error_mark_node;
26519 }
26520 else
26521 IDENTIFIER_MARKED (designator) = 1;
26522 }
26523 FOR_EACH_CONSTRUCTOR_ELT (v, i, designator, val)
26524 if (designator && TREE_CODE (designator) == IDENTIFIER_NODE)
26525 IDENTIFIER_MARKED (designator) = 0;
26526 }
26527
26528 suppress_location_wrappers = suppress;
26529
26530 *designated = first_designator != NULL_TREE;
26531 return v;
26532}
26533
26534/* Classes [gram.class] */
26535
26536/* Parse a class-name.
26537
26538 class-name:
26539 identifier
26540 template-id
26541
26542 TYPENAME_KEYWORD_P is true iff the `typename' keyword has been used
26543 to indicate that names looked up in dependent types should be
26544 assumed to be types. TEMPLATE_KEYWORD_P is true iff the `template'
26545 keyword has been used to indicate that the name that appears next
26546 is a template. TAG_TYPE indicates the explicit tag given before
26547 the type name, if any. If CHECK_DEPENDENCY_P is FALSE, names are
26548 looked up in dependent scopes. If CLASS_HEAD_P is TRUE, this class
26549 is the class being defined in a class-head. If ENUM_OK is TRUE,
26550 enum-names are also accepted.
26551
26552 Returns the TYPE_DECL representing the class. */
26553
26554static tree
26555cp_parser_class_name (cp_parser *parser,
26556 bool typename_keyword_p,
26557 bool template_keyword_p,
26558 enum tag_types tag_type,
26559 bool check_dependency_p,
26560 bool class_head_p,
26561 bool is_declaration,
26562 bool enum_ok)
26563{
26564 tree decl;
26565 tree identifier = NULL_TREE;
26566
26567 /* All class-names start with an identifier. */
26568 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
26569 if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
26570 {
26571 cp_parser_error (parser, gmsgid: "expected class-name");
26572 return error_mark_node;
26573 }
26574
26575 /* PARSER->SCOPE can be cleared when parsing the template-arguments
26576 to a template-id, so we save it here. Consider object scope too,
26577 so that make_typename_type below can use it (cp_parser_template_name
26578 considers object scope also). This may happen with code like
26579
26580 p->template A<T>::a()
26581
26582 where we first want to look up A<T>::a in the class of the object
26583 expression, as per [basic.lookup.classref]. */
26584 tree scope = parser->scope ? parser->scope : parser->context->object_type;
26585 /* This only checks parser->scope to avoid duplicate errors; if
26586 ->object_type is erroneous, go on to give a parse error. */
26587 if (parser->scope == error_mark_node)
26588 return error_mark_node;
26589
26590 /* Any name names a type if we're following the `typename' keyword
26591 in a qualified name where the enclosing scope is type-dependent. */
26592 const bool typename_p = (typename_keyword_p
26593 && parser->scope
26594 && TYPE_P (parser->scope)
26595 && dependent_scope_p (parser->scope));
26596 /* Handle the common case (an identifier, but not a template-id)
26597 efficiently. */
26598 if (token->type == CPP_NAME
26599 && !cp_parser_nth_token_starts_template_argument_list_p (parser, 2))
26600 {
26601 cp_token *identifier_token;
26602 bool ambiguous_p;
26603
26604 /* Look for the identifier. */
26605 identifier_token = cp_lexer_peek_token (lexer: parser->lexer);
26606 ambiguous_p = identifier_token->error_reported;
26607 identifier = cp_parser_identifier (parser);
26608 /* If the next token isn't an identifier, we are certainly not
26609 looking at a class-name. */
26610 if (identifier == error_mark_node)
26611 decl = error_mark_node;
26612 /* If we know this is a type-name, there's no need to look it
26613 up. */
26614 else if (typename_p)
26615 decl = identifier;
26616 else
26617 {
26618 tree ambiguous_decls;
26619 /* If we already know that this lookup is ambiguous, then
26620 we've already issued an error message; there's no reason
26621 to check again. */
26622 if (ambiguous_p)
26623 {
26624 cp_parser_simulate_error (parser);
26625 return error_mark_node;
26626 }
26627 /* If the next token is a `::', then the name must be a type
26628 name.
26629
26630 [basic.lookup.qual]
26631
26632 During the lookup for a name preceding the :: scope
26633 resolution operator, object, function, and enumerator
26634 names are ignored. */
26635 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE))
26636 tag_type = scope_type;
26637 /* Look up the name. */
26638 decl = cp_parser_lookup_name (parser, identifier,
26639 tag_type,
26640 /*is_template=*/false,
26641 /*is_namespace=*/false,
26642 check_dependency_p,
26643 &ambiguous_decls,
26644 identifier_token->location);
26645 if (ambiguous_decls)
26646 {
26647 if (cp_parser_parsing_tentatively (parser))
26648 cp_parser_simulate_error (parser);
26649 return error_mark_node;
26650 }
26651 }
26652 }
26653 else
26654 {
26655 /* Try a template-id. */
26656 decl = cp_parser_template_id (parser, template_keyword_p,
26657 check_dependency_p,
26658 tag_type,
26659 is_declaration);
26660 if (decl == error_mark_node)
26661 return error_mark_node;
26662 }
26663
26664 decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
26665
26666 /* If this is a typename, create a TYPENAME_TYPE. */
26667 if (typename_p && decl != error_mark_node)
26668 {
26669 decl = make_typename_type (scope, decl, typename_type,
26670 /*complain=*/tf_error);
26671 if (decl != error_mark_node)
26672 decl = TYPE_NAME (decl);
26673 }
26674
26675 decl = strip_using_decl (decl);
26676
26677 /* Check to see that it is really the name of a class. */
26678 if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
26679 && identifier_p (TREE_OPERAND (decl, 0))
26680 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SCOPE))
26681 /* Situations like this:
26682
26683 template <typename T> struct A {
26684 typename T::template X<int>::I i;
26685 };
26686
26687 are problematic. Is `T::template X<int>' a class-name? The
26688 standard does not seem to be definitive, but there is no other
26689 valid interpretation of the following `::'. Therefore, those
26690 names are considered class-names. */
26691 {
26692 decl = make_typename_type (scope, decl, tag_type, tf_error);
26693 if (decl != error_mark_node)
26694 decl = TYPE_NAME (decl);
26695 }
26696 else if (TREE_CODE (decl) != TYPE_DECL
26697 || TREE_TYPE (decl) == error_mark_node
26698 || !(MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))
26699 || (enum_ok && TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE))
26700 /* In Objective-C 2.0, a classname followed by '.' starts a
26701 dot-syntax expression, and it's not a type-name. */
26702 || (c_dialect_objc ()
26703 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_DOT
26704 && objc_is_class_name (decl)))
26705 decl = error_mark_node;
26706
26707 if (decl == error_mark_node)
26708 cp_parser_error (parser, gmsgid: "expected class-name");
26709 else if (identifier && !parser->scope)
26710 maybe_note_name_used_in_class (identifier, decl);
26711
26712 return decl;
26713}
26714
26715/* Make sure that any member-function parameters are in scope.
26716 For instance, a function's noexcept-specifier can use the function's
26717 parameters:
26718
26719 struct S {
26720 void fn (int p) noexcept(noexcept(p));
26721 };
26722
26723 so we need to make sure name lookup can find them. This is used
26724 when we delay parsing of the noexcept-specifier. */
26725
26726static void
26727inject_parm_decls (tree decl)
26728{
26729 begin_scope (sk_function_parms, decl);
26730 tree args = DECL_ARGUMENTS (decl);
26731
26732 do_push_parm_decls (decl, args, /*nonparms=*/NULL);
26733
26734 if (args && is_this_parameter (args))
26735 {
26736 gcc_checking_assert (current_class_ptr == NULL_TREE);
26737 current_class_ref = cp_build_fold_indirect_ref (args);
26738 current_class_ptr = args;
26739 }
26740}
26741
26742/* Undo the effects of inject_parm_decls. */
26743
26744static void
26745pop_injected_parms (void)
26746{
26747 pop_bindings_and_leave_scope ();
26748 current_class_ptr = current_class_ref = NULL_TREE;
26749}
26750
26751/* Parse a class-specifier.
26752
26753 class-specifier:
26754 class-head { member-specification [opt] }
26755
26756 Returns the TREE_TYPE representing the class. */
26757
26758tree
26759cp_parser_class_specifier (cp_parser* parser)
26760{
26761 auto_timevar tv (TV_PARSE_STRUCT);
26762
26763 tree type;
26764 tree attributes = NULL_TREE;
26765 bool nested_name_specifier_p;
26766 unsigned saved_num_template_parameter_lists;
26767 bool saved_in_function_body;
26768 unsigned char in_statement;
26769 bool in_switch_statement_p;
26770 bool saved_in_unbraced_linkage_specification_p;
26771 tree old_scope = NULL_TREE;
26772 tree scope = NULL_TREE;
26773 cp_token *closing_brace;
26774
26775 push_deferring_access_checks (dk_no_deferred);
26776
26777 /* Parse the class-head. */
26778 type = cp_parser_class_head (parser,
26779 &nested_name_specifier_p);
26780 /* If the class-head was a semantic disaster, skip the entire body
26781 of the class. */
26782 if (!type)
26783 {
26784 cp_parser_skip_to_end_of_block_or_statement (parser);
26785 pop_deferring_access_checks ();
26786 return error_mark_node;
26787 }
26788
26789 /* Look for the `{'. */
26790 matching_braces braces;
26791 if (!braces.require_open (parser))
26792 {
26793 pop_deferring_access_checks ();
26794 return error_mark_node;
26795 }
26796
26797 cp_ensure_no_omp_declare_simd (parser);
26798 cp_ensure_no_oacc_routine (parser);
26799
26800 /* Issue an error message if type-definitions are forbidden here. */
26801 bool type_definition_ok_p = cp_parser_check_type_definition (parser);
26802 /* Remember that we are defining one more class. */
26803 ++parser->num_classes_being_defined;
26804 /* Inside the class, surrounding template-parameter-lists do not
26805 apply. */
26806 saved_num_template_parameter_lists
26807 = parser->num_template_parameter_lists;
26808 parser->num_template_parameter_lists = 0;
26809 /* We are not in a function body. */
26810 saved_in_function_body = parser->in_function_body;
26811 parser->in_function_body = false;
26812 /* Or in a loop. */
26813 in_statement = parser->in_statement;
26814 parser->in_statement = 0;
26815 /* Or in a switch. */
26816 in_switch_statement_p = parser->in_switch_statement_p;
26817 parser->in_switch_statement_p = false;
26818 /* We are not immediately inside an extern "lang" block. */
26819 saved_in_unbraced_linkage_specification_p
26820 = parser->in_unbraced_linkage_specification_p;
26821 parser->in_unbraced_linkage_specification_p = false;
26822 /* 'this' from an enclosing non-static member function is unavailable. */
26823 tree saved_ccp = current_class_ptr;
26824 tree saved_ccr = current_class_ref;
26825 current_class_ptr = NULL_TREE;
26826 current_class_ref = NULL_TREE;
26827
26828 /* Start the class. */
26829 if (nested_name_specifier_p)
26830 {
26831 scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
26832 /* SCOPE must be a scope nested inside current scope. */
26833 if (is_nested_namespace (current_namespace,
26834 descendant: decl_namespace_context (scope)))
26835 old_scope = push_inner_scope (scope);
26836 else
26837 nested_name_specifier_p = false;
26838 }
26839 type = begin_class_definition (type);
26840
26841 if (type == error_mark_node)
26842 /* If the type is erroneous, skip the entire body of the class. */
26843 cp_parser_skip_to_closing_brace (parser);
26844 else
26845 /* Parse the member-specification. */
26846 cp_parser_member_specification_opt (parser);
26847
26848 /* Look for the trailing `}'. */
26849 closing_brace = braces.require_close (parser);
26850 /* Look for trailing attributes to apply to this class. */
26851 if (cp_parser_allow_gnu_extensions_p (parser))
26852 attributes = cp_parser_gnu_attributes_opt (parser);
26853 if (type != error_mark_node)
26854 type = finish_struct (type, attributes);
26855 if (nested_name_specifier_p)
26856 pop_inner_scope (old_scope, scope);
26857
26858 /* We've finished a type definition. Check for the common syntax
26859 error of forgetting a semicolon after the definition. We need to
26860 be careful, as we can't just check for not-a-semicolon and be done
26861 with it; the user might have typed:
26862
26863 class X { } c = ...;
26864 class X { } *p = ...;
26865
26866 and so forth. Instead, enumerate all the possible tokens that
26867 might follow this production; if we don't see one of them, then
26868 complain and silently insert the semicolon. */
26869 {
26870 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
26871 bool want_semicolon = true;
26872
26873 if (cp_next_tokens_can_be_std_attribute_p (parser))
26874 /* Don't try to parse c++11 attributes here. As per the
26875 grammar, that should be a task for
26876 cp_parser_decl_specifier_seq. */
26877 want_semicolon = false;
26878
26879 switch (token->type)
26880 {
26881 case CPP_NAME:
26882 case CPP_SEMICOLON:
26883 case CPP_MULT:
26884 case CPP_AND:
26885 case CPP_OPEN_PAREN:
26886 case CPP_CLOSE_PAREN:
26887 case CPP_COMMA:
26888 case CPP_SCOPE:
26889 want_semicolon = false;
26890 break;
26891
26892 /* While it's legal for type qualifiers and storage class
26893 specifiers to follow type definitions in the grammar, only
26894 compiler testsuites contain code like that. Assume that if
26895 we see such code, then what we're really seeing is a case
26896 like:
26897
26898 class X { }
26899 const <type> var = ...;
26900
26901 or
26902
26903 class Y { }
26904 static <type> func (...) ...
26905
26906 i.e. the qualifier or specifier applies to the next
26907 declaration. To do so, however, we need to look ahead one
26908 more token to see if *that* token is a type specifier.
26909
26910 This code could be improved to handle:
26911
26912 class Z { }
26913 static const <type> var = ...; */
26914 case CPP_KEYWORD:
26915 if (keyword_is_decl_specifier (token->keyword))
26916 {
26917 cp_token *lookahead = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
26918
26919 /* Handling user-defined types here would be nice, but very
26920 tricky. */
26921 want_semicolon
26922 = (lookahead->type == CPP_KEYWORD
26923 && keyword_begins_type_specifier (lookahead->keyword));
26924 }
26925 break;
26926 default:
26927 break;
26928 }
26929
26930 /* If we don't have a type, then something is very wrong and we
26931 shouldn't try to do anything clever. Likewise for not seeing the
26932 closing brace. */
26933 if (closing_brace && TYPE_P (type) && want_semicolon)
26934 {
26935 /* Locate the closing brace. */
26936 cp_token_position prev
26937 = cp_lexer_previous_token_position (lexer: parser->lexer);
26938 cp_token *prev_token = cp_lexer_token_at (parser->lexer, pos: prev);
26939 location_t loc = prev_token->location;
26940
26941 /* We want to suggest insertion of a ';' immediately *after* the
26942 closing brace, so, if we can, offset the location by 1 column. */
26943 location_t next_loc = loc;
26944 if (!linemap_location_from_macro_expansion_p (line_table, loc))
26945 next_loc = linemap_position_for_loc_and_offset (set: line_table, loc, offset: 1);
26946
26947 rich_location richloc (line_table, next_loc);
26948
26949 /* If we successfully offset the location, suggest the fix-it. */
26950 if (next_loc != loc)
26951 richloc.add_fixit_insert_before (where: next_loc, new_content: ";");
26952
26953 if (CLASSTYPE_DECLARED_CLASS (type))
26954 error_at (&richloc,
26955 "expected %<;%> after class definition");
26956 else if (TREE_CODE (type) == RECORD_TYPE)
26957 error_at (&richloc,
26958 "expected %<;%> after struct definition");
26959 else if (TREE_CODE (type) == UNION_TYPE)
26960 error_at (&richloc,
26961 "expected %<;%> after union definition");
26962 else
26963 gcc_unreachable ();
26964
26965 /* Unget one token and smash it to look as though we encountered
26966 a semicolon in the input stream. */
26967 cp_lexer_set_token_position (lexer: parser->lexer, pos: prev);
26968 token = cp_lexer_peek_token (lexer: parser->lexer);
26969 token->type = CPP_SEMICOLON;
26970 token->keyword = RID_MAX;
26971 }
26972 }
26973
26974 /* If this class is not itself within the scope of another class,
26975 then we need to parse the bodies of all of the queued function
26976 definitions. Note that the queued functions defined in a class
26977 are not always processed immediately following the
26978 class-specifier for that class. Consider:
26979
26980 struct A {
26981 struct B { void f() { sizeof (A); } };
26982 };
26983
26984 If `f' were processed before the processing of `A' were
26985 completed, there would be no way to compute the size of `A'.
26986 Note that the nesting we are interested in here is lexical --
26987 not the semantic nesting given by TYPE_CONTEXT. In particular,
26988 for:
26989
26990 struct A { struct B; };
26991 struct A::B { void f() { } };
26992
26993 there is no need to delay the parsing of `A::B::f'. */
26994 if (--parser->num_classes_being_defined == 0)
26995 {
26996 tree decl;
26997 tree class_type = NULL_TREE;
26998 tree pushed_scope = NULL_TREE;
26999 unsigned ix;
27000 cp_default_arg_entry *e;
27001
27002 if (!type_definition_ok_p || any_erroneous_template_args_p (type))
27003 {
27004 /* Skip default arguments, NSDMIs, etc, in order to improve
27005 error recovery (c++/71169, c++/71832). */
27006 vec_safe_truncate (unparsed_funs_with_default_args, size: 0);
27007 vec_safe_truncate (unparsed_nsdmis, size: 0);
27008 vec_safe_truncate (unparsed_funs_with_definitions, size: 0);
27009 }
27010
27011 /* In a first pass, parse default arguments to the functions.
27012 Then, in a second pass, parse the bodies of the functions.
27013 This two-phased approach handles cases like:
27014
27015 struct S {
27016 void f() { g(); }
27017 void g(int i = 3);
27018 };
27019
27020 */
27021 FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_default_args, ix, e)
27022 {
27023 decl = e->decl;
27024 /* If there are default arguments that have not yet been processed,
27025 take care of them now. */
27026 if (class_type != e->class_type)
27027 {
27028 if (pushed_scope)
27029 pop_scope (pushed_scope);
27030 class_type = e->class_type;
27031 pushed_scope = push_scope (class_type);
27032 }
27033 /* Make sure that any template parameters are in scope. */
27034 maybe_begin_member_template_processing (decl);
27035 /* Parse the default argument expressions. */
27036 cp_parser_late_parsing_default_args (parser, decl);
27037 /* Remove any template parameters from the symbol table. */
27038 maybe_end_member_template_processing ();
27039 }
27040 vec_safe_truncate (unparsed_funs_with_default_args, size: 0);
27041
27042 /* If there are noexcept-specifiers that have not yet been processed,
27043 take care of them now. Do this before processing NSDMIs as they
27044 may depend on noexcept-specifiers already having been processed. */
27045 FOR_EACH_VEC_SAFE_ELT (unparsed_noexcepts, ix, decl)
27046 {
27047 tree ctx = DECL_CONTEXT (decl);
27048 if (class_type != ctx)
27049 {
27050 if (pushed_scope)
27051 pop_scope (pushed_scope);
27052 class_type = ctx;
27053 pushed_scope = push_scope (class_type);
27054 }
27055
27056 tree def_parse = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
27057 def_parse = TREE_PURPOSE (def_parse);
27058
27059 /* Make sure that any template parameters are in scope. */
27060 maybe_begin_member_template_processing (decl);
27061
27062 /* Make sure that any member-function parameters are in scope.
27063 This function doesn't expect ccp to be set. */
27064 current_class_ptr = current_class_ref = NULL_TREE;
27065 inject_parm_decls (decl);
27066
27067 /* 'this' is not allowed in static member functions. */
27068 unsigned char local_variables_forbidden_p
27069 = parser->local_variables_forbidden_p;
27070 if (DECL_THIS_STATIC (decl))
27071 parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
27072
27073 /* Now we can parse the noexcept-specifier. */
27074 tree spec = cp_parser_late_noexcept_specifier (parser, def_parse);
27075
27076 if (spec == error_mark_node)
27077 spec = NULL_TREE;
27078
27079 /* Update the fn's type directly -- it might have escaped
27080 beyond this decl :( */
27081 fixup_deferred_exception_variants (TREE_TYPE (decl), spec);
27082 /* Update any instantiations we've already created. We must
27083 keep the new noexcept-specifier wrapped in a DEFERRED_NOEXCEPT
27084 so that maybe_instantiate_noexcept can tsubst the NOEXCEPT_EXPR
27085 in the pattern. */
27086 for (tree i : DEFPARSE_INSTANTIATIONS (def_parse))
27087 DEFERRED_NOEXCEPT_PATTERN (TREE_PURPOSE (i))
27088 = spec ? TREE_PURPOSE (spec) : error_mark_node;
27089
27090 /* Restore the state of local_variables_forbidden_p. */
27091 parser->local_variables_forbidden_p = local_variables_forbidden_p;
27092
27093 /* The finish_struct call above performed various override checking,
27094 but it skipped unparsed noexcept-specifier operands. Now that we
27095 have resolved them, check again. */
27096 noexcept_override_late_checks (decl);
27097
27098 /* Remove any member-function parameters from the symbol table. */
27099 pop_injected_parms ();
27100
27101 /* Remove any template parameters from the symbol table. */
27102 maybe_end_member_template_processing ();
27103 }
27104 vec_safe_truncate (unparsed_noexcepts, size: 0);
27105
27106 /* Now parse any NSDMIs. */
27107 FOR_EACH_VEC_SAFE_ELT (unparsed_nsdmis, ix, decl)
27108 {
27109 tree ctx = type_context_for_name_lookup (decl);
27110 if (class_type != ctx)
27111 {
27112 if (pushed_scope)
27113 pop_scope (pushed_scope);
27114 class_type = ctx;
27115 pushed_scope = push_scope (class_type);
27116 }
27117 inject_this_parameter (ctype: class_type, quals: TYPE_UNQUALIFIED);
27118 cp_parser_late_parsing_nsdmi (parser, decl);
27119 }
27120 vec_safe_truncate (unparsed_nsdmis, size: 0);
27121
27122 /* Now contract attributes. */
27123 FOR_EACH_VEC_SAFE_ELT (unparsed_contracts, ix, decl)
27124 {
27125 tree ctx = DECL_CONTEXT (decl);
27126 if (class_type != ctx)
27127 {
27128 if (pushed_scope)
27129 pop_scope (pushed_scope);
27130 class_type = ctx;
27131 pushed_scope = push_scope (class_type);
27132 }
27133
27134 temp_override<tree> cfd(current_function_decl, decl);
27135
27136 /* Make sure that any template parameters are in scope. */
27137 maybe_begin_member_template_processing (decl);
27138
27139 /* Make sure that any member-function parameters are in scope.
27140 This function doesn't expect ccp to be set. */
27141 current_class_ptr = current_class_ref = NULL_TREE;
27142 inject_parm_decls (decl);
27143
27144 /* 'this' is not allowed in static member functions. */
27145 unsigned char local_variables_forbidden_p
27146 = parser->local_variables_forbidden_p;
27147 if (DECL_THIS_STATIC (decl))
27148 parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
27149
27150 /* Now we can parse contract conditions. */
27151 for (tree a = DECL_ATTRIBUTES (decl); a; a = TREE_CHAIN (a))
27152 {
27153 if (cxx_contract_attribute_p (a))
27154 cp_parser_late_contract_condition (parser, decl, a);
27155 }
27156
27157 /* Restore the state of local_variables_forbidden_p. */
27158 parser->local_variables_forbidden_p = local_variables_forbidden_p;
27159
27160 /* Remove any member-function parameters from the symbol table. */
27161 pop_injected_parms ();
27162
27163 /* Remove any template parameters from the symbol table. */
27164 maybe_end_member_template_processing ();
27165
27166 /* Perform any deferred contract matching. */
27167 match_deferred_contracts (decl);
27168 }
27169 vec_safe_truncate (unparsed_contracts, size: 0);
27170
27171 current_class_ptr = NULL_TREE;
27172 current_class_ref = NULL_TREE;
27173 if (pushed_scope)
27174 pop_scope (pushed_scope);
27175
27176 /* Now parse the body of the functions. */
27177 if (flag_openmp)
27178 {
27179 /* OpenMP UDRs need to be parsed before all other functions. */
27180 FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
27181 if (DECL_OMP_DECLARE_REDUCTION_P (decl))
27182 cp_parser_late_parsing_for_member (parser, decl);
27183 FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
27184 if (!DECL_OMP_DECLARE_REDUCTION_P (decl))
27185 cp_parser_late_parsing_for_member (parser, decl);
27186 }
27187 else
27188 FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
27189 cp_parser_late_parsing_for_member (parser, decl);
27190 vec_safe_truncate (unparsed_funs_with_definitions, size: 0);
27191 }
27192
27193 /* Put back any saved access checks. */
27194 pop_deferring_access_checks ();
27195
27196 /* Restore saved state. */
27197 parser->in_switch_statement_p = in_switch_statement_p;
27198 parser->in_statement = in_statement;
27199 parser->in_function_body = saved_in_function_body;
27200 parser->num_template_parameter_lists
27201 = saved_num_template_parameter_lists;
27202 parser->in_unbraced_linkage_specification_p
27203 = saved_in_unbraced_linkage_specification_p;
27204 current_class_ptr = saved_ccp;
27205 current_class_ref = saved_ccr;
27206
27207 return type;
27208}
27209
27210/* Parse a class-head.
27211
27212 class-head:
27213 class-key identifier [opt] base-clause [opt]
27214 class-key nested-name-specifier identifier class-virt-specifier [opt] base-clause [opt]
27215 class-key nested-name-specifier [opt] template-id
27216 base-clause [opt]
27217
27218 class-virt-specifier:
27219 final
27220
27221 GNU Extensions:
27222 class-key attributes identifier [opt] base-clause [opt]
27223 class-key attributes nested-name-specifier identifier base-clause [opt]
27224 class-key attributes nested-name-specifier [opt] template-id
27225 base-clause [opt]
27226
27227 Upon return BASES is initialized to the list of base classes (or
27228 NULL, if there are none) in the same form returned by
27229 cp_parser_base_clause.
27230
27231 Returns the TYPE of the indicated class. Sets
27232 *NESTED_NAME_SPECIFIER_P to TRUE iff one of the productions
27233 involving a nested-name-specifier was used, and FALSE otherwise.
27234
27235 Returns error_mark_node if this is not a class-head.
27236
27237 Returns NULL_TREE if the class-head is syntactically valid, but
27238 semantically invalid in a way that means we should skip the entire
27239 body of the class. */
27240
27241static tree
27242cp_parser_class_head (cp_parser* parser,
27243 bool* nested_name_specifier_p)
27244{
27245 tree nested_name_specifier;
27246 enum tag_types class_key;
27247 tree id = NULL_TREE;
27248 tree type = NULL_TREE;
27249 tree attributes;
27250 tree bases;
27251 cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
27252 bool template_id_p = false;
27253 bool qualified_p = false;
27254 bool invalid_nested_name_p = false;
27255 bool invalid_explicit_specialization_p = false;
27256 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
27257 tree pushed_scope = NULL_TREE;
27258 unsigned num_templates;
27259 cp_token *type_start_token = NULL, *nested_name_specifier_token_start = NULL;
27260 /* Assume no nested-name-specifier will be present. */
27261 *nested_name_specifier_p = false;
27262 /* Assume no template parameter lists will be used in defining the
27263 type. */
27264 num_templates = 0;
27265 parser->colon_corrects_to_scope_p = false;
27266
27267 /* Look for the class-key. */
27268 class_key = cp_parser_class_key (parser);
27269 if (class_key == none_type)
27270 return error_mark_node;
27271
27272 location_t class_head_start_location = input_location;
27273
27274 /* Parse the attributes. */
27275 attributes = cp_parser_attributes_opt (parser);
27276 if (find_contract (attrs: attributes))
27277 diagnose_misapplied_contracts (attributes);
27278
27279 /* If the next token is `::', that is invalid -- but sometimes
27280 people do try to write:
27281
27282 struct ::S {};
27283
27284 Handle this gracefully by accepting the extra qualifier, and then
27285 issuing an error about it later if this really is a
27286 class-head. If it turns out just to be an elaborated type
27287 specifier, remain silent. */
27288 if (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false))
27289 qualified_p = true;
27290
27291 /* It is OK to define an inaccessible class; for example:
27292
27293 class A { class B; };
27294 class A::B {};
27295
27296 So we want to ignore access when parsing the class name.
27297 However, we might be tentatively parsing what is really an
27298 elaborated-type-specifier naming a template-id, e.g.
27299
27300 struct C<&D::m> c;
27301
27302 In this case the tentative parse as a class-head will fail, but not
27303 before cp_parser_template_id splices in a CPP_TEMPLATE_ID token.
27304 Since dk_no_check is sticky, we must instead use dk_deferred so that
27305 any such CPP_TEMPLATE_ID token created during this tentative parse
27306 will correctly capture the access checks imposed by the template-id . */
27307 push_deferring_access_checks (dk_deferred);
27308
27309 /* Determine the name of the class. Begin by looking for an
27310 optional nested-name-specifier. */
27311 nested_name_specifier_token_start = cp_lexer_peek_token (lexer: parser->lexer);
27312 nested_name_specifier
27313 = cp_parser_nested_name_specifier_opt (parser,
27314 /*typename_keyword_p=*/false,
27315 /*check_dependency_p=*/false,
27316 /*type_p=*/true,
27317 /*is_declaration=*/false);
27318 /* If there was a nested-name-specifier, then there *must* be an
27319 identifier. */
27320
27321 cp_token *bad_template_keyword = NULL;
27322
27323 if (nested_name_specifier)
27324 {
27325 type_start_token = cp_lexer_peek_token (lexer: parser->lexer);
27326 /* Although the grammar says `identifier', it really means
27327 `class-name' or `template-name'. You are only allowed to
27328 define a class that has already been declared with this
27329 syntax.
27330
27331 The proposed resolution for Core Issue 180 says that wherever
27332 you see `class T::X' you should treat `X' as a type-name.
27333
27334 We do not know if we will see a class-name, or a
27335 template-name. We look for a class-name first, in case the
27336 class-name is a template-id; if we looked for the
27337 template-name first we would stop after the template-name. */
27338 cp_parser_parse_tentatively (parser);
27339 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TEMPLATE))
27340 bad_template_keyword = cp_lexer_consume_token (lexer: parser->lexer);
27341 type = cp_parser_class_name (parser,
27342 /*typename_keyword_p=*/false,
27343 /*template_keyword_p=*/false,
27344 tag_type: class_type,
27345 /*check_dependency_p=*/false,
27346 /*class_head_p=*/true,
27347 /*is_declaration=*/false);
27348 /* If that didn't work, ignore the nested-name-specifier. */
27349 if (!cp_parser_parse_definitely (parser))
27350 {
27351 invalid_nested_name_p = true;
27352 type_start_token = cp_lexer_peek_token (lexer: parser->lexer);
27353 id = cp_parser_identifier (parser);
27354 if (id == error_mark_node)
27355 id = NULL_TREE;
27356 }
27357 /* If we could not find a corresponding TYPE, treat this
27358 declaration like an unqualified declaration. */
27359 if (type == error_mark_node)
27360 nested_name_specifier = NULL_TREE;
27361 /* Otherwise, count the number of templates used in TYPE and its
27362 containing scopes. */
27363 else
27364 num_templates = num_template_headers_for_class (TREE_TYPE (type));
27365 }
27366 /* Otherwise, the identifier is optional. */
27367 else
27368 {
27369 /* We don't know whether what comes next is a template-id,
27370 an identifier, or nothing at all. */
27371 cp_parser_parse_tentatively (parser);
27372 /* Check for a template-id. */
27373 type_start_token = cp_lexer_peek_token (lexer: parser->lexer);
27374 id = cp_parser_template_id (parser,
27375 /*template_keyword_p=*/false,
27376 /*check_dependency_p=*/true,
27377 tag_type: class_key,
27378 /*is_declaration=*/true);
27379 /* If that didn't work, it could still be an identifier. */
27380 if (!cp_parser_parse_definitely (parser))
27381 {
27382 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
27383 {
27384 type_start_token = cp_lexer_peek_token (lexer: parser->lexer);
27385 id = cp_parser_identifier (parser);
27386 }
27387 else
27388 id = NULL_TREE;
27389 }
27390 else
27391 {
27392 template_id_p = true;
27393 ++num_templates;
27394 }
27395 }
27396
27397 pop_deferring_access_checks ();
27398
27399 if (id)
27400 {
27401 cp_parser_check_for_invalid_template_id (parser, type: id,
27402 tag_type: class_key,
27403 location: type_start_token->location);
27404 }
27405 virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
27406
27407 /* If it's not a `:' or a `{' then we can't really be looking at a
27408 class-head, since a class-head only appears as part of a
27409 class-specifier. We have to detect this situation before calling
27410 xref_tag, since that has irreversible side-effects. */
27411 if (!cp_parser_next_token_starts_class_definition_p (parser))
27412 {
27413 cp_parser_error (parser, gmsgid: "expected %<{%> or %<:%>");
27414 type = error_mark_node;
27415 goto out;
27416 }
27417
27418 /* At this point, we're going ahead with the class-specifier, even
27419 if some other problem occurs. */
27420 cp_parser_commit_to_tentative_parse (parser);
27421 if (virt_specifiers & VIRT_SPEC_OVERRIDE)
27422 {
27423 cp_parser_error (parser,
27424 gmsgid: "cannot specify %<override%> for a class");
27425 type = error_mark_node;
27426 goto out;
27427 }
27428 /* Issue the error about the overly-qualified name now. */
27429 if (qualified_p)
27430 {
27431 cp_parser_error (parser,
27432 gmsgid: "global qualification of class name is invalid");
27433 type = error_mark_node;
27434 goto out;
27435 }
27436 else if (invalid_nested_name_p)
27437 {
27438 cp_parser_error (parser,
27439 gmsgid: "qualified name does not name a class");
27440 type = error_mark_node;
27441 goto out;
27442 }
27443 else if (nested_name_specifier)
27444 {
27445 tree scope;
27446
27447 if (bad_template_keyword)
27448 /* [temp.names]: in a qualified-id formed by a class-head-name, the
27449 keyword template shall not appear at the top level. */
27450 pedwarn (bad_template_keyword->location, OPT_Wpedantic,
27451 "keyword %<template%> not allowed in class-head-name");
27452
27453 /* Reject typedef-names in class heads. */
27454 if (!DECL_IMPLICIT_TYPEDEF_P (type))
27455 {
27456 error_at (type_start_token->location,
27457 "invalid class name in declaration of %qD",
27458 type);
27459 type = NULL_TREE;
27460 goto done;
27461 }
27462
27463 /* Figure out in what scope the declaration is being placed. */
27464 scope = current_scope ();
27465 /* If that scope does not contain the scope in which the
27466 class was originally declared, the program is invalid. */
27467 if (scope && !is_ancestor (ancestor: scope, descendant: nested_name_specifier))
27468 {
27469 if (at_namespace_scope_p ())
27470 error_at (type_start_token->location,
27471 "declaration of %qD in namespace %qD which does not "
27472 "enclose %qD",
27473 type, scope, nested_name_specifier);
27474 else
27475 error_at (type_start_token->location,
27476 "declaration of %qD in %qD which does not enclose %qD",
27477 type, scope, nested_name_specifier);
27478 type = NULL_TREE;
27479 goto done;
27480 }
27481 /* [dcl.meaning]
27482
27483 A declarator-id shall not be qualified except for the
27484 definition of a ... nested class outside of its class
27485 ... [or] the definition or explicit instantiation of a
27486 class member of a namespace outside of its namespace. */
27487 if (scope == nested_name_specifier)
27488 permerror (nested_name_specifier_token_start->location,
27489 "extra qualification not allowed");
27490 }
27491 /* An explicit-specialization must be preceded by "template <>". If
27492 it is not, try to recover gracefully. */
27493 if (at_namespace_scope_p ()
27494 && parser->num_template_parameter_lists == 0
27495 && !processing_template_parmlist
27496 && template_id_p)
27497 {
27498 /* Build a location of this form:
27499 struct typename <ARGS>
27500 ^~~~~~~~~~~~~~~~~~~~~~
27501 with caret==start at the start token, and
27502 finishing at the end of the type. */
27503 location_t reported_loc
27504 = make_location (caret: class_head_start_location,
27505 start: class_head_start_location,
27506 finish: get_finish (loc: type_start_token->location));
27507 rich_location richloc (line_table, reported_loc);
27508 richloc.add_fixit_insert_before (where: class_head_start_location,
27509 new_content: "template <> ");
27510 error_at (&richloc,
27511 "an explicit specialization must be preceded by"
27512 " %<template <>%>");
27513 invalid_explicit_specialization_p = true;
27514 /* Take the same action that would have been taken by
27515 cp_parser_explicit_specialization. */
27516 ++parser->num_template_parameter_lists;
27517 begin_specialization ();
27518 }
27519 /* There must be no "return" statements between this point and the
27520 end of this function; set "type "to the correct return value and
27521 use "goto done;" to return. */
27522 /* Make sure that the right number of template parameters were
27523 present. */
27524 if (!cp_parser_check_template_parameters (parser, num_templates,
27525 template_id_p,
27526 type_start_token->location,
27527 /*declarator=*/NULL))
27528 {
27529 /* If something went wrong, there is no point in even trying to
27530 process the class-definition. */
27531 type = NULL_TREE;
27532 goto done;
27533 }
27534
27535 /* Look up the type. */
27536 if (template_id_p)
27537 {
27538 if (TREE_CODE (id) == TEMPLATE_ID_EXPR
27539 && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
27540 || TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
27541 {
27542 error_at (type_start_token->location,
27543 "function template %qD redeclared as a class template", id);
27544 type = error_mark_node;
27545 }
27546 else
27547 {
27548 type = TREE_TYPE (id);
27549 type = maybe_process_partial_specialization (type);
27550
27551 /* Check the scope while we still know whether or not we had a
27552 nested-name-specifier. */
27553 if (type != error_mark_node)
27554 check_unqualified_spec_or_inst (type, type_start_token->location);
27555 }
27556 if (nested_name_specifier)
27557 pushed_scope = push_scope (nested_name_specifier);
27558 }
27559 else if (nested_name_specifier)
27560 {
27561 type = TREE_TYPE (type);
27562
27563 /* Given:
27564
27565 template <typename T> struct S { struct T };
27566 template <typename T> struct S<T>::T { };
27567
27568 we will get a TYPENAME_TYPE when processing the definition of
27569 `S::T'. We need to resolve it to the actual type before we
27570 try to define it. */
27571 if (TREE_CODE (type) == TYPENAME_TYPE)
27572 {
27573 type = resolve_typename_type (type, /*only_current_p=*/false);
27574 if (TREE_CODE (type) == TYPENAME_TYPE)
27575 {
27576 cp_parser_error (parser, gmsgid: "could not resolve typename type");
27577 type = error_mark_node;
27578 }
27579 }
27580
27581 type = maybe_process_partial_specialization (type);
27582 if (type == error_mark_node)
27583 {
27584 type = NULL_TREE;
27585 goto done;
27586 }
27587
27588 /* Enter the scope indicated by the nested-name-specifier. */
27589 pushed_scope = push_scope (nested_name_specifier);
27590 /* Get the canonical version of this type. */
27591 type = TYPE_MAIN_DECL (type);
27592 /* Call push_template_decl if it seems like we should be defining a
27593 template either from the template headers or the type we're
27594 defining, so that we diagnose both extra and missing headers. */
27595 if ((PROCESSING_REAL_TEMPLATE_DECL_P ()
27596 || CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type)))
27597 && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
27598 {
27599 type = push_template_decl (type);
27600 if (type == error_mark_node)
27601 {
27602 type = NULL_TREE;
27603 goto done;
27604 }
27605 }
27606
27607 type = TREE_TYPE (type);
27608 *nested_name_specifier_p = true;
27609 }
27610 else /* The name is not a nested name. */
27611 {
27612 /* If the class was unnamed, create a dummy name. */
27613 if (!id)
27614 id = make_anon_name ();
27615 TAG_how how = (parser->in_type_id_in_expr_p
27616 ? TAG_how::INNERMOST_NON_CLASS
27617 : TAG_how::CURRENT_ONLY);
27618 type = xref_tag (class_key, id, how,
27619 tpl_header_p: parser->num_template_parameter_lists);
27620 }
27621
27622 /* Diagnose class/struct/union mismatches. */
27623 cp_parser_check_class_key (parser, UNKNOWN_LOCATION, class_key, type,
27624 true, true);
27625
27626 /* Indicate whether this class was declared as a `class' or as a
27627 `struct'. */
27628 if (TREE_CODE (type) == RECORD_TYPE)
27629 CLASSTYPE_DECLARED_CLASS (type) = class_key == class_type;
27630
27631 /* If this type was already complete, and we see another definition,
27632 that's an error. Likewise if the type is already being defined:
27633 this can happen, eg, when it's defined from within an expression
27634 (c++/84605). */
27635 if (type != error_mark_node
27636 && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type)))
27637 {
27638 error_at (type_start_token->location, "redefinition of %q#T",
27639 type);
27640 inform (location_of (type), "previous definition of %q#T",
27641 type);
27642 type = NULL_TREE;
27643 goto done;
27644 }
27645 else if (type == error_mark_node)
27646 type = NULL_TREE;
27647
27648 if (type)
27649 {
27650 if (current_lambda_expr ()
27651 && uses_parameter_packs (attributes))
27652 {
27653 /* In a lambda this should work, but doesn't currently. */
27654 sorry ("unexpanded parameter pack in local class in lambda");
27655 attributes = NULL_TREE;
27656 }
27657
27658 /* Apply attributes now, before any use of the class as a template
27659 argument in its base list. */
27660 cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
27661 fixup_attribute_variants (type);
27662 }
27663
27664 /* Associate constraints with the type. */
27665 if (flag_concepts)
27666 type = associate_classtype_constraints (type);
27667
27668 /* We will have entered the scope containing the class; the names of
27669 base classes should be looked up in that context. For example:
27670
27671 struct A { struct B {}; struct C; };
27672 struct A::C : B {};
27673
27674 is valid. */
27675
27676 /* Get the list of base-classes, if there is one. Defer access checking
27677 until the entire list has been seen, as per [class.access.general]. */
27678 push_deferring_access_checks (dk_deferred);
27679 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
27680 {
27681 if (type)
27682 {
27683 pushclass (type);
27684 start_lambda_scope (TYPE_NAME (type));
27685 }
27686 bases = cp_parser_base_clause (parser);
27687 if (type)
27688 {
27689 finish_lambda_scope ();
27690 popclass ();
27691 }
27692 }
27693 else
27694 bases = NULL_TREE;
27695
27696 /* If we're really defining a class, process the base classes.
27697 If they're invalid, fail. */
27698 if (type && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
27699 xref_basetypes (type, bases);
27700
27701 /* Now that all bases have been seen and attached to the class, check
27702 accessibility of the types named in the base-clause. This must be
27703 done relative to the class scope, so that we accept e.g.
27704
27705 struct A { protected: struct B {}; };
27706 struct C : A::B, A {}; // OK: A::B is accessible via base A
27707
27708 as per [class.access.general]. */
27709 if (type)
27710 pushclass (type);
27711 pop_to_parent_deferring_access_checks ();
27712 if (type)
27713 popclass ();
27714
27715 done:
27716 /* Leave the scope given by the nested-name-specifier. We will
27717 enter the class scope itself while processing the members. */
27718 if (pushed_scope)
27719 pop_scope (pushed_scope);
27720
27721 if (invalid_explicit_specialization_p)
27722 {
27723 end_specialization ();
27724 --parser->num_template_parameter_lists;
27725 }
27726
27727 if (type)
27728 DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
27729 if (type && (virt_specifiers & VIRT_SPEC_FINAL))
27730 CLASSTYPE_FINAL (type) = 1;
27731 out:
27732 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
27733 return type;
27734}
27735
27736/* Parse a class-key.
27737
27738 class-key:
27739 class
27740 struct
27741 union
27742
27743 Returns the kind of class-key specified, or none_type to indicate
27744 error. */
27745
27746static enum tag_types
27747cp_parser_class_key (cp_parser* parser)
27748{
27749 cp_token *token;
27750 enum tag_types tag_type;
27751
27752 /* Look for the class-key. */
27753 token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_KEY);
27754 if (!token)
27755 return none_type;
27756
27757 /* Check to see if the TOKEN is a class-key. */
27758 tag_type = cp_parser_token_is_class_key (token);
27759 if (!tag_type)
27760 cp_parser_error (parser, gmsgid: "expected class-key");
27761 return tag_type;
27762}
27763
27764/* Parse a type-parameter-key.
27765
27766 type-parameter-key:
27767 class
27768 typename
27769 */
27770
27771static void
27772cp_parser_type_parameter_key (cp_parser* parser)
27773{
27774 /* Look for the type-parameter-key. */
27775 enum tag_types tag_type = none_type;
27776 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
27777 if ((tag_type = cp_parser_token_is_type_parameter_key (token)) != none_type)
27778 {
27779 cp_lexer_consume_token (lexer: parser->lexer);
27780 if (pedantic && tag_type == typename_type
27781 && cxx_dialect < cxx17)
27782 /* typename is not allowed in a template template parameter
27783 by the standard until C++17. */
27784 pedwarn (token->location, OPT_Wc__17_extensions,
27785 "ISO C++ forbids typename key in template template parameter;"
27786 " use %<-std=c++17%> or %<-std=gnu++17%>");
27787 }
27788 else
27789 cp_parser_error (parser, gmsgid: "expected %<class%> or %<typename%>");
27790
27791 return;
27792}
27793
27794/* Parse an (optional) member-specification.
27795
27796 member-specification:
27797 member-declaration member-specification [opt]
27798 access-specifier : member-specification [opt] */
27799
27800static void
27801cp_parser_member_specification_opt (cp_parser* parser)
27802{
27803 while (true)
27804 {
27805 cp_token *token;
27806 enum rid keyword;
27807
27808 /* Peek at the next token. */
27809 token = cp_lexer_peek_token (lexer: parser->lexer);
27810 /* If it's a `}', or EOF then we've seen all the members. */
27811 if (token->type == CPP_CLOSE_BRACE
27812 || token->type == CPP_EOF
27813 || token->type == CPP_PRAGMA_EOL)
27814 break;
27815
27816 /* See if this token is a keyword. */
27817 keyword = token->keyword;
27818 switch (keyword)
27819 {
27820 case RID_PUBLIC:
27821 case RID_PROTECTED:
27822 case RID_PRIVATE:
27823 /* Consume the access-specifier. */
27824 cp_lexer_consume_token (lexer: parser->lexer);
27825 /* Remember which access-specifier is active. */
27826 current_access_specifier = token->u.value;
27827 /* Look for the `:'. */
27828 cp_parser_require (parser, CPP_COLON, RT_COLON);
27829 break;
27830
27831 default:
27832 /* Accept #pragmas at class scope. */
27833 if (token->type == CPP_PRAGMA)
27834 {
27835 cp_parser_pragma (parser, pragma_member, NULL);
27836 break;
27837 }
27838
27839 /* Otherwise, the next construction must be a
27840 member-declaration. */
27841 cp_parser_member_declaration (parser);
27842 }
27843 }
27844}
27845
27846/* Parse a member-declaration.
27847
27848 member-declaration:
27849 decl-specifier-seq [opt] member-declarator-list [opt] ;
27850 function-definition ; [opt]
27851 :: [opt] nested-name-specifier template [opt] unqualified-id ;
27852 using-declaration
27853 template-declaration
27854 alias-declaration
27855
27856 member-declarator-list:
27857 member-declarator
27858 member-declarator-list , member-declarator
27859
27860 member-declarator:
27861 declarator pure-specifier [opt]
27862 declarator constant-initializer [opt]
27863 identifier [opt] : constant-expression
27864
27865 GNU Extensions:
27866
27867 member-declaration:
27868 __extension__ member-declaration
27869
27870 member-declarator:
27871 declarator attributes [opt] pure-specifier [opt]
27872 declarator attributes [opt] constant-initializer [opt]
27873 identifier [opt] attributes [opt] : constant-expression
27874
27875 C++0x Extensions:
27876
27877 member-declaration:
27878 static_assert-declaration */
27879
27880static void
27881cp_parser_member_declaration (cp_parser* parser)
27882{
27883 cp_decl_specifier_seq decl_specifiers;
27884 tree prefix_attributes;
27885 tree decl;
27886 int declares_class_or_enum;
27887 bool friend_p;
27888 cp_token *token = NULL;
27889 cp_token *decl_spec_token_start = NULL;
27890 cp_token *initializer_token_start = NULL;
27891 int saved_pedantic;
27892 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
27893
27894 /* Check for the `__extension__' keyword. */
27895 if (cp_parser_extension_opt (parser, &saved_pedantic))
27896 {
27897 /* Recurse. */
27898 cp_parser_member_declaration (parser);
27899 /* Restore the old value of the PEDANTIC flag. */
27900 pedantic = saved_pedantic;
27901
27902 return;
27903 }
27904
27905 /* Check for a template-declaration. */
27906 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TEMPLATE))
27907 {
27908 /* An explicit specialization here is an error condition, and we
27909 expect the specialization handler to detect and report this. */
27910 if (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_LESS
27911 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type == CPP_GREATER)
27912 cp_parser_explicit_specialization (parser);
27913 else
27914 cp_parser_template_declaration (parser, /*member_p=*/true);
27915
27916 return;
27917 }
27918 /* Check for a template introduction. */
27919 else if (cp_parser_template_declaration_after_export (parser, true))
27920 return;
27921
27922 /* Check for a using-declaration. */
27923 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_USING))
27924 {
27925 if (cxx_dialect < cxx11)
27926 /* Parse the using-declaration. */
27927 cp_parser_using_declaration (parser, /*access_declaration_p=*/false);
27928 else if (cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_ENUM))
27929 cp_parser_using_enum (parser);
27930 else
27931 {
27932 tree decl;
27933 bool alias_decl_expected;
27934 cp_parser_parse_tentatively (parser);
27935 decl = cp_parser_alias_declaration (parser);
27936 /* Note that if we actually see the '=' token after the
27937 identifier, cp_parser_alias_declaration commits the
27938 tentative parse. In that case, we really expect an
27939 alias-declaration. Otherwise, we expect a using
27940 declaration. */
27941 alias_decl_expected =
27942 !cp_parser_uncommitted_to_tentative_parse_p (parser);
27943 cp_parser_parse_definitely (parser);
27944
27945 if (alias_decl_expected)
27946 finish_member_declaration (decl);
27947 else
27948 cp_parser_using_declaration (parser,
27949 /*access_declaration_p=*/false);
27950 }
27951 return;
27952 }
27953
27954 /* Check for @defs. */
27955 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_AT_DEFS))
27956 {
27957 tree ivar, member;
27958 tree ivar_chains = cp_parser_objc_defs_expression (parser);
27959 ivar = ivar_chains;
27960 while (ivar)
27961 {
27962 member = ivar;
27963 ivar = TREE_CHAIN (member);
27964 TREE_CHAIN (member) = NULL_TREE;
27965 finish_member_declaration (member);
27966 }
27967 return;
27968 }
27969
27970 /* If the next token is `static_assert' we have a static assertion. */
27971 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_STATIC_ASSERT))
27972 {
27973 cp_parser_static_assert (parser, /*member_p=*/true);
27974 return;
27975 }
27976
27977 parser->colon_corrects_to_scope_p = false;
27978
27979 cp_omp_declare_simd_data odsd;
27980 if (cp_parser_using_declaration (parser, /*access_declaration=*/access_declaration_p: true))
27981 goto out;
27982
27983 /* Parse the decl-specifier-seq. */
27984 decl_spec_token_start = cp_lexer_peek_token (lexer: parser->lexer);
27985 cp_parser_decl_specifier_seq (parser,
27986 flags: (CP_PARSER_FLAGS_OPTIONAL
27987 | CP_PARSER_FLAGS_TYPENAME_OPTIONAL),
27988 decl_specs: &decl_specifiers,
27989 declares_class_or_enum: &declares_class_or_enum);
27990
27991 if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
27992 cp_parser_handle_directive_omp_attributes (parser,
27993 pattrs: &decl_specifiers.attributes,
27994 data: &odsd, start: true);
27995
27996 /* Check for an invalid type-name. */
27997 if (!decl_specifiers.any_type_specifiers_p
27998 && cp_parser_parse_and_diagnose_invalid_type_name (parser))
27999 goto out;
28000 /* If there is no declarator, then the decl-specifier-seq should
28001 specify a type. */
28002 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
28003 {
28004 /* If there was no decl-specifier-seq, and the next token is a
28005 `;', then we have something like:
28006
28007 struct S { ; };
28008
28009 [class.mem]
28010
28011 Each member-declaration shall declare at least one member
28012 name of the class. */
28013 if (!decl_specifiers.any_specifiers_p)
28014 {
28015 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
28016 if (cxx_dialect < cxx11 && !in_system_header_at (loc: token->location))
28017 {
28018 gcc_rich_location richloc (token->location);
28019 richloc.add_fixit_remove ();
28020 pedwarn (&richloc, OPT_Wpedantic, "extra %<;%>");
28021 }
28022 }
28023 else
28024 {
28025 /* See if this declaration is a friend. */
28026 friend_p = cp_parser_friend_p (&decl_specifiers);
28027 /* If there were decl-specifiers, check to see if there was
28028 a class-declaration. */
28029 tree type = check_tag_decl (&decl_specifiers,
28030 /*explicit_type_instantiation_p=*/false);
28031 /* Nested classes have already been added to the class, but
28032 a `friend' needs to be explicitly registered. */
28033 if (friend_p)
28034 {
28035 /* If the `friend' keyword was present, the friend must
28036 be introduced with a class-key. */
28037 if (!declares_class_or_enum && cxx_dialect < cxx11)
28038 pedwarn (decl_spec_token_start->location, OPT_Wpedantic,
28039 "in C++03 a class-key must be used "
28040 "when declaring a friend");
28041 /* In this case:
28042
28043 template <typename T> struct A {
28044 friend struct A<T>::B;
28045 };
28046
28047 A<T>::B will be represented by a TYPENAME_TYPE, and
28048 therefore not recognized by check_tag_decl. */
28049 if (!type)
28050 {
28051 type = decl_specifiers.type;
28052 if (type && TREE_CODE (type) == TYPE_DECL)
28053 type = TREE_TYPE (type);
28054 }
28055 /* Warn if an attribute cannot appear here, as per
28056 [dcl.attr.grammar]/5. But not when declares_class_or_enum:
28057 we ignore attributes in elaborated-type-specifiers. */
28058 if (!declares_class_or_enum
28059 && cxx11_attribute_p (decl_specifiers.attributes))
28060 {
28061 decl_specifiers.attributes = NULL_TREE;
28062 if (warning_at (decl_spec_token_start->location,
28063 OPT_Wattributes, "attribute ignored"))
28064 inform (decl_spec_token_start->location, "an attribute "
28065 "that appertains to a friend declaration that "
28066 "is not a definition is ignored");
28067 }
28068 if (!type || !TYPE_P (type))
28069 error_at (decl_spec_token_start->location,
28070 "friend declaration does not name a class or "
28071 "function");
28072 else
28073 make_friend_class (current_class_type, type,
28074 /*complain=*/true);
28075 }
28076 /* If there is no TYPE, an error message will already have
28077 been issued. */
28078 else if (!type || type == error_mark_node)
28079 ;
28080 /* An anonymous aggregate has to be handled specially; such
28081 a declaration really declares a data member (with a
28082 particular type), as opposed to a nested class. */
28083 else if (ANON_AGGR_TYPE_P (type))
28084 {
28085 /* C++11 9.5/6. */
28086 if (decl_specifiers.storage_class != sc_none)
28087 error_at (decl_spec_token_start->location,
28088 "a storage class on an anonymous aggregate "
28089 "in class scope is not allowed");
28090
28091 /* Remove constructors and such from TYPE, now that we
28092 know it is an anonymous aggregate. */
28093 fixup_anonymous_aggr (type);
28094 /* And make the corresponding data member. */
28095 decl = build_decl (decl_spec_token_start->location,
28096 FIELD_DECL, NULL_TREE, type);
28097 /* Add it to the class. */
28098 finish_member_declaration (decl);
28099 }
28100 else
28101 cp_parser_check_access_in_redeclaration
28102 (TYPE_NAME (type),
28103 location: decl_spec_token_start->location);
28104 }
28105 }
28106 else
28107 {
28108 bool assume_semicolon = false;
28109
28110 /* Clear attributes from the decl_specifiers but keep them
28111 around as prefix attributes that apply them to the entity
28112 being declared. */
28113 prefix_attributes = decl_specifiers.attributes;
28114 decl_specifiers.attributes = NULL_TREE;
28115 if (parser->omp_declare_simd
28116 && (parser->omp_declare_simd->attribs[0]
28117 == &decl_specifiers.attributes))
28118 parser->omp_declare_simd->attribs[0] = &prefix_attributes;
28119
28120 /* See if these declarations will be friends. */
28121 friend_p = cp_parser_friend_p (&decl_specifiers);
28122
28123 /* Keep going until we hit the `;' at the end of the
28124 declaration. */
28125 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
28126 {
28127 tree attributes = NULL_TREE;
28128 tree first_attribute;
28129 tree initializer;
28130 bool named_bitfld = false;
28131
28132 /* Peek at the next token. */
28133 token = cp_lexer_peek_token (lexer: parser->lexer);
28134
28135 /* The following code wants to know early if it is a bit-field
28136 or some other declaration. Attributes can appear before
28137 the `:' token. Skip over them without consuming any tokens
28138 to peek if they are followed by `:'. */
28139 if (cp_next_tokens_can_be_attribute_p (parser)
28140 || (token->type == CPP_NAME
28141 && cp_nth_tokens_can_be_attribute_p (parser, 2)
28142 && (named_bitfld = true)))
28143 {
28144 size_t n
28145 = cp_parser_skip_attributes_opt (parser, 1 + named_bitfld);
28146 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n);
28147 }
28148
28149 /* Check for a bitfield declaration. */
28150 if (token->type == CPP_COLON
28151 || (token->type == CPP_NAME
28152 && token == cp_lexer_peek_token (lexer: parser->lexer)
28153 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COLON)
28154 && (named_bitfld = true)))
28155 {
28156 tree identifier;
28157 tree width;
28158 tree late_attributes = NULL_TREE;
28159 location_t id_location
28160 = cp_lexer_peek_token (lexer: parser->lexer)->location;
28161
28162 if (named_bitfld)
28163 identifier = cp_parser_identifier (parser);
28164 else
28165 identifier = NULL_TREE;
28166
28167 /* Look for attributes that apply to the bitfield. */
28168 attributes = cp_parser_attributes_opt (parser);
28169
28170 /* Consume the `:' token. */
28171 cp_lexer_consume_token (lexer: parser->lexer);
28172
28173 /* Get the width of the bitfield. */
28174 width = cp_parser_constant_expression (parser, allow_non_constant_p: false, NULL,
28175 strict_p: cxx_dialect >= cxx11);
28176
28177 /* In C++20 and as extension for C++11 and above we allow
28178 default member initializers for bit-fields. */
28179 initializer = NULL_TREE;
28180 if (cxx_dialect >= cxx11
28181 && (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ)
28182 || cp_lexer_next_token_is (lexer: parser->lexer,
28183 type: CPP_OPEN_BRACE)))
28184 {
28185 location_t loc
28186 = cp_lexer_peek_token (lexer: parser->lexer)->location;
28187 if (cxx_dialect < cxx20
28188 && identifier != NULL_TREE)
28189 pedwarn (loc, OPT_Wc__20_extensions,
28190 "default member initializers for bit-fields "
28191 "only available with %<-std=c++20%> or "
28192 "%<-std=gnu++20%>");
28193
28194 initializer = cp_parser_save_nsdmi (parser);
28195 if (identifier == NULL_TREE)
28196 {
28197 error_at (loc, "default member initializer for "
28198 "unnamed bit-field");
28199 initializer = NULL_TREE;
28200 }
28201 }
28202 else
28203 {
28204 /* Look for attributes that apply to the bitfield after
28205 the `:' token and width. This is where GCC used to
28206 parse attributes in the past, pedwarn if there is
28207 a std attribute. */
28208 if (cp_next_tokens_can_be_std_attribute_p (parser))
28209 pedwarn (input_location, OPT_Wpedantic,
28210 "ISO C++ allows bit-field attributes only "
28211 "before the %<:%> token");
28212
28213 late_attributes = cp_parser_attributes_opt (parser);
28214 }
28215
28216 attributes = attr_chainon (attrs: attributes, attr: late_attributes);
28217
28218 /* Remember which attributes are prefix attributes and
28219 which are not. */
28220 first_attribute = attributes;
28221 /* Combine the attributes. */
28222 attributes = attr_chainon (attrs: prefix_attributes, attr: attributes);
28223
28224 /* Create the bitfield declaration. */
28225 decl = grokbitfield (identifier
28226 ? make_id_declarator (NULL_TREE,
28227 unqualified_name: identifier,
28228 sfk: sfk_none,
28229 id_location)
28230 : NULL,
28231 &decl_specifiers,
28232 width, initializer,
28233 attributes);
28234 }
28235 else
28236 {
28237 cp_declarator *declarator;
28238 tree asm_specification;
28239 int ctor_dtor_or_conv_p;
28240 bool static_p = (decl_specifiers.storage_class == sc_static);
28241 cp_parser_flags flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
28242 /* We can't delay parsing for friends,
28243 alias-declarations, and typedefs, even though the
28244 standard seems to require it. */
28245 if (!friend_p
28246 && !decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
28247 flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT;
28248
28249 /* Parse the declarator. */
28250 declarator
28251 = cp_parser_declarator (parser, dcl_kind: CP_PARSER_DECLARATOR_NAMED,
28252 flags,
28253 ctor_dtor_or_conv_p: &ctor_dtor_or_conv_p,
28254 /*parenthesized_p=*/NULL,
28255 /*member_p=*/true,
28256 friend_p, static_p);
28257
28258 /* If something went wrong parsing the declarator, make sure
28259 that we at least consume some tokens. */
28260 if (declarator == cp_error_declarator)
28261 {
28262 /* Skip to the end of the statement. */
28263 cp_parser_skip_to_end_of_statement (parser);
28264 /* If the next token is not a semicolon, that is
28265 probably because we just skipped over the body of
28266 a function. So, we consume a semicolon if
28267 present, but do not issue an error message if it
28268 is not present. */
28269 if (cp_lexer_next_token_is (lexer: parser->lexer,
28270 type: CPP_SEMICOLON))
28271 cp_lexer_consume_token (lexer: parser->lexer);
28272 goto out;
28273 }
28274
28275 /* Handle class-scope non-template C++17 deduction guides. */
28276 cp_parser_maybe_adjust_declarator_for_dguide (parser,
28277 decl_specs: &decl_specifiers,
28278 declarator,
28279 ctor_dtor_or_conv_p: &ctor_dtor_or_conv_p);
28280
28281 if (declares_class_or_enum & 2)
28282 cp_parser_check_for_definition_in_return_type
28283 (declarator, type: decl_specifiers.type,
28284 type_location: decl_specifiers.locations[ds_type_spec]);
28285
28286 /* Look for an asm-specification. */
28287 asm_specification = cp_parser_asm_specification_opt (parser);
28288 /* Look for attributes that apply to the declaration. */
28289 attributes = cp_parser_attributes_opt (parser);
28290 /* Remember which attributes are prefix attributes and
28291 which are not. */
28292 first_attribute = attributes;
28293 /* Combine the attributes. */
28294 attributes = attr_chainon (attrs: prefix_attributes, attr: attributes);
28295
28296 /* If it's an `=', then we have a constant-initializer or a
28297 pure-specifier. It is not correct to parse the
28298 initializer before registering the member declaration
28299 since the member declaration should be in scope while
28300 its initializer is processed. However, the rest of the
28301 front end does not yet provide an interface that allows
28302 us to handle this correctly. */
28303 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
28304 {
28305 /* In [class.mem]:
28306
28307 A pure-specifier shall be used only in the declaration of
28308 a virtual function.
28309
28310 A member-declarator can contain a constant-initializer
28311 only if it declares a static member of integral or
28312 enumeration type.
28313
28314 Therefore, if the DECLARATOR is for a function, we look
28315 for a pure-specifier; otherwise, we look for a
28316 constant-initializer. When we call `grokfield', it will
28317 perform more stringent semantics checks. */
28318 initializer_token_start = cp_lexer_peek_token (lexer: parser->lexer);
28319 declarator->init_loc = initializer_token_start->location;
28320 if (function_declarator_p (declarator)
28321 || (decl_specifiers.type
28322 && TREE_CODE (decl_specifiers.type) == TYPE_DECL
28323 && declarator->kind == cdk_id
28324 && (TREE_CODE (TREE_TYPE (decl_specifiers.type))
28325 == FUNCTION_TYPE)))
28326 initializer = cp_parser_pure_specifier (parser);
28327 else if (decl_specifiers.storage_class != sc_static)
28328 initializer = cp_parser_save_nsdmi (parser);
28329 else if (cxx_dialect >= cxx11)
28330 {
28331 /* Don't require a constant rvalue in C++11, since we
28332 might want a reference constant. We'll enforce
28333 constancy later. */
28334 cp_lexer_consume_token (lexer: parser->lexer);
28335 /* Parse the initializer. */
28336 initializer = cp_parser_initializer_clause (parser);
28337 }
28338 else
28339 /* Parse the initializer. */
28340 initializer = cp_parser_constant_initializer (parser);
28341 }
28342 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE)
28343 && !function_declarator_p (declarator))
28344 {
28345 declarator->init_loc
28346 = cp_lexer_peek_token (lexer: parser->lexer)->location;
28347 if (decl_specifiers.storage_class != sc_static)
28348 initializer = cp_parser_save_nsdmi (parser);
28349 else
28350 initializer = cp_parser_initializer (parser);
28351 }
28352 /* Detect invalid bit-field cases such as
28353
28354 int *p : 4;
28355 int &&r : 3;
28356
28357 and similar. */
28358 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON)
28359 /* If there were no type specifiers, it was a
28360 constructor. */
28361 && decl_specifiers.any_type_specifiers_p)
28362 {
28363 /* This is called for a decent diagnostic only. */
28364 tree d = grokdeclarator (declarator, &decl_specifiers,
28365 BITFIELD, /*initialized=*/false,
28366 &attributes);
28367 if (!error_operand_p (t: d))
28368 error_at (DECL_SOURCE_LOCATION (d),
28369 "bit-field %qD has non-integral type %qT",
28370 d, TREE_TYPE (d));
28371 cp_parser_skip_to_end_of_statement (parser);
28372 /* Avoid "extra ;" pedwarns. */
28373 if (cp_lexer_next_token_is (lexer: parser->lexer,
28374 type: CPP_SEMICOLON))
28375 cp_lexer_consume_token (lexer: parser->lexer);
28376 goto out;
28377 }
28378 /* Otherwise, there is no initializer. */
28379 else
28380 initializer = NULL_TREE;
28381
28382 /* See if we are probably looking at a function
28383 definition. We are certainly not looking at a
28384 member-declarator. Calling `grokfield' has
28385 side-effects, so we must not do it unless we are sure
28386 that we are looking at a member-declarator. */
28387 if (cp_parser_token_starts_function_definition_p
28388 (cp_lexer_peek_token (lexer: parser->lexer)))
28389 {
28390 /* The grammar does not allow a pure-specifier to be
28391 used when a member function is defined. (It is
28392 possible that this fact is an oversight in the
28393 standard, since a pure function may be defined
28394 outside of the class-specifier. */
28395 if (initializer && initializer_token_start)
28396 error_at (initializer_token_start->location,
28397 "pure-specifier on function-definition");
28398 decl = cp_parser_save_member_function_body (parser,
28399 &decl_specifiers,
28400 declarator,
28401 attributes);
28402
28403 if (parser->fully_implicit_function_template_p)
28404 decl = finish_fully_implicit_template (parser, decl);
28405 /* If the member was not a friend, declare it here. */
28406 if (!friend_p)
28407 finish_member_declaration (decl);
28408 /* Peek at the next token. */
28409 token = cp_lexer_peek_token (lexer: parser->lexer);
28410 /* If the next token is a semicolon, consume it. */
28411 if (token->type == CPP_SEMICOLON)
28412 {
28413 location_t semicolon_loc
28414 = cp_lexer_consume_token (lexer: parser->lexer)->location;
28415 gcc_rich_location richloc (semicolon_loc);
28416 richloc.add_fixit_remove ();
28417 warning_at (&richloc, OPT_Wextra_semi,
28418 "extra %<;%> after in-class "
28419 "function definition");
28420 }
28421 goto out;
28422 }
28423 else
28424 if (declarator->kind == cdk_function)
28425 declarator->id_loc = token->location;
28426
28427 /* Create the declaration. */
28428 decl = grokfield (declarator, &decl_specifiers,
28429 initializer, /*init_const_expr_p=*/true,
28430 asm_specification, attributes);
28431
28432 if (parser->fully_implicit_function_template_p)
28433 {
28434 if (friend_p)
28435 finish_fully_implicit_template (parser, 0);
28436 else
28437 decl = finish_fully_implicit_template (parser, decl);
28438 }
28439 }
28440
28441 cp_finalize_omp_declare_simd (parser, fndecl: decl);
28442 cp_finalize_oacc_routine (parser, decl, false);
28443
28444 /* Reset PREFIX_ATTRIBUTES. */
28445 if (attributes != error_mark_node)
28446 {
28447 while (attributes && TREE_CHAIN (attributes) != first_attribute)
28448 attributes = TREE_CHAIN (attributes);
28449 if (attributes)
28450 TREE_CHAIN (attributes) = NULL_TREE;
28451 }
28452
28453 /* If there is any qualification still in effect, clear it
28454 now; we will be starting fresh with the next declarator. */
28455 parser->scope = NULL_TREE;
28456 parser->qualifying_scope = NULL_TREE;
28457 parser->object_scope = NULL_TREE;
28458 /* If it's a `,', then there are more declarators. */
28459 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
28460 {
28461 cp_lexer_consume_token (lexer: parser->lexer);
28462 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
28463 {
28464 cp_token *token = cp_lexer_previous_token (lexer: parser->lexer);
28465 gcc_rich_location richloc (token->location);
28466 richloc.add_fixit_remove ();
28467 error_at (&richloc, "stray %<,%> at end of "
28468 "member declaration");
28469 }
28470 }
28471 /* If the next token isn't a `;', then we have a parse error. */
28472 else if (cp_lexer_next_token_is_not (lexer: parser->lexer,
28473 type: CPP_SEMICOLON))
28474 {
28475 /* The next token might be a ways away from where the
28476 actual semicolon is missing. Find the previous token
28477 and use that for our error position. */
28478 cp_token *token = cp_lexer_previous_token (lexer: parser->lexer);
28479 gcc_rich_location richloc (token->location);
28480 richloc.add_fixit_insert_after (new_content: ";");
28481 error_at (&richloc, "expected %<;%> at end of "
28482 "member declaration");
28483
28484 /* Assume that the user meant to provide a semicolon. If
28485 we were to cp_parser_skip_to_end_of_statement, we might
28486 skip to a semicolon inside a member function definition
28487 and issue nonsensical error messages. */
28488 assume_semicolon = true;
28489 }
28490
28491 if (decl)
28492 {
28493 /* Add DECL to the list of members. */
28494 if (!friend_p
28495 /* Explicitly include, eg, NSDMIs, for better error
28496 recovery (c++/58650). */
28497 || !DECL_DECLARES_FUNCTION_P (decl))
28498 finish_member_declaration (decl);
28499
28500 if (DECL_DECLARES_FUNCTION_P (decl))
28501 cp_parser_save_default_args (parser, STRIP_TEMPLATE (decl));
28502 else if (TREE_CODE (decl) == FIELD_DECL
28503 && DECL_INITIAL (decl))
28504 /* Add DECL to the queue of NSDMI to be parsed later. */
28505 vec_safe_push (unparsed_nsdmis, obj: decl);
28506 }
28507
28508 if (assume_semicolon)
28509 goto out;
28510 }
28511 }
28512
28513 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
28514 out:
28515 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
28516 cp_finalize_omp_declare_simd (parser, data: &odsd);
28517}
28518
28519/* Parse a pure-specifier.
28520
28521 pure-specifier:
28522 = 0
28523
28524 Returns INTEGER_ZERO_NODE if a pure specifier is found.
28525 Otherwise, ERROR_MARK_NODE is returned. */
28526
28527static tree
28528cp_parser_pure_specifier (cp_parser* parser)
28529{
28530 cp_token *token;
28531
28532 /* Look for the `=' token. */
28533 if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
28534 return error_mark_node;
28535 /* Look for the `0' token. */
28536 token = cp_lexer_peek_token (lexer: parser->lexer);
28537
28538 if (token->type == CPP_EOF
28539 || token->type == CPP_PRAGMA_EOL)
28540 return error_mark_node;
28541
28542 cp_lexer_consume_token (lexer: parser->lexer);
28543
28544 /* Accept = default or = delete in c++0x mode. */
28545 if (token->keyword == RID_DEFAULT
28546 || token->keyword == RID_DELETE)
28547 {
28548 maybe_warn_cpp0x (str: CPP0X_DEFAULTED_DELETED);
28549 return token->u.value;
28550 }
28551
28552 /* c_lex_with_flags marks a single digit '0' with PURE_ZERO. */
28553 if (token->type != CPP_NUMBER || !(token->flags & PURE_ZERO))
28554 {
28555 cp_parser_error (parser,
28556 gmsgid: "invalid pure specifier (only %<= 0%> is allowed)");
28557 cp_parser_skip_to_end_of_statement (parser);
28558 return error_mark_node;
28559 }
28560 if (PROCESSING_REAL_TEMPLATE_DECL_P ())
28561 {
28562 error_at (token->location, "templates may not be %<virtual%>");
28563 return error_mark_node;
28564 }
28565
28566 return integer_zero_node;
28567}
28568
28569/* Parse a constant-initializer.
28570
28571 constant-initializer:
28572 = constant-expression
28573
28574 Returns a representation of the constant-expression. */
28575
28576static tree
28577cp_parser_constant_initializer (cp_parser* parser)
28578{
28579 /* Look for the `=' token. */
28580 if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
28581 return error_mark_node;
28582
28583 /* It is invalid to write:
28584
28585 struct S { static const int i = { 7 }; };
28586
28587 */
28588 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
28589 {
28590 cp_parser_error (parser,
28591 gmsgid: "a brace-enclosed initializer is not allowed here");
28592 /* Consume the opening brace. */
28593 matching_braces braces;
28594 braces.consume_open (parser);
28595 /* Skip the initializer. */
28596 cp_parser_skip_to_closing_brace (parser);
28597 /* Look for the trailing `}'. */
28598 braces.require_close (parser);
28599
28600 return error_mark_node;
28601 }
28602
28603 return cp_parser_constant_expression (parser);
28604}
28605
28606/* Derived classes [gram.class.derived] */
28607
28608/* Parse a base-clause.
28609
28610 base-clause:
28611 : base-specifier-list
28612
28613 base-specifier-list:
28614 base-specifier ... [opt]
28615 base-specifier-list , base-specifier ... [opt]
28616
28617 Returns a TREE_LIST representing the base-classes, in the order in
28618 which they were declared. The representation of each node is as
28619 described by cp_parser_base_specifier.
28620
28621 In the case that no bases are specified, this function will return
28622 NULL_TREE, not ERROR_MARK_NODE. */
28623
28624static tree
28625cp_parser_base_clause (cp_parser* parser)
28626{
28627 tree bases = NULL_TREE;
28628
28629 /* Look for the `:' that begins the list. */
28630 cp_parser_require (parser, CPP_COLON, RT_COLON);
28631
28632 /* Scan the base-specifier-list. */
28633 while (true)
28634 {
28635 cp_token *token;
28636 tree base;
28637 bool pack_expansion_p = false;
28638
28639 /* Look for the base-specifier. */
28640 base = cp_parser_base_specifier (parser);
28641 /* Look for the (optional) ellipsis. */
28642 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
28643 {
28644 /* Consume the `...'. */
28645 cp_lexer_consume_token (lexer: parser->lexer);
28646
28647 pack_expansion_p = true;
28648 }
28649
28650 /* Add BASE to the front of the list. */
28651 if (base && base != error_mark_node)
28652 {
28653 if (pack_expansion_p)
28654 /* Make this a pack expansion type. */
28655 TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
28656
28657 if (!check_for_bare_parameter_packs (TREE_VALUE (base)))
28658 {
28659 TREE_CHAIN (base) = bases;
28660 bases = base;
28661 }
28662 }
28663 /* Peek at the next token. */
28664 token = cp_lexer_peek_token (lexer: parser->lexer);
28665 /* If it's not a comma, then the list is complete. */
28666 if (token->type != CPP_COMMA)
28667 break;
28668 /* Consume the `,'. */
28669 cp_lexer_consume_token (lexer: parser->lexer);
28670 }
28671
28672 /* PARSER->SCOPE may still be non-NULL at this point, if the last
28673 base class had a qualified name. However, the next name that
28674 appears is certainly not qualified. */
28675 parser->scope = NULL_TREE;
28676 parser->qualifying_scope = NULL_TREE;
28677 parser->object_scope = NULL_TREE;
28678
28679 return nreverse (bases);
28680}
28681
28682/* Parse a base-specifier.
28683
28684 base-specifier:
28685 :: [opt] nested-name-specifier [opt] class-name
28686 virtual access-specifier [opt] :: [opt] nested-name-specifier
28687 [opt] class-name
28688 access-specifier virtual [opt] :: [opt] nested-name-specifier
28689 [opt] class-name
28690
28691 Returns a TREE_LIST. The TREE_PURPOSE will be one of
28692 ACCESS_{DEFAULT,PUBLIC,PROTECTED,PRIVATE}_[VIRTUAL]_NODE to
28693 indicate the specifiers provided. The TREE_VALUE will be a TYPE
28694 (or the ERROR_MARK_NODE) indicating the type that was specified. */
28695
28696static tree
28697cp_parser_base_specifier (cp_parser* parser)
28698{
28699 cp_token *token;
28700 bool done = false;
28701 bool virtual_p = false;
28702 bool duplicate_virtual_error_issued_p = false;
28703 bool duplicate_access_error_issued_p = false;
28704 bool class_scope_p, template_p;
28705 tree access = access_default_node;
28706 tree type;
28707
28708 /* Process the optional `virtual' and `access-specifier'. */
28709 while (!done)
28710 {
28711 /* Peek at the next token. */
28712 token = cp_lexer_peek_token (lexer: parser->lexer);
28713 /* Process `virtual'. */
28714 switch (token->keyword)
28715 {
28716 case RID_VIRTUAL:
28717 /* If `virtual' appears more than once, issue an error. */
28718 if (virtual_p && !duplicate_virtual_error_issued_p)
28719 {
28720 cp_parser_error (parser,
28721 gmsgid: "%<virtual%> specified more than once in base-specifier");
28722 duplicate_virtual_error_issued_p = true;
28723 }
28724
28725 virtual_p = true;
28726
28727 /* Consume the `virtual' token. */
28728 cp_lexer_consume_token (lexer: parser->lexer);
28729
28730 break;
28731
28732 case RID_PUBLIC:
28733 case RID_PROTECTED:
28734 case RID_PRIVATE:
28735 /* If more than one access specifier appears, issue an
28736 error. */
28737 if (access != access_default_node
28738 && !duplicate_access_error_issued_p)
28739 {
28740 cp_parser_error (parser,
28741 gmsgid: "more than one access specifier in base-specifier");
28742 duplicate_access_error_issued_p = true;
28743 }
28744
28745 access = ridpointers[(int) token->keyword];
28746
28747 /* Consume the access-specifier. */
28748 cp_lexer_consume_token (lexer: parser->lexer);
28749
28750 break;
28751
28752 default:
28753 done = true;
28754 break;
28755 }
28756 }
28757 /* It is not uncommon to see programs mechanically, erroneously, use
28758 the 'typename' keyword to denote (dependent) qualified types
28759 as base classes. */
28760 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TYPENAME))
28761 {
28762 token = cp_lexer_peek_token (lexer: parser->lexer);
28763 if (!processing_template_decl)
28764 error_at (token->location,
28765 "keyword %<typename%> not allowed outside of templates");
28766 else
28767 error_at (token->location,
28768 "keyword %<typename%> not allowed in this context "
28769 "(the base class is implicitly a type)");
28770 cp_lexer_consume_token (lexer: parser->lexer);
28771 }
28772
28773 /* Look for the optional `::' operator. */
28774 cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
28775 /* Look for the nested-name-specifier. The simplest way to
28776 implement:
28777
28778 [temp.res]
28779
28780 The keyword `typename' is not permitted in a base-specifier or
28781 mem-initializer; in these contexts a qualified name that
28782 depends on a template-parameter is implicitly assumed to be a
28783 type name.
28784
28785 is to pretend that we have seen the `typename' keyword at this
28786 point. */
28787 cp_parser_nested_name_specifier_opt (parser,
28788 /*typename_keyword_p=*/true,
28789 /*check_dependency_p=*/true,
28790 /*type_p=*/true,
28791 /*is_declaration=*/true);
28792 /* If the base class is given by a qualified name, assume that names
28793 we see are type names or templates, as appropriate. */
28794 class_scope_p = (parser->scope && TYPE_P (parser->scope));
28795 template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
28796
28797 if (!parser->scope
28798 && cp_lexer_next_token_is_decltype (lexer: parser->lexer))
28799 /* DR 950 allows decltype as a base-specifier. */
28800 type = cp_parser_decltype (parser);
28801 else
28802 {
28803 /* Otherwise, look for the class-name. */
28804 type = cp_parser_class_name (parser,
28805 typename_keyword_p: class_scope_p,
28806 template_keyword_p: template_p,
28807 tag_type: typename_type,
28808 /*check_dependency_p=*/true,
28809 /*class_head_p=*/false,
28810 /*is_declaration=*/true);
28811 type = TREE_TYPE (type);
28812 }
28813
28814 if (type == error_mark_node)
28815 return error_mark_node;
28816
28817 return finish_base_specifier (type, access, virtual_p);
28818}
28819
28820/* Exception handling [gram.exception] */
28821
28822/* Save the tokens that make up the noexcept-specifier for a member-function.
28823 Returns a DEFERRED_PARSE. */
28824
28825static tree
28826cp_parser_save_noexcept (cp_parser *parser)
28827{
28828 cp_token *first = parser->lexer->next_token;
28829 /* We want everything up to, including, the final ')'. */
28830 cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0);
28831 cp_token *last = parser->lexer->next_token;
28832
28833 /* As with default arguments and NSDMIs, make use of DEFERRED_PARSE
28834 to carry the information we will need. */
28835 tree expr = make_node (DEFERRED_PARSE);
28836 /* Save away the noexcept-specifier; we will process it when the
28837 class is complete. */
28838 DEFPARSE_TOKENS (expr) = cp_token_cache_new (first, last);
28839 DEFPARSE_INSTANTIATIONS (expr) = nullptr;
28840 expr = build_tree_list (expr, NULL_TREE);
28841 return expr;
28842}
28843
28844/* Used for late processing of noexcept-specifiers of member-functions.
28845 DEFAULT_ARG is the unparsed operand of a noexcept-specifier which
28846 we saved for later; parse it now. DECL is the declaration of the
28847 member function. */
28848
28849static tree
28850cp_parser_late_noexcept_specifier (cp_parser *parser, tree default_arg)
28851{
28852 /* Make sure we've gotten something that hasn't been parsed yet. */
28853 gcc_assert (TREE_CODE (default_arg) == DEFERRED_PARSE);
28854
28855 push_unparsed_function_queues (parser);
28856
28857 /* Push the saved tokens for the noexcept-specifier onto the parser's
28858 lexer stack. */
28859 cp_token_cache *tokens = DEFPARSE_TOKENS (default_arg);
28860 cp_parser_push_lexer_for_tokens (parser, cache: tokens);
28861
28862 /* Parse the cached noexcept-specifier. */
28863 tree parsed_arg
28864 = cp_parser_noexcept_specification_opt (parser,
28865 CP_PARSER_FLAGS_NONE,
28866 /*require_constexpr=*/true,
28867 /*consumed_expr=*/NULL,
28868 /*return_cond=*/false);
28869
28870 /* Revert to the main lexer. */
28871 cp_parser_pop_lexer (parser);
28872
28873 /* Restore the queue. */
28874 pop_unparsed_function_queues (parser);
28875
28876 /* And we're done. */
28877 return parsed_arg;
28878}
28879
28880/* Perform late checking of overriding function with respect to their
28881 noexcept-specifiers. FNDECL is the member function that potentially
28882 overrides some virtual function with the same signature. */
28883
28884static void
28885noexcept_override_late_checks (tree fndecl)
28886{
28887 tree binfo = TYPE_BINFO (DECL_CONTEXT (fndecl));
28888 tree base_binfo;
28889
28890 if (DECL_STATIC_FUNCTION_P (fndecl))
28891 return;
28892
28893 for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
28894 {
28895 tree basetype = BINFO_TYPE (base_binfo);
28896
28897 if (!TYPE_POLYMORPHIC_P (basetype))
28898 continue;
28899
28900 tree fn = look_for_overrides_here (basetype, fndecl);
28901 if (fn)
28902 maybe_check_overriding_exception_spec (fndecl, fn);
28903 }
28904}
28905
28906/* Parse an (optional) noexcept-specification.
28907
28908 noexcept-specification:
28909 noexcept ( constant-expression ) [opt]
28910
28911 If no noexcept-specification is present, returns NULL_TREE.
28912 Otherwise, if REQUIRE_CONSTEXPR is false, then either parse and return any
28913 expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if
28914 there are no parentheses. CONSUMED_EXPR will be set accordingly.
28915 Otherwise, returns a noexcept specification unless RETURN_COND is true,
28916 in which case a boolean condition is returned instead. The parser flags
28917 FLAGS is used to control parsing. QUALS are qualifiers indicating whether
28918 the (member) function is `const'. */
28919
28920static tree
28921cp_parser_noexcept_specification_opt (cp_parser* parser,
28922 cp_parser_flags flags,
28923 bool require_constexpr,
28924 bool* consumed_expr,
28925 bool return_cond)
28926{
28927 cp_token *token;
28928 const char *saved_message;
28929
28930 /* Peek at the next token. */
28931 token = cp_lexer_peek_token (lexer: parser->lexer);
28932
28933 /* Is it a noexcept-specification? */
28934 if (cp_parser_is_keyword (token, keyword: RID_NOEXCEPT))
28935 {
28936 tree expr;
28937
28938 /* [class.mem]/6 says that a noexcept-specifer (within the
28939 member-specification of the class) is a complete-class context of
28940 a class. So, if the noexcept-specifier has the optional expression,
28941 just save the tokens, and reparse this after we're done with the
28942 class. */
28943
28944 if ((flags & CP_PARSER_FLAGS_DELAY_NOEXCEPT)
28945 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_PAREN)
28946 /* No need to delay parsing for a number literal or true/false. */
28947 && !((cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_NUMBER)
28948 || cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_KEYWORD))
28949 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 4, type: CPP_CLOSE_PAREN))
28950 && at_class_scope_p ()
28951 && TYPE_BEING_DEFINED (current_class_type)
28952 && !LAMBDA_TYPE_P (current_class_type))
28953 return cp_parser_save_noexcept (parser);
28954
28955 cp_lexer_consume_token (lexer: parser->lexer);
28956
28957 if (cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_OPEN_PAREN)
28958 {
28959 matching_parens parens;
28960 parens.consume_open (parser);
28961
28962 if (require_constexpr)
28963 {
28964 /* Types may not be defined in an exception-specification. */
28965 saved_message = parser->type_definition_forbidden_message;
28966 parser->type_definition_forbidden_message
28967 = G_("types may not be defined in an exception-specification");
28968
28969 bool non_constant_p;
28970 expr
28971 = cp_parser_constant_expression (parser,
28972 /*allow_non_constant=*/allow_non_constant_p: true,
28973 non_constant_p: &non_constant_p);
28974 if (non_constant_p
28975 && !require_potential_rvalue_constant_expression (expr))
28976 {
28977 expr = NULL_TREE;
28978 return_cond = true;
28979 }
28980
28981 /* Restore the saved message. */
28982 parser->type_definition_forbidden_message = saved_message;
28983 }
28984 else
28985 {
28986 expr = cp_parser_expression (parser);
28987 *consumed_expr = true;
28988 }
28989
28990 parens.require_close (parser);
28991 }
28992 else
28993 {
28994 expr = boolean_true_node;
28995 if (!require_constexpr)
28996 *consumed_expr = false;
28997 }
28998
28999 /* We cannot build a noexcept-spec right away because this will check
29000 that expr is a constexpr. */
29001 if (!return_cond)
29002 return build_noexcept_spec (expr, tf_warning_or_error);
29003 else
29004 return expr;
29005 }
29006 else
29007 return NULL_TREE;
29008}
29009
29010/* Parse an (optional) exception-specification.
29011
29012 exception-specification:
29013 throw ( type-id-list [opt] )
29014
29015 Returns a TREE_LIST representing the exception-specification. The
29016 TREE_VALUE of each node is a type. The parser flags FLAGS is used to
29017 control parsing. QUALS are qualifiers indicating whether the (member)
29018 function is `const'. */
29019
29020static tree
29021cp_parser_exception_specification_opt (cp_parser* parser,
29022 cp_parser_flags flags)
29023{
29024 cp_token *token;
29025 tree type_id_list;
29026 const char *saved_message;
29027
29028 /* Peek at the next token. */
29029 token = cp_lexer_peek_token (lexer: parser->lexer);
29030
29031 /* Is it a noexcept-specification? */
29032 type_id_list
29033 = cp_parser_noexcept_specification_opt (parser, flags,
29034 /*require_constexpr=*/true,
29035 /*consumed_expr=*/NULL,
29036 /*return_cond=*/false);
29037 if (type_id_list != NULL_TREE)
29038 return type_id_list;
29039
29040 /* If it's not `throw', then there's no exception-specification. */
29041 if (!cp_parser_is_keyword (token, keyword: RID_THROW))
29042 return NULL_TREE;
29043
29044 location_t loc = token->location;
29045
29046 /* Consume the `throw'. */
29047 cp_lexer_consume_token (lexer: parser->lexer);
29048
29049 /* Look for the `('. */
29050 matching_parens parens;
29051 parens.require_open (parser);
29052
29053 /* Peek at the next token. */
29054 token = cp_lexer_peek_token (lexer: parser->lexer);
29055 /* If it's not a `)', then there is a type-id-list. */
29056 if (token->type != CPP_CLOSE_PAREN)
29057 {
29058 /* Types may not be defined in an exception-specification. */
29059 saved_message = parser->type_definition_forbidden_message;
29060 parser->type_definition_forbidden_message
29061 = G_("types may not be defined in an exception-specification");
29062 /* Parse the type-id-list. */
29063 type_id_list = cp_parser_type_id_list (parser);
29064 /* Restore the saved message. */
29065 parser->type_definition_forbidden_message = saved_message;
29066
29067 if (cxx_dialect >= cxx17)
29068 {
29069 error_at (loc, "ISO C++17 does not allow dynamic exception "
29070 "specifications");
29071 type_id_list = NULL_TREE;
29072 }
29073 else if (cxx_dialect >= cxx11)
29074 warning_at (loc, OPT_Wdeprecated,
29075 "dynamic exception specifications are deprecated in "
29076 "C++11");
29077 }
29078 /* In C++17, throw() is equivalent to noexcept (true). throw()
29079 is deprecated in C++11 and above as well, but is still widely used,
29080 so don't warn about it yet. */
29081 else if (cxx_dialect >= cxx17)
29082 type_id_list = noexcept_true_spec;
29083 else
29084 type_id_list = empty_except_spec;
29085
29086 /* Look for the `)'. */
29087 parens.require_close (parser);
29088
29089 return type_id_list;
29090}
29091
29092/* Parse an (optional) type-id-list.
29093
29094 type-id-list:
29095 type-id ... [opt]
29096 type-id-list , type-id ... [opt]
29097
29098 Returns a TREE_LIST. The TREE_VALUE of each node is a TYPE,
29099 in the order that the types were presented. */
29100
29101static tree
29102cp_parser_type_id_list (cp_parser* parser)
29103{
29104 tree types = NULL_TREE;
29105
29106 while (true)
29107 {
29108 cp_token *token;
29109 tree type;
29110
29111 token = cp_lexer_peek_token (lexer: parser->lexer);
29112
29113 /* Get the next type-id. */
29114 type = cp_parser_type_id (parser);
29115 /* Check for invalid 'auto'. */
29116 if (flag_concepts && type_uses_auto (type))
29117 {
29118 error_at (token->location,
29119 "invalid use of %<auto%> in exception-specification");
29120 type = error_mark_node;
29121 }
29122 /* Parse the optional ellipsis. */
29123 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
29124 {
29125 /* Consume the `...'. */
29126 cp_lexer_consume_token (lexer: parser->lexer);
29127
29128 /* Turn the type into a pack expansion expression. */
29129 type = make_pack_expansion (type);
29130 }
29131 /* Add it to the list. */
29132 types = add_exception_specifier (types, type, /*complain=*/1);
29133 /* Peek at the next token. */
29134 token = cp_lexer_peek_token (lexer: parser->lexer);
29135 /* If it is not a `,', we are done. */
29136 if (token->type != CPP_COMMA)
29137 break;
29138 /* Consume the `,'. */
29139 cp_lexer_consume_token (lexer: parser->lexer);
29140 }
29141
29142 return nreverse (types);
29143}
29144
29145/* Parse a try-block.
29146
29147 try-block:
29148 try compound-statement handler-seq */
29149
29150static tree
29151cp_parser_try_block (cp_parser* parser)
29152{
29153 tree try_block;
29154
29155 cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
29156 if (parser->in_function_body
29157 && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
29158 && cxx_dialect < cxx20)
29159 pedwarn (input_location, OPT_Wc__20_extensions,
29160 "%<try%> in %<constexpr%> function only "
29161 "available with %<-std=c++20%> or %<-std=gnu++20%>");
29162
29163 try_block = begin_try_block ();
29164 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_TRY_BLOCK, function_body: false);
29165 finish_try_block (try_block);
29166 cp_parser_handler_seq (parser);
29167 finish_handler_sequence (try_block);
29168
29169 return try_block;
29170}
29171
29172/* Parse a function-try-block.
29173
29174 function-try-block:
29175 try ctor-initializer [opt] function-body handler-seq */
29176
29177static void
29178cp_parser_function_try_block (cp_parser* parser)
29179{
29180 tree compound_stmt;
29181 tree try_block;
29182
29183 /* Look for the `try' keyword. */
29184 if (!cp_parser_require_keyword (parser, RID_TRY, RT_TRY))
29185 return;
29186 /* Let the rest of the front end know where we are. */
29187 try_block = begin_function_try_block (&compound_stmt);
29188 /* Parse the function-body. */
29189 cp_parser_ctor_initializer_opt_and_function_body
29190 (parser, /*in_function_try_block=*/true);
29191 /* We're done with the `try' part. */
29192 finish_function_try_block (try_block);
29193 /* Parse the handlers. */
29194 cp_parser_handler_seq (parser);
29195 /* We're done with the handlers. */
29196 finish_function_handler_sequence (try_block, compound_stmt);
29197}
29198
29199/* Parse a handler-seq.
29200
29201 handler-seq:
29202 handler handler-seq [opt] */
29203
29204static void
29205cp_parser_handler_seq (cp_parser* parser)
29206{
29207 while (true)
29208 {
29209 cp_token *token;
29210
29211 /* Parse the handler. */
29212 cp_parser_handler (parser);
29213 /* Peek at the next token. */
29214 token = cp_lexer_peek_token (lexer: parser->lexer);
29215 /* If it's not `catch' then there are no more handlers. */
29216 if (!cp_parser_is_keyword (token, keyword: RID_CATCH))
29217 break;
29218 }
29219}
29220
29221/* Parse a handler.
29222
29223 handler:
29224 catch ( exception-declaration ) compound-statement */
29225
29226static void
29227cp_parser_handler (cp_parser* parser)
29228{
29229 tree handler;
29230 tree declaration;
29231
29232 cp_parser_require_keyword (parser, RID_CATCH, RT_CATCH);
29233 handler = begin_handler ();
29234 matching_parens parens;
29235 parens.require_open (parser);
29236 declaration = cp_parser_exception_declaration (parser);
29237 finish_handler_parms (declaration, handler);
29238 parens.require_close (parser);
29239 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_NORMAL, function_body: false);
29240 finish_handler (handler);
29241}
29242
29243/* Parse an exception-declaration.
29244
29245 exception-declaration:
29246 type-specifier-seq declarator
29247 type-specifier-seq abstract-declarator
29248 type-specifier-seq
29249 ...
29250
29251 Returns a VAR_DECL for the declaration, or NULL_TREE if the
29252 ellipsis variant is used. */
29253
29254static tree
29255cp_parser_exception_declaration (cp_parser* parser)
29256{
29257 cp_decl_specifier_seq type_specifiers;
29258 cp_declarator *declarator;
29259 const char *saved_message;
29260
29261 /* If it's an ellipsis, it's easy to handle. */
29262 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
29263 {
29264 /* Consume the `...' token. */
29265 cp_lexer_consume_token (lexer: parser->lexer);
29266 return NULL_TREE;
29267 }
29268
29269 /* Types may not be defined in exception-declarations. */
29270 saved_message = parser->type_definition_forbidden_message;
29271 parser->type_definition_forbidden_message
29272 = G_("types may not be defined in exception-declarations");
29273
29274 /* Parse the type-specifier-seq. */
29275 cp_parser_type_specifier_seq (parser, flags: CP_PARSER_FLAGS_NONE,
29276 /*is_declaration=*/true,
29277 /*is_trailing_return=*/false,
29278 type_specifier_seq: &type_specifiers);
29279 /* If it's a `)', then there is no declarator. */
29280 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
29281 declarator = NULL;
29282 else
29283 declarator = cp_parser_declarator (parser, dcl_kind: CP_PARSER_DECLARATOR_EITHER,
29284 flags: CP_PARSER_FLAGS_NONE,
29285 /*ctor_dtor_or_conv_p=*/NULL,
29286 /*parenthesized_p=*/NULL,
29287 /*member_p=*/false,
29288 /*friend_p=*/false,
29289 /*static_p=*/false);
29290
29291 /* Restore the saved message. */
29292 parser->type_definition_forbidden_message = saved_message;
29293
29294 if (!type_specifiers.any_specifiers_p)
29295 return error_mark_node;
29296
29297 return grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, NULL);
29298}
29299
29300/* Parse a throw-expression.
29301
29302 throw-expression:
29303 throw assignment-expression [opt]
29304
29305 Returns a THROW_EXPR representing the throw-expression. */
29306
29307static tree
29308cp_parser_throw_expression (cp_parser* parser)
29309{
29310 tree expression;
29311 cp_token* token;
29312 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
29313
29314 cp_parser_require_keyword (parser, RID_THROW, RT_THROW);
29315 token = cp_lexer_peek_token (lexer: parser->lexer);
29316 /* Figure out whether or not there is an assignment-expression
29317 following the "throw" keyword. */
29318 if (token->type == CPP_COMMA
29319 || token->type == CPP_SEMICOLON
29320 || token->type == CPP_CLOSE_PAREN
29321 || token->type == CPP_CLOSE_SQUARE
29322 || token->type == CPP_CLOSE_BRACE
29323 || token->type == CPP_COLON)
29324 expression = NULL_TREE;
29325 else
29326 expression = cp_parser_assignment_expression (parser);
29327
29328 /* Construct a location e.g.:
29329 throw x
29330 ^~~~~~~
29331 with caret == start at the start of the "throw" token, and
29332 the end at the end of the final token we consumed. */
29333 location_t combined_loc = make_location (caret: start_loc, start: start_loc,
29334 lexer: parser->lexer);
29335 expression = build_throw (combined_loc, expression, tf_warning_or_error);
29336
29337 return expression;
29338}
29339
29340/* Parse a yield-expression.
29341
29342 yield-expression:
29343 co_yield assignment-expression
29344 co_yield braced-init-list
29345
29346 Returns a CO_YIELD_EXPR representing the yield-expression. */
29347
29348static tree
29349cp_parser_yield_expression (cp_parser* parser)
29350{
29351 tree expr;
29352
29353 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
29354 location_t kw_loc = token->location; /* Save for later. */
29355
29356 cp_parser_require_keyword (parser, RID_CO_YIELD, RT_CO_YIELD);
29357
29358 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
29359 {
29360 cp_lexer_set_source_position (lexer: parser->lexer);
29361 /* ??? : probably a moot point? */
29362 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
29363 expr = cp_parser_braced_list (parser);
29364 }
29365 else
29366 expr = cp_parser_assignment_expression (parser);
29367
29368 if (expr == error_mark_node)
29369 return expr;
29370
29371 return finish_co_yield_expr (kw_loc, expr);
29372}
29373
29374/* GNU Extensions */
29375
29376/* Parse an (optional) asm-specification.
29377
29378 asm-specification:
29379 asm ( string-literal )
29380
29381 If the asm-specification is present, returns a STRING_CST
29382 corresponding to the string-literal. Otherwise, returns
29383 NULL_TREE. */
29384
29385static tree
29386cp_parser_asm_specification_opt (cp_parser* parser)
29387{
29388 /* Peek at the next token. */
29389 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
29390 /* If the next token isn't the `asm' keyword, then there's no
29391 asm-specification. */
29392 if (!cp_parser_is_keyword (token, keyword: RID_ASM))
29393 return NULL_TREE;
29394
29395 /* Consume the `asm' token. */
29396 cp_lexer_consume_token (lexer: parser->lexer);
29397 /* Look for the `('. */
29398 matching_parens parens;
29399 parens.require_open (parser);
29400
29401 /* Look for the string-literal. */
29402 tree asm_specification = cp_parser_string_literal (parser,
29403 /*translate=*/false,
29404 /*wide_ok=*/false);
29405
29406 /* Look for the `)'. */
29407 parens.require_close (parser);
29408
29409 return asm_specification;
29410}
29411
29412/* Parse an asm-operand-list.
29413
29414 asm-operand-list:
29415 asm-operand
29416 asm-operand-list , asm-operand
29417
29418 asm-operand:
29419 string-literal ( expression )
29420 [ string-literal ] string-literal ( expression )
29421
29422 Returns a TREE_LIST representing the operands. The TREE_VALUE of
29423 each node is the expression. The TREE_PURPOSE is itself a
29424 TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed
29425 string-literal (or NULL_TREE if not present) and whose TREE_VALUE
29426 is a STRING_CST for the string literal before the parenthesis. Returns
29427 ERROR_MARK_NODE if any of the operands are invalid. */
29428
29429static tree
29430cp_parser_asm_operand_list (cp_parser* parser)
29431{
29432 tree asm_operands = NULL_TREE;
29433 bool invalid_operands = false;
29434
29435 while (true)
29436 {
29437 tree name;
29438
29439 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
29440 {
29441 /* Consume the `[' token. */
29442 cp_lexer_consume_token (lexer: parser->lexer);
29443 /* Read the operand name. */
29444 name = cp_parser_identifier (parser);
29445 if (name != error_mark_node)
29446 name = build_string (IDENTIFIER_LENGTH (name),
29447 IDENTIFIER_POINTER (name));
29448 /* Look for the closing `]'. */
29449 cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
29450 }
29451 else
29452 name = NULL_TREE;
29453 /* Look for the string-literal. */
29454 tree string_literal = cp_parser_string_literal (parser,
29455 /*translate=*/false,
29456 /*wide_ok=*/false);
29457
29458 /* Look for the `('. */
29459 matching_parens parens;
29460 parens.require_open (parser);
29461 /* Parse the expression. */
29462 tree expression = cp_parser_expression (parser);
29463 /* Look for the `)'. */
29464 parens.require_close (parser);
29465
29466 if (name == error_mark_node
29467 || string_literal == error_mark_node
29468 || expression == error_mark_node)
29469 invalid_operands = true;
29470
29471 /* Add this operand to the list. */
29472 asm_operands = tree_cons (build_tree_list (name, string_literal),
29473 expression,
29474 asm_operands);
29475 /* If the next token is not a `,', there are no more
29476 operands. */
29477 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
29478 break;
29479 /* Consume the `,'. */
29480 cp_lexer_consume_token (lexer: parser->lexer);
29481 }
29482
29483 return invalid_operands ? error_mark_node : nreverse (asm_operands);
29484}
29485
29486/* Parse an asm-clobber-list.
29487
29488 asm-clobber-list:
29489 string-literal
29490 asm-clobber-list , string-literal
29491
29492 Returns a TREE_LIST, indicating the clobbers in the order that they
29493 appeared. The TREE_VALUE of each node is a STRING_CST. */
29494
29495static tree
29496cp_parser_asm_clobber_list (cp_parser* parser)
29497{
29498 tree clobbers = NULL_TREE;
29499
29500 while (true)
29501 {
29502 /* Look for the string literal. */
29503 tree string_literal = cp_parser_string_literal (parser,
29504 /*translate=*/false,
29505 /*wide_ok=*/false);
29506 /* Add it to the list. */
29507 clobbers = tree_cons (NULL_TREE, string_literal, clobbers);
29508 /* If the next token is not a `,', then the list is
29509 complete. */
29510 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
29511 break;
29512 /* Consume the `,' token. */
29513 cp_lexer_consume_token (lexer: parser->lexer);
29514 }
29515
29516 return clobbers;
29517}
29518
29519/* Parse an asm-label-list.
29520
29521 asm-label-list:
29522 identifier
29523 asm-label-list , identifier
29524
29525 Returns a TREE_LIST, indicating the labels in the order that they
29526 appeared. The TREE_VALUE of each node is a label. */
29527
29528static tree
29529cp_parser_asm_label_list (cp_parser* parser)
29530{
29531 tree labels = NULL_TREE;
29532
29533 while (true)
29534 {
29535 tree identifier, label, name;
29536
29537 /* Look for the identifier. */
29538 identifier = cp_parser_identifier (parser);
29539 if (!error_operand_p (t: identifier))
29540 {
29541 label = lookup_label (identifier);
29542 if (TREE_CODE (label) == LABEL_DECL)
29543 {
29544 TREE_USED (label) = 1;
29545 check_goto (label);
29546 name = build_string (IDENTIFIER_LENGTH (identifier),
29547 IDENTIFIER_POINTER (identifier));
29548 labels = tree_cons (name, label, labels);
29549 }
29550 }
29551 /* If the next token is not a `,', then the list is
29552 complete. */
29553 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
29554 break;
29555 /* Consume the `,' token. */
29556 cp_lexer_consume_token (lexer: parser->lexer);
29557 }
29558
29559 return nreverse (labels);
29560}
29561
29562/* Return TRUE iff the next tokens in the stream are possibly the
29563 beginning of a GNU extension attribute. */
29564
29565static bool
29566cp_next_tokens_can_be_gnu_attribute_p (cp_parser *parser)
29567{
29568 return cp_nth_tokens_can_be_gnu_attribute_p (parser, 1);
29569}
29570
29571/* Return TRUE iff the next tokens in the stream are possibly the
29572 beginning of a standard C++-11 attribute specifier. */
29573
29574static bool
29575cp_next_tokens_can_be_std_attribute_p (cp_parser *parser)
29576{
29577 return cp_nth_tokens_can_be_std_attribute_p (parser, 1);
29578}
29579
29580/* Return TRUE iff the next Nth tokens in the stream are possibly the
29581 beginning of a standard C++-11 attribute specifier. */
29582
29583static bool
29584cp_nth_tokens_can_be_std_attribute_p (cp_parser *parser, size_t n)
29585{
29586 cp_token *token = cp_lexer_peek_nth_token (lexer: parser->lexer, n);
29587
29588 return (cxx_dialect >= cxx11
29589 && ((token->type == CPP_KEYWORD && token->keyword == RID_ALIGNAS)
29590 || (token->type == CPP_OPEN_SQUARE
29591 && (token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: n + 1))
29592 && token->type == CPP_OPEN_SQUARE)));
29593}
29594
29595/* Return TRUE iff the next Nth tokens in the stream are possibly the
29596 beginning of a GNU extension attribute. */
29597
29598static bool
29599cp_nth_tokens_can_be_gnu_attribute_p (cp_parser *parser, size_t n)
29600{
29601 cp_token *token = cp_lexer_peek_nth_token (lexer: parser->lexer, n);
29602
29603 return token->type == CPP_KEYWORD && token->keyword == RID_ATTRIBUTE;
29604}
29605
29606/* Return true iff the next tokens can be the beginning of either a
29607 GNU attribute list, or a standard C++11 attribute sequence. */
29608
29609static bool
29610cp_next_tokens_can_be_attribute_p (cp_parser *parser)
29611{
29612 return (cp_next_tokens_can_be_gnu_attribute_p (parser)
29613 || cp_next_tokens_can_be_std_attribute_p (parser));
29614}
29615
29616/* Return true iff the next Nth tokens can be the beginning of either
29617 a GNU attribute list, or a standard C++11 attribute sequence. */
29618
29619static bool
29620cp_nth_tokens_can_be_attribute_p (cp_parser *parser, size_t n)
29621{
29622 return (cp_nth_tokens_can_be_gnu_attribute_p (parser, n)
29623 || cp_nth_tokens_can_be_std_attribute_p (parser, n));
29624}
29625
29626/* Parse either a standard C++-11 attribute-specifier-seq, or a series
29627 of GNU attributes, or return NULL. */
29628
29629static tree
29630cp_parser_attributes_opt (cp_parser *parser)
29631{
29632 tree attrs = NULL_TREE;
29633 while (true)
29634 {
29635 if (cp_next_tokens_can_be_gnu_attribute_p (parser))
29636 attrs = attr_chainon (attrs, attr: cp_parser_gnu_attributes_opt (parser));
29637 else if (cp_next_tokens_can_be_std_attribute_p (parser))
29638 attrs = attr_chainon (attrs, attr: cp_parser_std_attribute_spec_seq (parser));
29639 else
29640 break;
29641 }
29642 return attrs;
29643}
29644
29645/* Parse an (optional) series of attributes.
29646
29647 attributes:
29648 attributes attribute
29649
29650 attribute:
29651 __attribute__ (( attribute-list [opt] ))
29652
29653 The return value is as for cp_parser_gnu_attribute_list. */
29654
29655static tree
29656cp_parser_gnu_attributes_opt (cp_parser* parser)
29657{
29658 tree attributes = NULL_TREE;
29659
29660 auto cleanup = make_temp_override
29661 (var&: parser->auto_is_implicit_function_template_parm_p, overrider: false);
29662
29663 while (true)
29664 {
29665 cp_token *token;
29666 tree attribute_list;
29667 bool ok = true;
29668
29669 /* Peek at the next token. */
29670 token = cp_lexer_peek_token (lexer: parser->lexer);
29671 /* If it's not `__attribute__', then we're done. */
29672 if (token->keyword != RID_ATTRIBUTE)
29673 break;
29674
29675 /* Consume the `__attribute__' keyword. */
29676 cp_lexer_consume_token (lexer: parser->lexer);
29677 /* Look for the two `(' tokens. */
29678 matching_parens outer_parens;
29679 if (!outer_parens.require_open (parser))
29680 ok = false;
29681 matching_parens inner_parens;
29682 if (!inner_parens.require_open (parser))
29683 ok = false;
29684
29685 /* Peek at the next token. */
29686 token = cp_lexer_peek_token (lexer: parser->lexer);
29687 if (token->type != CPP_CLOSE_PAREN)
29688 /* Parse the attribute-list. */
29689 attribute_list = cp_parser_gnu_attribute_list (parser);
29690 else
29691 /* If the next token is a `)', then there is no attribute
29692 list. */
29693 attribute_list = NULL;
29694
29695 /* Look for the two `)' tokens. */
29696 if (!inner_parens.require_close (parser))
29697 ok = false;
29698 if (!outer_parens.require_close (parser))
29699 ok = false;
29700 if (!ok)
29701 cp_parser_skip_to_end_of_statement (parser);
29702
29703 /* Add these new attributes to the list. */
29704 attributes = attr_chainon (attrs: attributes, attr: attribute_list);
29705 }
29706
29707 return attributes;
29708}
29709
29710/* Parse a GNU attribute-list.
29711
29712 attribute-list:
29713 attribute
29714 attribute-list , attribute
29715
29716 attribute:
29717 identifier
29718 identifier ( identifier )
29719 identifier ( identifier , expression-list )
29720 identifier ( expression-list )
29721
29722 Returns a TREE_LIST, or NULL_TREE on error. Each node corresponds
29723 to an attribute. The TREE_PURPOSE of each node is the identifier
29724 indicating which attribute is in use. The TREE_VALUE represents
29725 the arguments, if any. */
29726
29727static tree
29728cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
29729{
29730 tree attribute_list = NULL_TREE;
29731 bool save_translate_strings_p = parser->translate_strings_p;
29732
29733 /* Don't create wrapper nodes within attributes: the
29734 handlers don't know how to handle them. */
29735 auto_suppress_location_wrappers sentinel;
29736
29737 parser->translate_strings_p = false;
29738 while (true)
29739 {
29740 cp_token *token;
29741 tree identifier;
29742 tree attribute;
29743
29744 /* Look for the identifier. We also allow keywords here; for
29745 example `__attribute__ ((const))' is legal. */
29746 token = cp_lexer_peek_token (lexer: parser->lexer);
29747 if (token->type == CPP_NAME
29748 || token->type == CPP_KEYWORD)
29749 {
29750 tree arguments = NULL_TREE;
29751
29752 /* Consume the token, but save it since we need it for the
29753 SIMD enabled function parsing. */
29754 cp_token *id_token = cp_lexer_consume_token (lexer: parser->lexer);
29755
29756 /* Save away the identifier that indicates which attribute
29757 this is. */
29758 identifier = (token->type == CPP_KEYWORD)
29759 /* For keywords, use the canonical spelling, not the
29760 parsed identifier. */
29761 ? ridpointers[(int) token->keyword]
29762 : id_token->u.value;
29763
29764 identifier = canonicalize_attr_name (attr_name: identifier);
29765 attribute = build_tree_list (identifier, NULL_TREE);
29766
29767 /* Peek at the next token. */
29768 token = cp_lexer_peek_token (lexer: parser->lexer);
29769 /* If it's an `(', then parse the attribute arguments. */
29770 if (token->type == CPP_OPEN_PAREN)
29771 {
29772 vec<tree, va_gc> *vec;
29773 int attr_flag = (attribute_takes_identifier_p (identifier)
29774 ? id_attr : normal_attr);
29775 if (is_attribute_p (attr_name: "assume", ident: identifier))
29776 attr_flag = assume_attr;
29777 vec = cp_parser_parenthesized_expression_list
29778 (parser, is_attribute_list: attr_flag, /*cast_p=*/false,
29779 /*allow_expansion_p=*/false,
29780 /*non_constant_p=*/NULL);
29781 if (vec == NULL)
29782 arguments = error_mark_node;
29783 else
29784 {
29785 arguments = build_tree_list_vec (vec);
29786 release_tree_vector (vec);
29787 }
29788 /* Save the arguments away. */
29789 TREE_VALUE (attribute) = arguments;
29790 }
29791
29792 if (arguments != error_mark_node)
29793 {
29794 /* Add this attribute to the list. */
29795 TREE_CHAIN (attribute) = attribute_list;
29796 attribute_list = attribute;
29797 }
29798
29799 token = cp_lexer_peek_token (lexer: parser->lexer);
29800 }
29801 /* Unless EXACTLY_ONE is set look for more attributes.
29802 If the next token isn't a `,', we're done. */
29803 if (exactly_one || token->type != CPP_COMMA)
29804 break;
29805
29806 /* Consume the comma and keep going. */
29807 cp_lexer_consume_token (lexer: parser->lexer);
29808 }
29809 parser->translate_strings_p = save_translate_strings_p;
29810
29811 /* We built up the list in reverse order. */
29812 return nreverse (attribute_list);
29813}
29814
29815/* Parse arguments of omp::directive attribute.
29816
29817 ( directive-name ,[opt] clause-list[opt] )
29818
29819 For directive just remember the first/last tokens for subsequent
29820 parsing. */
29821
29822static void
29823cp_parser_omp_directive_args (cp_parser *parser, tree attribute, bool decl_p)
29824{
29825 cp_token *first = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
29826 if (first->type == CPP_CLOSE_PAREN)
29827 {
29828 cp_lexer_consume_token (lexer: parser->lexer);
29829 error_at (first->location, "expected OpenMP directive name");
29830 cp_lexer_consume_token (lexer: parser->lexer);
29831 TREE_VALUE (attribute) = NULL_TREE;
29832 return;
29833 }
29834 size_t n = cp_parser_skip_balanced_tokens (parser, 1);
29835 if (n == 1)
29836 {
29837 cp_lexer_consume_token (lexer: parser->lexer);
29838 error_at (first->location, "expected attribute argument as balanced "
29839 "token sequence");
29840 TREE_VALUE (attribute) = NULL_TREE;
29841 return;
29842 }
29843 for (n = n - 2; n; --n)
29844 cp_lexer_consume_token (lexer: parser->lexer);
29845 cp_token *last = cp_lexer_peek_token (lexer: parser->lexer);
29846 cp_lexer_consume_token (lexer: parser->lexer);
29847 tree arg = make_node (DEFERRED_PARSE);
29848 DEFPARSE_TOKENS (arg) = cp_token_cache_new (first, last);
29849 DEFPARSE_INSTANTIATIONS (arg) = nullptr;
29850 if (decl_p)
29851 TREE_PUBLIC (arg) = 1;
29852 TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
29853}
29854
29855/* Parse arguments of omp::sequence attribute.
29856
29857 ( omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... ) */
29858
29859static void
29860cp_parser_omp_sequence_args (cp_parser *parser, tree attribute)
29861{
29862 matching_parens parens;
29863 parens.consume_open (parser);
29864 do
29865 {
29866 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
29867 if (token->type == CPP_NAME
29868 && token->u.value == omp_identifier
29869 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_SCOPE))
29870 {
29871 cp_lexer_consume_token (lexer: parser->lexer);
29872 cp_lexer_consume_token (lexer: parser->lexer);
29873 token = cp_lexer_peek_token (lexer: parser->lexer);
29874 }
29875 bool directive = false;
29876 const char *p;
29877 if (token->type != CPP_NAME)
29878 p = "";
29879 else
29880 p = IDENTIFIER_POINTER (token->u.value);
29881 if (strcmp (s1: p, s2: "directive") == 0)
29882 directive = true;
29883 else if (strcmp (s1: p, s2: "sequence") != 0)
29884 {
29885 error_at (token->location, "expected %<directive%> or %<sequence%>");
29886 cp_parser_skip_to_closing_parenthesis (parser,
29887 /*recovering=*/true,
29888 /*or_comma=*/true,
29889 /*consume_paren=*/false);
29890 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
29891 break;
29892 cp_lexer_consume_token (lexer: parser->lexer);
29893 }
29894 cp_lexer_consume_token (lexer: parser->lexer);
29895 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_PAREN))
29896 cp_parser_required_error (parser, RT_OPEN_PAREN, false,
29897 UNKNOWN_LOCATION);
29898 else if (directive)
29899 cp_parser_omp_directive_args (parser, attribute, decl_p: false);
29900 else
29901 cp_parser_omp_sequence_args (parser, attribute);
29902 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
29903 break;
29904 cp_lexer_consume_token (lexer: parser->lexer);
29905 }
29906 while (1);
29907 if (!parens.require_close (parser))
29908 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false,
29909 /*consume_paren=*/true);
29910}
29911
29912/* Parse a standard C++11 attribute.
29913
29914 The returned representation is a TREE_LIST which TREE_PURPOSE is
29915 the scoped name of the attribute, and the TREE_VALUE is its
29916 arguments list.
29917
29918 Note that the scoped name of the attribute is itself a TREE_LIST
29919 which TREE_PURPOSE is the namespace of the attribute, and
29920 TREE_VALUE its name. This is unlike a GNU attribute -- as parsed
29921 by cp_parser_gnu_attribute_list -- that doesn't have any namespace
29922 and which TREE_PURPOSE is directly the attribute name.
29923
29924 Clients of the attribute code should use get_attribute_namespace
29925 and get_attribute_name to get the actual namespace and name of
29926 attributes, regardless of their being GNU or C++11 attributes.
29927
29928 attribute:
29929 attribute-token attribute-argument-clause [opt]
29930
29931 attribute-token:
29932 identifier
29933 attribute-scoped-token
29934
29935 attribute-scoped-token:
29936 attribute-namespace :: identifier
29937
29938 attribute-namespace:
29939 identifier
29940
29941 attribute-argument-clause:
29942 ( balanced-token-seq )
29943
29944 balanced-token-seq:
29945 balanced-token [opt]
29946 balanced-token-seq balanced-token
29947
29948 balanced-token:
29949 ( balanced-token-seq )
29950 [ balanced-token-seq ]
29951 { balanced-token-seq }. */
29952
29953static tree
29954cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
29955{
29956 tree attribute, attr_id = NULL_TREE, arguments;
29957 cp_token *token;
29958
29959 auto cleanup = make_temp_override
29960 (var&: parser->auto_is_implicit_function_template_parm_p, overrider: false);
29961
29962 /* First, parse name of the attribute, a.k.a attribute-token. */
29963
29964 token = cp_lexer_peek_token (lexer: parser->lexer);
29965 if (token->type == CPP_NAME)
29966 attr_id = token->u.value;
29967 else if (token->type == CPP_KEYWORD)
29968 attr_id = ridpointers[(int) token->keyword];
29969 else if (token->flags & NAMED_OP)
29970 attr_id = get_identifier (cpp_type2name (token->type, token->flags));
29971
29972 if (attr_id == NULL_TREE)
29973 return NULL_TREE;
29974
29975 cp_lexer_consume_token (lexer: parser->lexer);
29976
29977 token = cp_lexer_peek_token (lexer: parser->lexer);
29978 if (token->type == CPP_SCOPE)
29979 {
29980 /* We are seeing a scoped attribute token. */
29981
29982 cp_lexer_consume_token (lexer: parser->lexer);
29983 if (attr_ns)
29984 error_at (token->location, "attribute using prefix used together "
29985 "with scoped attribute token");
29986 attr_ns = attr_id;
29987
29988 token = cp_lexer_peek_token (lexer: parser->lexer);
29989 if (token->type == CPP_NAME)
29990 attr_id = token->u.value;
29991 else if (token->type == CPP_KEYWORD)
29992 attr_id = ridpointers[(int) token->keyword];
29993 else if (token->flags & NAMED_OP)
29994 attr_id = get_identifier (cpp_type2name (token->type, token->flags));
29995 else
29996 {
29997 error_at (token->location,
29998 "expected an identifier for the attribute name");
29999 return error_mark_node;
30000 }
30001 cp_lexer_consume_token (lexer: parser->lexer);
30002
30003 attr_ns = canonicalize_attr_name (attr_name: attr_ns);
30004 attr_id = canonicalize_attr_name (attr_name: attr_id);
30005 attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
30006 NULL_TREE);
30007 token = cp_lexer_peek_token (lexer: parser->lexer);
30008 }
30009 else if (attr_ns)
30010 {
30011 attr_ns = canonicalize_attr_name (attr_name: attr_ns);
30012 attr_id = canonicalize_attr_name (attr_name: attr_id);
30013 attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
30014 NULL_TREE);
30015 }
30016 else
30017 {
30018 attr_id = canonicalize_attr_name (attr_name: attr_id);
30019 attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id),
30020 NULL_TREE);
30021
30022 /* We used to treat C++11 noreturn attribute as equivalent to GNU's,
30023 but no longer: we have to be able to tell [[noreturn]] and
30024 __attribute__((noreturn)) apart. */
30025 /* C++14 deprecated attribute is equivalent to GNU's. */
30026 if (is_attribute_p (attr_name: "deprecated", ident: attr_id))
30027 TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
30028 /* C++17 fallthrough attribute is equivalent to GNU's. */
30029 else if (is_attribute_p (attr_name: "fallthrough", ident: attr_id))
30030 TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
30031 /* C++23 assume attribute is equivalent to GNU's. */
30032 else if (is_attribute_p (attr_name: "assume", ident: attr_id))
30033 TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
30034 /* Transactional Memory TS optimize_for_synchronized attribute is
30035 equivalent to GNU transaction_callable. */
30036 else if (is_attribute_p (attr_name: "optimize_for_synchronized", ident: attr_id))
30037 TREE_PURPOSE (attribute)
30038 = get_identifier ("transaction_callable");
30039 /* Transactional Memory attributes are GNU attributes. */
30040 else if (tm_attr_to_mask (attr_id))
30041 TREE_PURPOSE (attribute) = attr_id;
30042 }
30043
30044 /* Now parse the optional argument clause of the attribute. */
30045
30046 if (token->type != CPP_OPEN_PAREN)
30047 {
30048 if ((flag_openmp || flag_openmp_simd)
30049 && attr_ns == omp_identifier
30050 && (is_attribute_p (attr_name: "directive", ident: attr_id)
30051 || is_attribute_p (attr_name: "sequence", ident: attr_id)
30052 || is_attribute_p (attr_name: "decl", ident: attr_id)))
30053 {
30054 error_at (token->location, "%<omp::%E%> attribute requires argument",
30055 attr_id);
30056 return NULL_TREE;
30057 }
30058 return attribute;
30059 }
30060
30061 {
30062 vec<tree, va_gc> *vec;
30063 int attr_flag = normal_attr;
30064
30065 /* Maybe we don't expect to see any arguments for this attribute. */
30066 const attribute_spec *as
30067 = lookup_attribute_spec (TREE_PURPOSE (attribute));
30068 if (as && as->max_length == 0)
30069 {
30070 error_at (token->location, "%qE attribute does not take any arguments",
30071 attr_id);
30072 cp_parser_skip_to_closing_parenthesis (parser,
30073 /*recovering=*/true,
30074 /*or_comma=*/false,
30075 /*consume_paren=*/true);
30076 return error_mark_node;
30077 }
30078
30079 if (is_attribute_p (attr_name: "assume", ident: attr_id)
30080 && (attr_ns == NULL_TREE || attr_ns == gnu_identifier))
30081 /* The assume attribute needs special handling of the argument. */
30082 attr_flag = assume_attr;
30083 else if (attr_ns == gnu_identifier
30084 && attribute_takes_identifier_p (attr_id))
30085 /* A GNU attribute that takes an identifier in parameter. */
30086 attr_flag = id_attr;
30087 else if (attr_ns == NULL_TREE
30088 && cxx_dialect >= cxx26
30089 && (is_attribute_p (attr_name: "deprecated", ident: attr_id)
30090 || is_attribute_p (attr_name: "nodiscard", ident: attr_id)))
30091 attr_flag = uneval_string_attr;
30092
30093 /* If this is a fake attribute created to handle -Wno-attributes,
30094 we must skip parsing the arguments. */
30095 if (as == NULL || attribute_ignored_p (as))
30096 {
30097 if ((flag_openmp || flag_openmp_simd) && attr_ns == omp_identifier)
30098 {
30099 if (is_attribute_p (attr_name: "directive", ident: attr_id))
30100 {
30101 cp_parser_omp_directive_args (parser, attribute, decl_p: false);
30102 return attribute;
30103 }
30104 else if (is_attribute_p (attr_name: "decl", ident: attr_id))
30105 {
30106 TREE_VALUE (TREE_PURPOSE (attribute))
30107 = get_identifier ("directive");
30108 cp_parser_omp_directive_args (parser, attribute, decl_p: true);
30109 return attribute;
30110 }
30111 else if (is_attribute_p (attr_name: "sequence", ident: attr_id))
30112 {
30113 TREE_VALUE (TREE_PURPOSE (attribute))
30114 = get_identifier ("directive");
30115 cp_parser_omp_sequence_args (parser, attribute);
30116 TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
30117 return attribute;
30118 }
30119 }
30120
30121 /* For unknown attributes, just skip balanced tokens instead of
30122 trying to parse the arguments. Set TREE_VALUE (attribute) to
30123 error_mark_node to distinguish skipped arguments from attributes
30124 with no arguments. */
30125 for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; n; --n)
30126 cp_lexer_consume_token (lexer: parser->lexer);
30127 TREE_VALUE (attribute) = error_mark_node;
30128 return attribute;
30129 }
30130
30131 vec = cp_parser_parenthesized_expression_list
30132 (parser, is_attribute_list: attr_flag, /*cast_p=*/false,
30133 /*allow_expansion_p=*/true,
30134 /*non_constant_p=*/NULL);
30135 if (vec == NULL)
30136 arguments = error_mark_node;
30137 else
30138 {
30139 if (vec->is_empty ())
30140 /* e.g. [[attr()]]. */
30141 error_at (token->location, "parentheses must be omitted if "
30142 "%qE attribute argument list is empty",
30143 attr_id);
30144 arguments = build_tree_list_vec (vec);
30145 release_tree_vector (vec);
30146 }
30147
30148 if (arguments == error_mark_node)
30149 attribute = error_mark_node;
30150 else
30151 TREE_VALUE (attribute) = arguments;
30152 }
30153
30154 return attribute;
30155}
30156
30157/* Warn if the attribute ATTRIBUTE appears more than once in the
30158 attribute-list ATTRIBUTES. This used to be enforced for certain
30159 attributes, but the restriction was removed in P2156.
30160 LOC is the location of ATTRIBUTE. Returns true if ATTRIBUTE was not
30161 found in ATTRIBUTES. */
30162
30163static bool
30164cp_parser_check_std_attribute (location_t loc, tree attributes, tree attribute)
30165{
30166 static auto alist = { "noreturn", "deprecated", "nodiscard", "maybe_unused",
30167 "likely", "unlikely", "fallthrough",
30168 "no_unique_address", "carries_dependency" };
30169 if (attributes)
30170 for (const auto &a : alist)
30171 if (is_attribute_p (attr_name: a, ident: get_attribute_name (attribute))
30172 && is_attribute_namespace_p (attr_ns: "", attr: attribute)
30173 && lookup_attribute (attr_ns: "", attr_name: a, list: attributes))
30174 {
30175 if (!from_macro_expansion_at (loc))
30176 warning_at (loc, OPT_Wattributes, "attribute %qs specified "
30177 "multiple times", a);
30178 return false;
30179 }
30180 return true;
30181}
30182
30183/* Parse a list of standard C++-11 attributes.
30184
30185 attribute-list:
30186 attribute [opt]
30187 attribute-list , attribute[opt]
30188 attribute ...
30189 attribute-list , attribute ...
30190*/
30191
30192static tree
30193cp_parser_std_attribute_list (cp_parser *parser, tree attr_ns)
30194{
30195 tree attributes = NULL_TREE, attribute = NULL_TREE;
30196 cp_token *token = NULL;
30197
30198 while (true)
30199 {
30200 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
30201 attribute = cp_parser_std_attribute (parser, attr_ns);
30202 if (attribute == error_mark_node)
30203 break;
30204 if (attribute != NULL_TREE)
30205 {
30206 if (cp_parser_check_std_attribute (loc, attributes, attribute))
30207 {
30208 TREE_CHAIN (attribute) = attributes;
30209 attributes = attribute;
30210 }
30211 }
30212 token = cp_lexer_peek_token (lexer: parser->lexer);
30213 if (token->type == CPP_ELLIPSIS)
30214 {
30215 cp_lexer_consume_token (lexer: parser->lexer);
30216 if (attribute == NULL_TREE)
30217 error_at (token->location,
30218 "expected attribute before %<...%>");
30219 else if (TREE_VALUE (attribute) == NULL_TREE)
30220 {
30221 error_at (token->location, "attribute with no arguments "
30222 "contains no parameter packs");
30223 return error_mark_node;
30224 }
30225 else if (TREE_VALUE (attribute) != error_mark_node)
30226 {
30227 tree pack = make_pack_expansion (TREE_VALUE (attribute));
30228 if (pack == error_mark_node)
30229 return error_mark_node;
30230 TREE_VALUE (attribute) = pack;
30231 }
30232 token = cp_lexer_peek_token (lexer: parser->lexer);
30233 }
30234 if (token->type != CPP_COMMA)
30235 break;
30236 cp_lexer_consume_token (lexer: parser->lexer);
30237 }
30238 attributes = nreverse (attributes);
30239 return attributes;
30240}
30241
30242/* Optionally parse a C++20 contract role. A NULL return means that no
30243 contract role was specified.
30244
30245 contract-role:
30246 % default
30247 % identifier
30248
30249 If the identifier does not name a known contract role, it will
30250 be assumed to be default. Returns the identifier for the role
30251 token. */
30252
30253static tree
30254cp_parser_contract_role (cp_parser *parser)
30255{
30256 gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_MOD));
30257 cp_lexer_consume_token (lexer: parser->lexer);
30258
30259 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
30260 tree role_id = NULL_TREE;
30261 if (token->type == CPP_NAME)
30262 role_id = token->u.value;
30263 else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
30264 role_id = get_identifier ("default");
30265 else
30266 {
30267 error_at (token->location, "expected contract-role");
30268 return error_mark_node;
30269 }
30270 cp_lexer_consume_token (lexer: parser->lexer);
30271
30272 /* FIXME: Warn about invalid/unknown roles? */
30273 return role_id;
30274}
30275
30276/* Parse an optional contract mode.
30277
30278 contract-mode:
30279 contract-semantic
30280 [contract-level] [contract-role]
30281
30282 contract-semantic:
30283 check_never_continue
30284 check_maybe_continue
30285 check_always_continue
30286
30287 contract-level:
30288 default
30289 audit
30290 axiom
30291
30292 contract-role:
30293 default
30294 identifier
30295
30296 This grammar is taken from P1332R0. During parsing, this sets options
30297 on the MODE object to determine the configuration of the contract.
30298
30299 Returns a tree containing the identifiers used in the configuration.
30300 This is either an IDENTIFIER with the literal semantic or a TREE_LIST
30301 whose TREE_VALUE is the contract-level and whose TREE_PURPOSE is the
30302 contract-role, if any. NULL_TREE is returned if no information is
30303 given (i.e., all defaults selected). */
30304
30305static tree
30306cp_parser_contract_mode_opt (cp_parser *parser,
30307 bool postcondition_p)
30308{
30309 /* The mode is empty; the level and role are default. */
30310 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
30311 return NULL_TREE;
30312
30313 /* There is only a role; the level is default. */
30314 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MOD))
30315 {
30316 tree role_id = cp_parser_contract_role (parser);
30317 return build_tree_list (role_id, get_identifier ("default"));
30318 }
30319
30320 /* Otherwise, match semantic or level. */
30321 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
30322 contract_level level = CONTRACT_INVALID;
30323 contract_semantic semantic = CCS_INVALID;
30324 tree config_id;
30325 if (token->type == CPP_NAME)
30326 {
30327 config_id = token->u.value;
30328
30329 /* Either a named level, a concrete semantic, or an identifier
30330 for a postcondition. */
30331 const char *ident = IDENTIFIER_POINTER (token->u.value);
30332 level = map_contract_level (ident);
30333 semantic = map_contract_semantic (ident);
30334
30335 /* The identifier is the return value for a postcondition. */
30336 if (level == CONTRACT_INVALID && semantic == CCS_INVALID
30337 && postcondition_p)
30338 return NULL_TREE;
30339 }
30340 else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
30341 {
30342 config_id = get_identifier ("default");
30343 level = CONTRACT_DEFAULT;
30344 }
30345 else
30346 {
30347 /* We got some other token other than a ':'. */
30348 error_at (token->location, "expected contract semantic or level");
30349 return NULL_TREE;
30350 }
30351
30352 /* Consume the literal semantic or level token. */
30353 cp_lexer_consume_token (lexer: parser->lexer);
30354
30355 if (semantic == CCS_INVALID && level == CONTRACT_INVALID)
30356 {
30357 error_at (token->location,
30358 "expected contract level: "
30359 "%<default%>, %<audit%>, or %<axiom%>");
30360 return NULL_TREE;
30361 }
30362
30363 /* We matched an explicit semantic. */
30364 if (semantic != CCS_INVALID)
30365 {
30366 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MOD))
30367 {
30368 error ("invalid use of contract role for explicit semantic");
30369 cp_lexer_consume_token (lexer: parser->lexer);
30370 cp_lexer_consume_token (lexer: parser->lexer);
30371 }
30372 return config_id;
30373 }
30374
30375 /* We matched a level, there may be a role; otherwise this is default. */
30376 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MOD))
30377 {
30378 tree role_id = cp_parser_contract_role (parser);
30379 return build_tree_list (role_id, config_id);
30380 }
30381
30382 return build_tree_list (NULL_TREE, config_id);
30383}
30384
30385static tree
30386find_error (tree *tp, int *, void *)
30387{
30388 if (*tp == error_mark_node)
30389 return *tp;
30390 return NULL_TREE;
30391}
30392
30393static bool
30394contains_error_p (tree t)
30395{
30396 return walk_tree (&t, find_error, NULL, NULL);
30397}
30398
30399/* Parse a standard C++20 contract attribute specifier.
30400
30401 contract-attribute-specifier:
30402 [ [ assert contract-level [opt] : conditional-expression ] ]
30403 [ [ pre contract-level [opt] : conditional-expression ] ]
30404 [ [ post contract-level [opt] identifier [opt] : conditional-expression ] ]
30405
30406 For free functions, we cannot determine the type of the postcondition
30407 identifier because the we haven't called grokdeclarator yet. In those
30408 cases we parse the postcondition as if the identifier was declared as
30409 'auto <identifier>'. We then instantiate the postcondition once the
30410 return type is known.
30411
30412 For member functions, contracts are in the complete-class context, so the
30413 parse is deferred. We also have the return type avaialable (unless it's
30414 deduced), so we don't need to parse the postcondition in terms of a
30415 placeholder. */
30416
30417static tree
30418cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute)
30419{
30420 gcc_assert (contract_attribute_p (attribute));
30421 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
30422 location_t loc = token->location;
30423
30424 bool assertion_p = is_attribute_p (attr_name: "assert", ident: attribute);
30425 bool postcondition_p = is_attribute_p (attr_name: "post", ident: attribute);
30426
30427 /* Parse the optional mode. */
30428 tree mode = cp_parser_contract_mode_opt (parser, postcondition_p);
30429
30430 /* Check for postcondition identifiers. */
30431 cp_expr identifier;
30432 if (postcondition_p && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
30433 identifier = cp_parser_identifier (parser);
30434 if (identifier == error_mark_node)
30435 return error_mark_node;
30436
30437 cp_parser_require (parser, CPP_COLON, RT_COLON);
30438
30439 /* Defer the parsing of pre/post contracts inside class definitions. */
30440 tree contract;
30441 if (!assertion_p &&
30442 current_class_type &&
30443 TYPE_BEING_DEFINED (current_class_type))
30444 {
30445 /* Skip until we reach an unenclose ']'. If we ran into an unnested ']'
30446 that doesn't close the attribute, return an error and let the attribute
30447 handling code emit an error for missing ']]'. */
30448 cp_token *first = cp_lexer_peek_token (lexer: parser->lexer);
30449 cp_parser_skip_to_closing_parenthesis_1 (parser,
30450 /*recovering=*/false,
30451 or_ttype: CPP_CLOSE_SQUARE,
30452 /*consume_paren=*/false);
30453 if (cp_lexer_peek_token (lexer: parser->lexer)->type != CPP_CLOSE_SQUARE
30454 || cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type != CPP_CLOSE_SQUARE)
30455 return error_mark_node;
30456 cp_token *last = cp_lexer_peek_token (lexer: parser->lexer);
30457
30458 /* Build a deferred-parse node. */
30459 tree condition = make_node (DEFERRED_PARSE);
30460 DEFPARSE_TOKENS (condition) = cp_token_cache_new (first, last);
30461 DEFPARSE_INSTANTIATIONS (condition) = NULL;
30462
30463 /* And its corresponding contract. */
30464 contract = grok_contract (attribute, mode, identifier, condition, loc);
30465 }
30466 else
30467 {
30468 /* Enable location wrappers when parsing contracts. */
30469 auto suppression = make_temp_override (var&: suppress_location_wrappers, overrider: 0);
30470
30471 /* Build a fake variable for the result identifier. */
30472 tree result = NULL_TREE;
30473 if (identifier)
30474 {
30475 begin_scope (sk_block, NULL_TREE);
30476 result = make_postcondition_variable (identifier);
30477 ++processing_template_decl;
30478 }
30479
30480 /* Parse the condition, ensuring that parameters or the return variable
30481 aren't flagged for use outside the body of a function. */
30482 ++processing_contract_condition;
30483 cp_expr condition = cp_parser_conditional_expression (parser);
30484 --processing_contract_condition;
30485
30486 /* Try to recover from errors by scanning up to the end of the
30487 attribute. Sometimes we get partially parsed expressions, so
30488 we need to search the condition for errors. */
30489 if (contains_error_p (t: condition))
30490 cp_parser_skip_up_to_closing_square_bracket (parser);
30491
30492 /* Build the contract. */
30493 contract = grok_contract (attribute, mode, result, condition, loc);
30494
30495 /* Leave our temporary scope for the postcondition result. */
30496 if (result)
30497 {
30498 --processing_template_decl;
30499 pop_bindings_and_leave_scope ();
30500 }
30501 }
30502
30503 if (!flag_contracts)
30504 {
30505 error_at (loc, "contracts are only available with %<-fcontracts%>");
30506 return error_mark_node;
30507 }
30508
30509 return finish_contract_attribute (attribute, contract);
30510}
30511
30512/* Parse a contract condition for a deferred contract. */
30513
30514void cp_parser_late_contract_condition (cp_parser *parser,
30515 tree fn,
30516 tree attribute)
30517{
30518 tree contract = TREE_VALUE (TREE_VALUE (attribute));
30519
30520 /* Make sure we've gotten something that hasn't been parsed yet or that
30521 we're not parsing an invalid contract. */
30522 tree condition = CONTRACT_CONDITION (contract);
30523 if (TREE_CODE (condition) != DEFERRED_PARSE)
30524 return;
30525
30526 tree identifier = NULL_TREE;
30527 if (TREE_CODE (contract) == POSTCONDITION_STMT)
30528 identifier = POSTCONDITION_IDENTIFIER (contract);
30529
30530 /* Build a fake variable for the result identifier. */
30531 tree result = NULL_TREE;
30532 if (identifier)
30533 {
30534 /* TODO: Can we guarantee that the identifier has a location? */
30535 location_t loc = cp_expr_location (t_: contract);
30536 tree type = TREE_TYPE (TREE_TYPE (fn));
30537 if (!check_postcondition_result (fn, type, loc))
30538 {
30539 invalidate_contract (contract);
30540 return;
30541 }
30542
30543 begin_scope (sk_block, NULL_TREE);
30544 result = make_postcondition_variable (identifier, type);
30545 ++processing_template_decl;
30546 }
30547
30548 /* 'this' is not allowed in preconditions of constructors or in postconditions
30549 of destructors. Note that the previous value of this variable is
30550 established by the calling function, so we need to save it here. */
30551 tree saved_ccr = current_class_ref;
30552 tree saved_ccp = current_class_ptr;
30553 if ((DECL_CONSTRUCTOR_P (fn) && PRECONDITION_P (contract)) ||
30554 (DECL_DESTRUCTOR_P (fn) && POSTCONDITION_P (contract)))
30555 {
30556 current_class_ref = current_class_ptr = NULL_TREE;
30557 parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
30558 }
30559
30560 push_unparsed_function_queues (parser);
30561
30562 /* Push the saved tokens onto the parser's lexer stack. */
30563 cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
30564 cp_parser_push_lexer_for_tokens (parser, cache: tokens);
30565
30566 /* Parse the condition, ensuring that parameters or the return variable
30567 aren't flagged for use outside the body of a function. */
30568 ++processing_contract_condition;
30569 condition = cp_parser_conditional_expression (parser);
30570 --processing_contract_condition;
30571
30572 /* Revert to the main lexer. */
30573 cp_parser_pop_lexer (parser);
30574
30575 /* Restore the queue. */
30576 pop_unparsed_function_queues (parser);
30577
30578 current_class_ref = saved_ccr;
30579 current_class_ptr = saved_ccp;
30580
30581 /* Commit to changes. */
30582 update_late_contract (contract, result, condition);
30583
30584 /* Leave our temporary scope for the postcondition result. */
30585 if (result)
30586 {
30587 --processing_template_decl;
30588 pop_bindings_and_leave_scope ();
30589 }
30590}
30591
30592/* Parse a standard C++-11 attribute specifier.
30593
30594 attribute-specifier:
30595 [ [ attribute-using-prefix [opt] attribute-list ] ]
30596 contract-attribute-specifier
30597 alignment-specifier
30598
30599 attribute-using-prefix:
30600 using attribute-namespace :
30601
30602 alignment-specifier:
30603 alignas ( type-id ... [opt] )
30604 alignas ( alignment-expression ... [opt] ).
30605
30606 Extensions for contracts:
30607
30608 contract-attribute-specifier:
30609 [ [ assert : contract-mode [opt] : conditional-expression ] ]
30610 [ [ pre : contract-mode [opt] : conditional-expression ] ]
30611 [ [ post : contract-mode [opt] identifier [opt] :
30612 conditional-expression ] ]
30613
30614 Return void_list_node if the current token doesn't start an
30615 attribute-specifier to differentiate from NULL_TREE returned e.g.
30616 for [ [ ] ]. */
30617
30618static tree
30619cp_parser_std_attribute_spec (cp_parser *parser)
30620{
30621 tree attributes = NULL_TREE;
30622 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
30623
30624 if (token->type == CPP_OPEN_SQUARE
30625 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_OPEN_SQUARE)
30626 {
30627 tree attr_ns = NULL_TREE;
30628 tree attr_name = NULL_TREE;
30629
30630 cp_lexer_consume_token (lexer: parser->lexer);
30631 cp_lexer_consume_token (lexer: parser->lexer);
30632
30633 token = cp_lexer_peek_token (lexer: parser->lexer);
30634 if (token->type == CPP_NAME)
30635 {
30636 attr_name = token->u.value;
30637 attr_name = canonicalize_attr_name (attr_name);
30638 }
30639
30640 /* Handle contract-attribute-specs specially. */
30641 if (attr_name && contract_attribute_p (id: attr_name))
30642 {
30643 tree attrs = cp_parser_contract_attribute_spec (parser, attribute: attr_name);
30644 if (attrs != error_mark_node)
30645 attributes = attrs;
30646 goto finish_attrs;
30647 }
30648
30649 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_USING))
30650 {
30651 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
30652 if (token->type == CPP_NAME)
30653 attr_ns = token->u.value;
30654 else if (token->type == CPP_KEYWORD)
30655 attr_ns = ridpointers[(int) token->keyword];
30656 else if (token->flags & NAMED_OP)
30657 attr_ns = get_identifier (cpp_type2name (token->type,
30658 token->flags));
30659 if (attr_ns
30660 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_COLON))
30661 {
30662 if (cxx_dialect < cxx17)
30663 pedwarn (input_location, OPT_Wc__17_extensions,
30664 "attribute using prefix only available "
30665 "with %<-std=c++17%> or %<-std=gnu++17%>");
30666
30667 cp_lexer_consume_token (lexer: parser->lexer);
30668 cp_lexer_consume_token (lexer: parser->lexer);
30669 cp_lexer_consume_token (lexer: parser->lexer);
30670 }
30671 else
30672 attr_ns = NULL_TREE;
30673 }
30674
30675 attributes = cp_parser_std_attribute_list (parser, attr_ns);
30676
30677 finish_attrs:
30678 if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)
30679 || !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
30680 cp_parser_skip_to_end_of_statement (parser);
30681 else
30682 /* Warn about parsing c++11 attribute in non-c++11 mode, only
30683 when we are sure that we have actually parsed them. */
30684 maybe_warn_cpp0x (str: CPP0X_ATTRIBUTES);
30685 }
30686 else
30687 {
30688 tree alignas_expr;
30689
30690 /* Look for an alignment-specifier. */
30691
30692 token = cp_lexer_peek_token (lexer: parser->lexer);
30693
30694 if (token->type != CPP_KEYWORD
30695 || token->keyword != RID_ALIGNAS)
30696 return void_list_node;
30697
30698 cp_lexer_consume_token (lexer: parser->lexer);
30699 maybe_warn_cpp0x (str: CPP0X_ATTRIBUTES);
30700
30701 matching_parens parens;
30702 if (!parens.require_open (parser))
30703 return error_mark_node;
30704
30705 cp_parser_parse_tentatively (parser);
30706 alignas_expr = cp_parser_type_id (parser);
30707
30708 if (!cp_parser_parse_definitely (parser))
30709 {
30710 alignas_expr = cp_parser_assignment_expression (parser);
30711 if (alignas_expr == error_mark_node)
30712 cp_parser_skip_to_end_of_statement (parser);
30713 if (alignas_expr == NULL_TREE
30714 || alignas_expr == error_mark_node)
30715 return alignas_expr;
30716 }
30717
30718 alignas_expr = cxx_alignas_expr (alignas_expr);
30719 alignas_expr = build_tree_list (NULL_TREE, alignas_expr);
30720
30721 /* Handle alignas (pack...). */
30722 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
30723 {
30724 cp_lexer_consume_token (lexer: parser->lexer);
30725 alignas_expr = make_pack_expansion (alignas_expr);
30726 }
30727
30728 /* Something went wrong, so don't build the attribute. */
30729 if (alignas_expr == error_mark_node)
30730 return error_mark_node;
30731
30732 /* Missing ')' means the code cannot possibly be valid; go ahead
30733 and commit to make sure we issue a hard error. */
30734 if (cp_parser_uncommitted_to_tentative_parse_p (parser)
30735 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
30736 cp_parser_commit_to_tentative_parse (parser);
30737
30738 if (!parens.require_close (parser))
30739 return error_mark_node;
30740
30741 /* Build the C++-11 representation of an 'aligned'
30742 attribute. */
30743 attributes
30744 = build_tree_list (build_tree_list (gnu_identifier,
30745 aligned_identifier), alignas_expr);
30746 }
30747
30748 return attributes;
30749}
30750
30751/* Parse a standard C++-11 attribute-specifier-seq.
30752
30753 attribute-specifier-seq:
30754 attribute-specifier-seq [opt] attribute-specifier */
30755
30756static tree
30757cp_parser_std_attribute_spec_seq (cp_parser *parser)
30758{
30759 tree attr_specs = NULL_TREE;
30760 tree attr_last = NULL_TREE;
30761
30762 /* Don't create wrapper nodes within attributes: the
30763 handlers don't know how to handle them. */
30764 auto_suppress_location_wrappers sentinel;
30765
30766 while (true)
30767 {
30768 tree attr_spec = cp_parser_std_attribute_spec (parser);
30769 if (attr_spec == void_list_node)
30770 break;
30771 /* Accept [[]][[]]; for which cp_parser_std_attribute_spec
30772 returns NULL_TREE as there are no attributes. */
30773 if (attr_spec == NULL_TREE)
30774 continue;
30775 if (attr_spec == error_mark_node)
30776 return error_mark_node;
30777
30778 if (attr_last)
30779 TREE_CHAIN (attr_last) = attr_spec;
30780 else
30781 attr_specs = attr_last = attr_spec;
30782 attr_last = tree_last (attr_last);
30783 }
30784
30785 return attr_specs;
30786}
30787
30788/* Skip a balanced-token starting at Nth token (with 1 as the next token),
30789 return index of the first token after balanced-token, or N on failure. */
30790
30791static size_t
30792cp_parser_skip_balanced_tokens (cp_parser *parser, size_t n)
30793{
30794 size_t orig_n = n;
30795 int nparens = 0, nbraces = 0, nsquares = 0;
30796 do
30797 switch (cp_lexer_peek_nth_token (lexer: parser->lexer, n: n++)->type)
30798 {
30799 case CPP_PRAGMA_EOL:
30800 if (!parser->lexer->in_pragma)
30801 break;
30802 /* FALLTHRU */
30803 case CPP_EOF:
30804 /* Ran out of tokens. */
30805 return orig_n;
30806 case CPP_OPEN_PAREN:
30807 ++nparens;
30808 break;
30809 case CPP_OPEN_BRACE:
30810 ++nbraces;
30811 break;
30812 case CPP_OPEN_SQUARE:
30813 ++nsquares;
30814 break;
30815 case CPP_CLOSE_PAREN:
30816 --nparens;
30817 break;
30818 case CPP_CLOSE_BRACE:
30819 --nbraces;
30820 break;
30821 case CPP_CLOSE_SQUARE:
30822 --nsquares;
30823 break;
30824 default:
30825 break;
30826 }
30827 while (nparens || nbraces || nsquares);
30828 return n;
30829}
30830
30831/* Skip GNU attribute tokens starting at Nth token (with 1 as the next token),
30832 return index of the first token after the GNU attribute tokens, or N on
30833 failure. */
30834
30835static size_t
30836cp_parser_skip_gnu_attributes_opt (cp_parser *parser, size_t n)
30837{
30838 while (true)
30839 {
30840 if (!cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n, keyword: RID_ATTRIBUTE)
30841 || !cp_lexer_nth_token_is (lexer: parser->lexer, n: n + 1, type: CPP_OPEN_PAREN)
30842 || !cp_lexer_nth_token_is (lexer: parser->lexer, n: n + 2, type: CPP_OPEN_PAREN))
30843 break;
30844
30845 size_t n2 = cp_parser_skip_balanced_tokens (parser, n: n + 2);
30846 if (n2 == n + 2)
30847 break;
30848 if (!cp_lexer_nth_token_is (lexer: parser->lexer, n: n2, type: CPP_CLOSE_PAREN))
30849 break;
30850 n = n2 + 1;
30851 }
30852 return n;
30853}
30854
30855/* Skip standard C++11 attribute tokens starting at Nth token (with 1 as the
30856 next token), return index of the first token after the standard C++11
30857 attribute tokens, or N on failure. */
30858
30859static size_t
30860cp_parser_skip_std_attribute_spec_seq (cp_parser *parser, size_t n)
30861{
30862 while (true)
30863 {
30864 if (cp_lexer_nth_token_is (lexer: parser->lexer, n, type: CPP_OPEN_SQUARE)
30865 && cp_lexer_nth_token_is (lexer: parser->lexer, n: n + 1, type: CPP_OPEN_SQUARE))
30866 {
30867 size_t n2 = cp_parser_skip_balanced_tokens (parser, n: n + 1);
30868 if (n2 == n + 1)
30869 break;
30870 if (!cp_lexer_nth_token_is (lexer: parser->lexer, n: n2, type: CPP_CLOSE_SQUARE))
30871 break;
30872 n = n2 + 1;
30873 }
30874 else if (cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n, keyword: RID_ALIGNAS)
30875 && cp_lexer_nth_token_is (lexer: parser->lexer, n: n + 1, type: CPP_OPEN_PAREN))
30876 {
30877 size_t n2 = cp_parser_skip_balanced_tokens (parser, n: n + 1);
30878 if (n2 == n + 1)
30879 break;
30880 n = n2;
30881 }
30882 else
30883 break;
30884 }
30885 return n;
30886}
30887
30888/* Skip standard C++11 or GNU attribute tokens starting at Nth token (with 1
30889 as the next token), return index of the first token after the attribute
30890 tokens, or N on failure. */
30891
30892static size_t
30893cp_parser_skip_attributes_opt (cp_parser *parser, size_t n)
30894{
30895 if (cp_nth_tokens_can_be_gnu_attribute_p (parser, n))
30896 return cp_parser_skip_gnu_attributes_opt (parser, n);
30897 return cp_parser_skip_std_attribute_spec_seq (parser, n);
30898}
30899
30900/* Parse an optional `__extension__' keyword. Returns TRUE if it is
30901 present, and FALSE otherwise. *SAVED_PEDANTIC is set to the
30902 current value of the PEDANTIC flag, regardless of whether or not
30903 the `__extension__' keyword is present. The caller is responsible
30904 for restoring the value of the PEDANTIC flag. */
30905
30906static bool
30907cp_parser_extension_opt (cp_parser* parser, int* saved_pedantic)
30908{
30909 /* Save the old value of the PEDANTIC flag. */
30910 *saved_pedantic = pedantic;
30911
30912 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_EXTENSION))
30913 {
30914 /* Consume the `__extension__' token. */
30915 cp_lexer_consume_token (lexer: parser->lexer);
30916 /* We're not being pedantic while the `__extension__' keyword is
30917 in effect. */
30918 pedantic = 0;
30919
30920 return true;
30921 }
30922
30923 return false;
30924}
30925
30926/* Parse a label declaration.
30927
30928 label-declaration:
30929 __label__ label-declarator-seq ;
30930
30931 label-declarator-seq:
30932 identifier , label-declarator-seq
30933 identifier */
30934
30935static void
30936cp_parser_label_declaration (cp_parser* parser)
30937{
30938 /* Look for the `__label__' keyword. */
30939 cp_parser_require_keyword (parser, RID_LABEL, RT_LABEL);
30940
30941 while (true)
30942 {
30943 tree identifier;
30944
30945 /* Look for an identifier. */
30946 identifier = cp_parser_identifier (parser);
30947 /* If we failed, stop. */
30948 if (identifier == error_mark_node)
30949 break;
30950 /* Declare it as a label. */
30951 finish_label_decl (identifier);
30952 /* If the next token is a `;', stop. */
30953 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
30954 break;
30955 /* Look for the `,' separating the label declarations. */
30956 cp_parser_require (parser, CPP_COMMA, RT_COMMA);
30957 }
30958
30959 /* Look for the final `;'. */
30960 cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
30961}
30962
30963// -------------------------------------------------------------------------- //
30964// Concept definitions
30965
30966static tree
30967cp_parser_concept_definition (cp_parser *parser)
30968{
30969 /* A concept definition is an unevaluated context. */
30970 cp_unevaluated u;
30971
30972 gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT));
30973 cp_lexer_consume_token (lexer: parser->lexer);
30974
30975 cp_expr id = cp_parser_identifier (parser);
30976 if (id == error_mark_node)
30977 {
30978 cp_parser_skip_to_end_of_statement (parser);
30979 cp_parser_consume_semicolon_at_end_of_statement (parser);
30980 return NULL_TREE;
30981 }
30982
30983 tree attrs = cp_parser_attributes_opt (parser);
30984
30985 if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
30986 {
30987 cp_parser_skip_to_end_of_statement (parser);
30988 cp_parser_consume_semicolon_at_end_of_statement (parser);
30989 return error_mark_node;
30990 }
30991
30992 processing_constraint_expression_sentinel parsing_constraint;
30993 tree init = cp_parser_constraint_expression (parser);
30994 if (init == error_mark_node)
30995 cp_parser_skip_to_end_of_statement (parser);
30996
30997 /* Consume the trailing ';'. Diagnose the problem if it isn't there,
30998 but continue as if it were. */
30999 cp_parser_consume_semicolon_at_end_of_statement (parser);
31000
31001 return finish_concept_definition (id, init, attrs);
31002}
31003
31004// -------------------------------------------------------------------------- //
31005// Requires Clause
31006
31007/* Diagnose an expression that should appear in ()'s within a requires-clause
31008 and suggest where to place those parentheses. */
31009
31010static void
31011cp_parser_diagnose_ungrouped_constraint_plain (location_t loc)
31012{
31013 error_at (loc, "expression must be enclosed in parentheses");
31014}
31015
31016static void
31017cp_parser_diagnose_ungrouped_constraint_rich (location_t loc)
31018{
31019 gcc_rich_location richloc (loc);
31020 richloc.add_fixit_insert_before (new_content: "(");
31021 richloc.add_fixit_insert_after (new_content: ")");
31022 error_at (&richloc, "expression must be enclosed in parentheses");
31023}
31024
31025/* Characterizes the likely kind of expression intended by a mis-written
31026 primary constraint. */
31027enum primary_constraint_error
31028{
31029 pce_ok,
31030 pce_maybe_operator,
31031 pce_maybe_postfix
31032};
31033
31034/* Returns true if the token(s) following a primary-expression in a
31035 constraint-logical-* expression would require parentheses. */
31036
31037static primary_constraint_error
31038cp_parser_constraint_requires_parens (cp_parser *parser, bool lambda_p)
31039{
31040 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
31041 switch (token->type)
31042 {
31043 default:
31044 return pce_ok;
31045
31046 case CPP_EQ:
31047 {
31048 /* An equal sign may be part of the definition of a function,
31049 and not an assignment operator, when parsing the expression
31050 for a trailing requires-clause. For example:
31051
31052 template<typename T>
31053 struct S {
31054 S() requires C<T> = default;
31055 };
31056
31057 Don't try to reparse this a binary operator. */
31058 if (cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_DELETE)
31059 || cp_lexer_nth_token_is_keyword (lexer: parser->lexer, n: 2, keyword: RID_DEFAULT))
31060 return pce_ok;
31061
31062 gcc_fallthrough ();
31063 }
31064
31065 /* Arithmetic operators. */
31066 case CPP_PLUS:
31067 case CPP_MINUS:
31068 case CPP_MULT:
31069 case CPP_DIV:
31070 case CPP_MOD:
31071 /* Bitwise operators. */
31072 case CPP_AND:
31073 case CPP_OR:
31074 case CPP_XOR:
31075 case CPP_RSHIFT:
31076 case CPP_LSHIFT:
31077 /* Relational operators. */
31078 case CPP_EQ_EQ:
31079 case CPP_NOT_EQ:
31080 case CPP_LESS:
31081 case CPP_GREATER:
31082 case CPP_LESS_EQ:
31083 case CPP_GREATER_EQ:
31084 case CPP_SPACESHIP:
31085 /* Pointer-to-member. */
31086 case CPP_DOT_STAR:
31087 case CPP_DEREF_STAR:
31088 /* Assignment operators. */
31089 case CPP_PLUS_EQ:
31090 case CPP_MINUS_EQ:
31091 case CPP_MULT_EQ:
31092 case CPP_DIV_EQ:
31093 case CPP_MOD_EQ:
31094 case CPP_AND_EQ:
31095 case CPP_OR_EQ:
31096 case CPP_XOR_EQ:
31097 case CPP_RSHIFT_EQ:
31098 case CPP_LSHIFT_EQ:
31099 /* Conditional operator */
31100 case CPP_QUERY:
31101 /* Unenclosed binary or conditional operator. */
31102 return pce_maybe_operator;
31103
31104 case CPP_OPEN_PAREN:
31105 {
31106 /* A primary constraint that precedes the parameter-list of a
31107 lambda expression is followed by an open paren.
31108
31109 []<typename T> requires C (T a, T b) { ... }
31110
31111 Don't try to re-parse this as a postfix expression. */
31112 if (lambda_p)
31113 return pce_ok;
31114
31115 gcc_fallthrough ();
31116 }
31117 case CPP_OPEN_SQUARE:
31118 {
31119 /* A primary-constraint-expression followed by a '[[' is not a
31120 postfix expression. */
31121 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_SQUARE))
31122 return pce_ok;
31123
31124 gcc_fallthrough ();
31125 }
31126 case CPP_PLUS_PLUS:
31127 case CPP_MINUS_MINUS:
31128 case CPP_DOT:
31129 /* Unenclosed postfix operator. */
31130 return pce_maybe_postfix;
31131
31132 case CPP_DEREF:
31133 /* A primary constraint that precedes the lambda-declarator of a
31134 lambda expression is followed by trailing return type.
31135
31136 []<typename T> requires C -> void {}
31137
31138 Don't try to re-parse this as a postfix expression in
31139 C++23 and later. In C++20 ( needs to come in between but we
31140 allow it to be omitted with pedwarn. */
31141 if (lambda_p)
31142 return pce_ok;
31143 /* Unenclosed postfix operator. */
31144 return pce_maybe_postfix;
31145 }
31146}
31147
31148/* Returns true if the next token begins a unary expression, preceded by
31149 an operator or keyword. */
31150
31151static bool
31152cp_parser_unary_constraint_requires_parens (cp_parser *parser)
31153{
31154 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
31155 switch (token->type)
31156 {
31157 case CPP_NOT:
31158 case CPP_PLUS:
31159 case CPP_MINUS:
31160 case CPP_MULT:
31161 case CPP_COMPL:
31162 case CPP_PLUS_PLUS:
31163 case CPP_MINUS_MINUS:
31164 return true;
31165
31166 case CPP_KEYWORD:
31167 {
31168 switch (token->keyword)
31169 {
31170 case RID_STATCAST:
31171 case RID_DYNCAST:
31172 case RID_REINTCAST:
31173 case RID_CONSTCAST:
31174 case RID_TYPEID:
31175 case RID_SIZEOF:
31176 case RID_ALIGNOF:
31177 case RID_NOEXCEPT:
31178 case RID_NEW:
31179 case RID_DELETE:
31180 case RID_THROW:
31181 return true;
31182
31183 default:
31184 break;
31185 }
31186 }
31187
31188 default:
31189 break;
31190 }
31191
31192 return false;
31193}
31194
31195/* Parse a primary expression within a constraint. */
31196
31197static cp_expr
31198cp_parser_constraint_primary_expression (cp_parser *parser, bool lambda_p)
31199{
31200 /* If this looks like a unary expression, parse it as such, but diagnose
31201 it as ill-formed; it requires parens. */
31202 if (cp_parser_unary_constraint_requires_parens (parser))
31203 {
31204 cp_expr e = cp_parser_assignment_expression (parser, NULL, cast_p: false, decltype_p: false);
31205 cp_parser_diagnose_ungrouped_constraint_rich (loc: e.get_location());
31206 return e;
31207 }
31208
31209 cp_lexer_save_tokens (lexer: parser->lexer);
31210 cp_id_kind idk;
31211 location_t loc = input_location;
31212 cp_expr expr = cp_parser_primary_expression (parser,
31213 /*address_p=*/false,
31214 /*cast_p=*/false,
31215 /*template_arg_p=*/false,
31216 idk: &idk);
31217 expr.maybe_add_location_wrapper ();
31218
31219 primary_constraint_error pce = pce_ok;
31220 if (expr != error_mark_node)
31221 {
31222 /* The primary-expression could be part of an unenclosed non-logical
31223 compound expression. */
31224 pce = cp_parser_constraint_requires_parens (parser, lambda_p);
31225 }
31226 if (pce == pce_ok)
31227 {
31228 cp_lexer_commit_tokens (lexer: parser->lexer);
31229 return finish_constraint_primary_expr (expr);
31230 }
31231
31232 /* Retry the parse at a lower precedence. If that succeeds, diagnose the
31233 error, but return the expression as if it were valid. */
31234 cp_lexer_rollback_tokens (lexer: parser->lexer);
31235 cp_parser_parse_tentatively (parser);
31236 if (pce == pce_maybe_operator)
31237 expr = cp_parser_assignment_expression (parser, NULL, cast_p: false, decltype_p: false);
31238 else
31239 expr = cp_parser_simple_cast_expression (parser);
31240 if (cp_parser_parse_definitely (parser))
31241 {
31242 cp_parser_diagnose_ungrouped_constraint_rich (loc: expr.get_location());
31243 return expr;
31244 }
31245
31246 /* Otherwise, something has gone very wrong, and we can't generate a more
31247 meaningful diagnostic or recover. */
31248 cp_parser_diagnose_ungrouped_constraint_plain (loc);
31249 return error_mark_node;
31250}
31251
31252/* Parse a constraint-logical-and-expression.
31253
31254 constraint-logical-and-expression:
31255 primary-expression
31256 constraint-logical-and-expression '&&' primary-expression */
31257
31258static cp_expr
31259cp_parser_constraint_logical_and_expression (cp_parser *parser, bool lambda_p)
31260{
31261 cp_expr lhs = cp_parser_constraint_primary_expression (parser, lambda_p);
31262 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_AND_AND))
31263 {
31264 cp_token *op = cp_lexer_consume_token (lexer: parser->lexer);
31265 tree rhs = cp_parser_constraint_primary_expression (parser, lambda_p);
31266 lhs = finish_constraint_and_expr (op->location, lhs, rhs);
31267 }
31268 return lhs;
31269}
31270
31271/* Parse a constraint-logical-or-expression.
31272
31273 constraint-logical-or-expression:
31274 constraint-logical-and-expression
31275 constraint-logical-or-expression '||' constraint-logical-and-expression */
31276
31277static cp_expr
31278cp_parser_constraint_logical_or_expression (cp_parser *parser, bool lambda_p)
31279{
31280 cp_expr lhs = cp_parser_constraint_logical_and_expression (parser, lambda_p);
31281 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OR_OR))
31282 {
31283 cp_token *op = cp_lexer_consume_token (lexer: parser->lexer);
31284 cp_expr rhs = cp_parser_constraint_logical_and_expression (parser, lambda_p);
31285 lhs = finish_constraint_or_expr (op->location, lhs, rhs);
31286 }
31287 return lhs;
31288}
31289
31290/* Parse the expression after a requires-clause. This has a different grammar
31291 than that in the concepts TS. */
31292
31293static tree
31294cp_parser_requires_clause_expression (cp_parser *parser, bool lambda_p)
31295{
31296 processing_constraint_expression_sentinel parsing_constraint;
31297 ++processing_template_decl;
31298 cp_expr expr = cp_parser_constraint_logical_or_expression (parser, lambda_p);
31299 --processing_template_decl;
31300 if (check_for_bare_parameter_packs (expr))
31301 expr = error_mark_node;
31302 return expr;
31303}
31304
31305/* Parse a expression after a requires clause.
31306
31307 constraint-expression:
31308 logical-or-expression
31309
31310 The required logical-or-expression must be a constant expression. Note
31311 that we don't check that the expression is constepxr here. We defer until
31312 we analyze constraints and then, we only check atomic constraints. */
31313
31314static tree
31315cp_parser_constraint_expression (cp_parser *parser)
31316{
31317 processing_constraint_expression_sentinel parsing_constraint;
31318 ++processing_template_decl;
31319 cp_expr expr = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: true,
31320 prec: PREC_NOT_OPERATOR, NULL);
31321 --processing_template_decl;
31322 if (check_for_bare_parameter_packs (expr))
31323 expr = error_mark_node;
31324 expr.maybe_add_location_wrapper ();
31325 return expr;
31326}
31327
31328/* Optionally parse a requires clause:
31329
31330 requires-clause:
31331 `requires` constraint-logical-or-expression.
31332 [ConceptsTS]
31333 `requires constraint-expression.
31334
31335 LAMBDA_P is true when the requires-clause is parsed before the
31336 parameter-list of a lambda-declarator. */
31337
31338static tree
31339cp_parser_requires_clause_opt (cp_parser *parser, bool lambda_p)
31340{
31341 /* A requires clause is an unevaluated context. */
31342 cp_unevaluated u;
31343
31344 cp_token *tok = cp_lexer_peek_token (lexer: parser->lexer);
31345 if (tok->keyword != RID_REQUIRES)
31346 {
31347 if (!flag_concepts && tok->type == CPP_NAME
31348 && tok->u.value == ridpointers[RID_REQUIRES])
31349 {
31350 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
31351 "%<requires%> only available with "
31352 "%<-std=c++20%> or %<-fconcepts%>");
31353 /* Parse and discard the requires-clause. */
31354 cp_lexer_consume_token (lexer: parser->lexer);
31355 cp_parser_constraint_expression (parser);
31356 }
31357 return NULL_TREE;
31358 }
31359
31360 cp_token *tok2 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
31361 if (tok2->type == CPP_OPEN_BRACE)
31362 {
31363 /* An opening brace following the start of a requires-clause is
31364 ill-formed; the user likely forgot the second `requires' that
31365 would start a requires-expression. */
31366 gcc_rich_location richloc (tok2->location);
31367 richloc.add_fixit_insert_after (where: tok->location, new_content: " requires");
31368 error_at (&richloc, "missing additional %<requires%> to start "
31369 "a requires-expression");
31370 /* Don't consume the `requires', so that it's reused as the start of a
31371 requires-expression. */
31372 }
31373 else
31374 cp_lexer_consume_token (lexer: parser->lexer);
31375
31376 if (!flag_concepts_ts)
31377 return cp_parser_requires_clause_expression (parser, lambda_p);
31378 else
31379 return cp_parser_constraint_expression (parser);
31380}
31381
31382/*---------------------------------------------------------------------------
31383 Requires expressions
31384---------------------------------------------------------------------------*/
31385
31386/* Parse a requires expression
31387
31388 requirement-expression:
31389 'requires' requirement-parameter-list [opt] requirement-body */
31390
31391static tree
31392cp_parser_requires_expression (cp_parser *parser)
31393{
31394 gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES));
31395 location_t loc = cp_lexer_consume_token (lexer: parser->lexer)->location;
31396
31397 /* Avoid committing to outer tentative parse. */
31398 tentative_firewall firewall (parser);
31399
31400 /* This is definitely a requires-expression. */
31401 cp_parser_commit_to_tentative_parse (parser);
31402
31403 tree parms, reqs;
31404 {
31405 /* Local parameters are delared as variables within the scope
31406 of the expression. They are not visible past the end of
31407 the expression. Expressions within the requires-expression
31408 are unevaluated. */
31409 struct scope_sentinel
31410 {
31411 scope_sentinel ()
31412 {
31413 ++cp_unevaluated_operand;
31414 begin_scope (sk_function_parms, NULL_TREE);
31415 current_binding_level->requires_expression = true;
31416 }
31417
31418 ~scope_sentinel ()
31419 {
31420 pop_bindings_and_leave_scope ();
31421 --cp_unevaluated_operand;
31422 }
31423 } s;
31424
31425 /* Parse the optional parameter list. */
31426 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
31427 {
31428 parms = cp_parser_requirement_parameter_list (parser);
31429 if (parms == error_mark_node)
31430 return error_mark_node;
31431 }
31432 else
31433 parms = NULL_TREE;
31434
31435 /* Parse the requirement body. */
31436 ++processing_template_decl;
31437 reqs = cp_parser_requirement_body (parser);
31438 --processing_template_decl;
31439 if (reqs == error_mark_node)
31440 return error_mark_node;
31441 }
31442
31443 /* This needs to happen after pop_bindings_and_leave_scope, as it reverses
31444 the parm chain. */
31445 grokparms (parms, &parms);
31446 loc = make_location (caret: loc, start: loc, lexer: parser->lexer);
31447 tree expr = finish_requires_expr (loc, parms, reqs);
31448 if (!processing_template_decl)
31449 {
31450 /* Perform semantic processing now to diagnose any invalid types and
31451 expressions. */
31452 int saved_errorcount = errorcount;
31453 tsubst_requires_expr (expr, NULL_TREE, tf_warning_or_error, NULL_TREE);
31454 if (errorcount > saved_errorcount)
31455 return error_mark_node;
31456 }
31457 return expr;
31458}
31459
31460/* Parse a parameterized requirement.
31461
31462 requirement-parameter-list:
31463 '(' parameter-declaration-clause ')' */
31464
31465static tree
31466cp_parser_requirement_parameter_list (cp_parser *parser)
31467{
31468 matching_parens parens;
31469 if (!parens.require_open (parser))
31470 return error_mark_node;
31471
31472 tree parms = (cp_parser_parameter_declaration_clause
31473 (parser, flags: CP_PARSER_FLAGS_TYPENAME_OPTIONAL));
31474
31475 if (!parens.require_close (parser))
31476 return error_mark_node;
31477
31478 /* Modify the declared parameters by removing their context
31479 so they don't refer to the enclosing scope and explicitly
31480 indicating that they are constraint variables. */
31481 for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
31482 {
31483 if (parm == void_list_node || parm == explicit_void_list_node)
31484 break;
31485 tree decl = TREE_VALUE (parm);
31486 if (decl != error_mark_node)
31487 {
31488 DECL_CONTEXT (decl) = NULL_TREE;
31489 CONSTRAINT_VAR_P (decl) = true;
31490 }
31491 }
31492
31493 return parms;
31494}
31495
31496/* Parse the body of a requirement.
31497
31498 requirement-body:
31499 '{' requirement-list '}' */
31500static tree
31501cp_parser_requirement_body (cp_parser *parser)
31502{
31503 matching_braces braces;
31504 if (!braces.require_open (parser))
31505 return error_mark_node;
31506
31507 tree reqs = cp_parser_requirement_seq (parser);
31508
31509 if (!braces.require_close (parser))
31510 return error_mark_node;
31511
31512 return reqs;
31513}
31514
31515/* Parse a sequence of requirements.
31516
31517 requirement-seq:
31518 requirement
31519 requirement-seq requirement */
31520
31521static tree
31522cp_parser_requirement_seq (cp_parser *parser)
31523{
31524 tree result = NULL_TREE;
31525 do
31526 {
31527 tree req = cp_parser_requirement (parser);
31528 if (req != error_mark_node)
31529 result = tree_cons (NULL_TREE, req, result);
31530 }
31531 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_BRACE)
31532 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_EOF));
31533
31534 /* If there are no valid requirements, this is not a valid expression. */
31535 if (!result)
31536 return error_mark_node;
31537
31538 /* Reverse the order of requirements so they are analyzed in order. */
31539 return nreverse (result);
31540}
31541
31542/* Parse a syntactic requirement or type requirement.
31543
31544 requirement:
31545 simple-requirement
31546 compound-requirement
31547 type-requirement
31548 nested-requirement */
31549
31550static tree
31551cp_parser_requirement (cp_parser *parser)
31552{
31553 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
31554 return cp_parser_compound_requirement (parser);
31555 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TYPENAME))
31556 {
31557 /* It's probably a type-requirement. */
31558 cp_parser_parse_tentatively (parser);
31559 tree req = cp_parser_type_requirement (parser);
31560 if (cp_parser_parse_definitely (parser))
31561 return req;
31562 /* No, maybe it's something like typename T::type(); */
31563 cp_parser_parse_tentatively (parser);
31564 req = cp_parser_simple_requirement (parser);
31565 if (cp_parser_parse_definitely (parser))
31566 return req;
31567 /* Non-tentative for the error. */
31568 return cp_parser_type_requirement (parser);
31569 }
31570 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_REQUIRES))
31571 return cp_parser_nested_requirement (parser);
31572 else
31573 return cp_parser_simple_requirement (parser);
31574}
31575
31576/* Parse a simple requirement.
31577
31578 simple-requirement:
31579 expression ';' */
31580
31581static tree
31582cp_parser_simple_requirement (cp_parser *parser)
31583{
31584 location_t start = cp_lexer_peek_token (lexer: parser->lexer)->location;
31585 cp_expr expr = cp_parser_expression (parser, NULL, cast_p: false, decltype_p: false);
31586 if (expr == error_mark_node)
31587 cp_parser_skip_to_end_of_statement (parser);
31588
31589 cp_parser_consume_semicolon_at_end_of_statement (parser);
31590
31591 if (!expr || expr == error_mark_node)
31592 return error_mark_node;
31593
31594 /* Sometimes we don't get locations, so use the cached token location
31595 as a reasonable approximation. */
31596 if (expr.get_location() == UNKNOWN_LOCATION)
31597 expr.set_location (start);
31598
31599 for (tree t = expr; ; )
31600 {
31601 if (TREE_CODE (t) == TRUTH_ANDIF_EXPR
31602 || TREE_CODE (t) == TRUTH_ORIF_EXPR)
31603 {
31604 t = TREE_OPERAND (t, 0);
31605 continue;
31606 }
31607 if (concept_check_p (t))
31608 {
31609 gcc_rich_location richloc (get_start (loc: start));
31610 richloc.add_fixit_insert_before (where: start, new_content: "requires ");
31611 warning_at (&richloc, OPT_Wmissing_requires, "testing "
31612 "if a concept-id is a valid expression; add "
31613 "%<requires%> to check satisfaction");
31614 }
31615 break;
31616 }
31617
31618 return finish_simple_requirement (expr.get_location (), expr);
31619}
31620
31621/* Parse a type requirement
31622
31623 type-requirement
31624 nested-name-specifier [opt] required-type-name ';'
31625
31626 required-type-name:
31627 type-name
31628 'template' [opt] simple-template-id */
31629
31630static tree
31631cp_parser_type_requirement (cp_parser *parser)
31632{
31633 cp_token *start_tok = cp_lexer_consume_token (lexer: parser->lexer);
31634 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
31635
31636 // Save the scope before parsing name specifiers.
31637 tree saved_scope = parser->scope;
31638 tree saved_object_scope = parser->object_scope;
31639 tree saved_qualifying_scope = parser->qualifying_scope;
31640 cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
31641 cp_parser_nested_name_specifier_opt (parser,
31642 /*typename_keyword_p=*/true,
31643 /*check_dependency_p=*/true,
31644 /*type_p=*/true,
31645 /*is_declaration=*/false);
31646
31647 tree type;
31648 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TEMPLATE))
31649 {
31650 cp_lexer_consume_token (lexer: parser->lexer);
31651 type = cp_parser_template_id (parser,
31652 /*template_keyword_p=*/true,
31653 /*check_dependency_p=*/true,
31654 /*tag_type=*/none_type,
31655 /*is_declaration=*/false);
31656 type = make_typename_type (parser->scope, type, typename_type,
31657 /*complain=*/tf_error);
31658 }
31659 else
31660 type = cp_parser_type_name (parser, /*typename_keyword_p=*/true);
31661
31662 if (TREE_CODE (type) == TYPE_DECL)
31663 type = TREE_TYPE (type);
31664
31665 parser->scope = saved_scope;
31666 parser->object_scope = saved_object_scope;
31667 parser->qualifying_scope = saved_qualifying_scope;
31668
31669 if (type == error_mark_node)
31670 cp_parser_skip_to_end_of_statement (parser);
31671
31672 cp_parser_consume_semicolon_at_end_of_statement (parser);
31673
31674 if (type == error_mark_node)
31675 return error_mark_node;
31676
31677 loc = make_location (caret: loc, start: start_tok->location, lexer: parser->lexer);
31678 return finish_type_requirement (loc, type);
31679}
31680
31681/* Parse a compound requirement
31682
31683 compound-requirement:
31684 '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] ';' */
31685
31686static tree
31687cp_parser_compound_requirement (cp_parser *parser)
31688{
31689 /* Parse an expression enclosed in '{ }'s. */
31690 matching_braces braces;
31691 if (!braces.require_open (parser))
31692 return error_mark_node;
31693
31694 cp_token *expr_token = cp_lexer_peek_token (lexer: parser->lexer);
31695
31696 tree expr = cp_parser_expression (parser, NULL, cast_p: false, decltype_p: false);
31697 if (expr == error_mark_node)
31698 cp_parser_skip_to_closing_brace (parser);
31699
31700 if (!braces.require_close (parser))
31701 {
31702 cp_parser_skip_to_end_of_statement (parser);
31703 cp_parser_consume_semicolon_at_end_of_statement (parser);
31704 return error_mark_node;
31705 }
31706
31707 /* If the expression was invalid, skip the remainder of the requirement. */
31708 if (!expr || expr == error_mark_node)
31709 {
31710 cp_parser_skip_to_end_of_statement (parser);
31711 cp_parser_consume_semicolon_at_end_of_statement (parser);
31712 return error_mark_node;
31713 }
31714
31715 /* Parse the optional noexcept. */
31716 bool noexcept_p = false;
31717 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_NOEXCEPT))
31718 {
31719 cp_lexer_consume_token (lexer: parser->lexer);
31720 noexcept_p = true;
31721 }
31722
31723 /* Parse the optional trailing return type. */
31724 tree type = NULL_TREE;
31725 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DEREF))
31726 {
31727 cp_lexer_consume_token (lexer: parser->lexer);
31728 cp_token *tok = cp_lexer_peek_token (lexer: parser->lexer);
31729
31730 bool saved_result_type_constraint_p = parser->in_result_type_constraint_p;
31731 parser->in_result_type_constraint_p = true;
31732 /* C++20 allows either a type-id or a type-constraint. Parsing
31733 a type-id will subsume the parsing for a type-constraint but
31734 allow for more syntactic forms (e.g., const C<T>*). */
31735 type = cp_parser_trailing_type_id (parser);
31736 parser->in_result_type_constraint_p = saved_result_type_constraint_p;
31737 if (type == error_mark_node)
31738 return error_mark_node;
31739
31740 location_t type_loc = make_location (caret: tok->location, start: tok->location,
31741 lexer: parser->lexer);
31742
31743 /* Check that we haven't written something like 'const C<T>*'. */
31744 if (type_uses_auto (type))
31745 {
31746 if (!is_auto (type))
31747 {
31748 error_at (type_loc,
31749 "result type is not a plain type-constraint");
31750 cp_parser_consume_semicolon_at_end_of_statement (parser);
31751 return error_mark_node;
31752 }
31753 }
31754 else if (!flag_concepts_ts)
31755 /* P1452R2 removed the trailing-return-type option. */
31756 error_at (type_loc,
31757 "return-type-requirement is not a type-constraint");
31758 }
31759
31760 location_t loc = make_location (caret: expr_token->location,
31761 start: braces.open_location (),
31762 lexer: parser->lexer);
31763
31764 cp_parser_consume_semicolon_at_end_of_statement (parser);
31765
31766 if (expr == error_mark_node || type == error_mark_node)
31767 return error_mark_node;
31768
31769 return finish_compound_requirement (loc, expr, type, noexcept_p);
31770}
31771
31772/* Parse a nested requirement. This is the same as a requires clause.
31773
31774 nested-requirement:
31775 requires-clause */
31776
31777static tree
31778cp_parser_nested_requirement (cp_parser *parser)
31779{
31780 gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES));
31781 cp_token *tok = cp_lexer_consume_token (lexer: parser->lexer);
31782 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
31783 tree req = cp_parser_constraint_expression (parser);
31784 if (req == error_mark_node)
31785 cp_parser_skip_to_end_of_statement (parser);
31786 loc = make_location (caret: loc, start: tok->location, lexer: parser->lexer);
31787 cp_parser_consume_semicolon_at_end_of_statement (parser);
31788 if (req == error_mark_node)
31789 return error_mark_node;
31790 return finish_nested_requirement (loc, req);
31791}
31792
31793/* Support Functions */
31794
31795/* Return the appropriate prefer_type argument for lookup_name based on
31796 tag_type. */
31797
31798static inline LOOK_want
31799prefer_type_arg (tag_types tag_type)
31800{
31801 switch (tag_type)
31802 {
31803 case none_type: return LOOK_want::NORMAL; // No preference.
31804 case scope_type: return LOOK_want::TYPE_NAMESPACE; // Type or namespace.
31805 default: return LOOK_want::TYPE; // Type only.
31806 }
31807}
31808
31809/* Looks up NAME in the current scope, as given by PARSER->SCOPE.
31810 NAME should have one of the representations used for an
31811 id-expression. If NAME is the ERROR_MARK_NODE, the ERROR_MARK_NODE
31812 is returned. If PARSER->SCOPE is a dependent type, then a
31813 SCOPE_REF is returned.
31814
31815 If NAME is a TEMPLATE_ID_EXPR, then it will be immediately
31816 returned; the name was already resolved when the TEMPLATE_ID_EXPR
31817 was formed. Abstractly, such entities should not be passed to this
31818 function, because they do not need to be looked up, but it is
31819 simpler to check for this special case here, rather than at the
31820 call-sites.
31821
31822 In cases not explicitly covered above, this function returns a
31823 DECL, OVERLOAD, or baselink representing the result of the lookup.
31824 If there was no entity with the indicated NAME, the ERROR_MARK_NODE
31825 is returned.
31826
31827 If TAG_TYPE is not NONE_TYPE, it indicates an explicit type keyword
31828 (e.g., "struct") that was used. In that case bindings that do not
31829 refer to types are ignored.
31830
31831 If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
31832 ignored. If IS_TEMPLATE IS 2, the 'template' keyword was specified.
31833
31834 If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
31835 are ignored.
31836
31837 If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
31838 types.
31839
31840 If AMBIGUOUS_DECLS is non-NULL, *AMBIGUOUS_DECLS is set to a
31841 TREE_LIST of candidates if name-lookup results in an ambiguity, and
31842 NULL_TREE otherwise. */
31843
31844static cp_expr
31845cp_parser_lookup_name (cp_parser *parser, tree name,
31846 enum tag_types tag_type,
31847 int is_template,
31848 bool is_namespace,
31849 bool check_dependency,
31850 tree *ambiguous_decls,
31851 location_t name_location)
31852{
31853 tree decl;
31854 tree object_type = parser->context->object_type;
31855
31856 /* Assume that the lookup will be unambiguous. */
31857 if (ambiguous_decls)
31858 *ambiguous_decls = NULL_TREE;
31859
31860 /* Now that we have looked up the name, the OBJECT_TYPE (if any) is
31861 no longer valid. Note that if we are parsing tentatively, and
31862 the parse fails, OBJECT_TYPE will be automatically restored. */
31863 parser->context->object_type = NULL_TREE;
31864
31865 if (name == error_mark_node)
31866 return error_mark_node;
31867
31868 /* A template-id has already been resolved; there is no lookup to
31869 do. */
31870 if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
31871 return name;
31872 if (BASELINK_P (name))
31873 {
31874 gcc_assert (TREE_CODE (BASELINK_FUNCTIONS (name))
31875 == TEMPLATE_ID_EXPR);
31876 return name;
31877 }
31878
31879 /* A BIT_NOT_EXPR is used to represent a destructor. By this point,
31880 it should already have been checked to make sure that the name
31881 used matches the type being destroyed. */
31882 if (TREE_CODE (name) == BIT_NOT_EXPR)
31883 {
31884 tree type;
31885
31886 /* Figure out to which type this destructor applies. */
31887 if (parser->scope)
31888 type = parser->scope;
31889 else if (object_type)
31890 type = object_type;
31891 else
31892 type = current_class_type;
31893 /* If that's not a class type, there is no destructor. */
31894 if (!type || !CLASS_TYPE_P (type))
31895 return error_mark_node;
31896
31897 /* In a non-static member function, check implicit this->. */
31898 if (current_class_ref)
31899 return lookup_destructor (current_class_ref, parser->scope, name,
31900 tf_warning_or_error);
31901
31902 if (CLASSTYPE_LAZY_DESTRUCTOR (type))
31903 lazily_declare_fn (sfk_destructor, type);
31904
31905 if (tree dtor = CLASSTYPE_DESTRUCTOR (type))
31906 return dtor;
31907
31908 return error_mark_node;
31909 }
31910
31911 /* By this point, the NAME should be an ordinary identifier. If
31912 the id-expression was a qualified name, the qualifying scope is
31913 stored in PARSER->SCOPE at this point. */
31914 gcc_assert (identifier_p (name));
31915
31916 /* Perform the lookup. */
31917 if (parser->scope)
31918 {
31919 bool dependent_p;
31920
31921 if (parser->scope == error_mark_node)
31922 return error_mark_node;
31923
31924 /* If the SCOPE is dependent, the lookup must be deferred until
31925 the template is instantiated -- unless we are explicitly
31926 looking up names in uninstantiated templates. Even then, we
31927 cannot look up the name if the scope is not a class type; it
31928 might, for example, be a template type parameter. */
31929 dependent_p = (TYPE_P (parser->scope)
31930 && dependent_scope_p (parser->scope));
31931 if ((check_dependency || !CLASS_TYPE_P (parser->scope))
31932 && dependent_p)
31933 /* Defer lookup. */
31934 decl = error_mark_node;
31935 else
31936 {
31937 tree pushed_scope = NULL_TREE;
31938
31939 /* If PARSER->SCOPE is a dependent type, then it must be a
31940 class type, and we must not be checking dependencies;
31941 otherwise, we would have processed this lookup above. So
31942 that PARSER->SCOPE is not considered a dependent base by
31943 lookup_member, we must enter the scope here. */
31944 if (dependent_p)
31945 pushed_scope = push_scope (parser->scope);
31946
31947 /* If the PARSER->SCOPE is a template specialization, it
31948 may be instantiated during name lookup. In that case,
31949 errors may be issued. Even if we rollback the current
31950 tentative parse, those errors are valid. */
31951 decl = lookup_qualified_name (scope: parser->scope, name,
31952 prefer_type_arg (tag_type),
31953 /*complain=*/true);
31954
31955 /* 3.4.3.1: In a lookup in which the constructor is an acceptable
31956 lookup result and the nested-name-specifier nominates a class C:
31957 * if the name specified after the nested-name-specifier, when
31958 looked up in C, is the injected-class-name of C (Clause 9), or
31959 * if the name specified after the nested-name-specifier is the
31960 same as the identifier or the simple-template-id's template-
31961 name in the last component of the nested-name-specifier,
31962 the name is instead considered to name the constructor of
31963 class C. [ Note: for example, the constructor is not an
31964 acceptable lookup result in an elaborated-type-specifier so
31965 the constructor would not be used in place of the
31966 injected-class-name. --end note ] Such a constructor name
31967 shall be used only in the declarator-id of a declaration that
31968 names a constructor or in a using-declaration. */
31969 if (tag_type == none_type
31970 && DECL_SELF_REFERENCE_P (decl)
31971 && same_type_p (DECL_CONTEXT (decl), parser->scope))
31972 decl = lookup_qualified_name (scope: parser->scope, ctor_identifier,
31973 prefer_type_arg (tag_type),
31974 /*complain=*/true);
31975
31976 if (pushed_scope)
31977 pop_scope (pushed_scope);
31978 }
31979
31980 /* If the scope is a dependent type and either we deferred lookup or
31981 we did lookup but didn't find the name, rememeber the name. */
31982 if (decl == error_mark_node && TYPE_P (parser->scope)
31983 && dependent_type_p (parser->scope))
31984 {
31985 if (tag_type)
31986 {
31987 tree type;
31988
31989 /* The resolution to Core Issue 180 says that `struct
31990 A::B' should be considered a type-name, even if `A'
31991 is dependent. */
31992 type = make_typename_type (parser->scope, name, tag_type,
31993 /*complain=*/tf_error);
31994 if (type != error_mark_node)
31995 decl = TYPE_NAME (type);
31996 }
31997 else if (is_template
31998 && (cp_parser_next_token_ends_template_argument_p (parser)
31999 || cp_lexer_next_token_is (lexer: parser->lexer,
32000 type: CPP_CLOSE_PAREN)))
32001 decl = make_unbound_class_template (parser->scope,
32002 name, NULL_TREE,
32003 /*complain=*/tf_error);
32004 else
32005 decl = build_qualified_name (/*type=*/NULL_TREE,
32006 parser->scope, name,
32007 is_template);
32008 }
32009 parser->qualifying_scope = parser->scope;
32010 parser->object_scope = NULL_TREE;
32011 }
32012 else if (object_type)
32013 {
32014 bool dep = dependent_scope_p (object_type);
32015
32016 /* Look up the name in the scope of the OBJECT_TYPE, unless the
32017 OBJECT_TYPE is not a class. */
32018 if (!dep && CLASS_TYPE_P (object_type))
32019 /* If the OBJECT_TYPE is a template specialization, it may
32020 be instantiated during name lookup. In that case, errors
32021 may be issued. Even if we rollback the current tentative
32022 parse, those errors are valid. */
32023 decl = lookup_member (object_type,
32024 name,
32025 /*protect=*/0,
32026 /*prefer_type=*/tag_type != none_type,
32027 tf_warning_or_error);
32028 else
32029 decl = NULL_TREE;
32030
32031 /* If we didn't find a member and have dependent bases, the member lookup
32032 is now dependent. */
32033 if (!dep && !decl && any_dependent_bases_p (object_type))
32034 dep = true;
32035
32036 if (dep && is_template == 2)
32037 /* The template keyword specifies a dependent template. */;
32038 else if (!decl)
32039 /* Look it up in the enclosing context. DR 141: When looking for a
32040 template-name after -> or ., only consider class templates. */
32041 decl = lookup_name (name, want: is_namespace ? LOOK_want::NAMESPACE
32042 /* DR 141: When looking in the
32043 current enclosing context for a
32044 template-name after -> or ., only
32045 consider class templates. */
32046 : is_template ? LOOK_want::TYPE
32047 : prefer_type_arg (tag_type));
32048
32049 /* If we did unqualified lookup of a dependent member-qualified name and
32050 found something, do we want to use it? P1787 clarified that we need
32051 to look in the object scope first even if it's dependent, but for now
32052 let's still use it in some cases.
32053 FIXME remember unqualified lookup result to use if member lookup fails
32054 at instantiation time. */
32055 if (decl && dep && is_template)
32056 {
32057 saved_token_sentinel toks (parser->lexer, STS_ROLLBACK);
32058 /* Only use the unqualified class template lookup if we're actually
32059 looking at a template arg list. */
32060 if (!cp_parser_skip_entire_template_parameter_list (parser))
32061 decl = NULL_TREE;
32062 }
32063
32064 /* If we know we're looking for a type (e.g. A in p->A::x),
32065 mock up a typename. */
32066 if (!decl && dep && tag_type != none_type)
32067 {
32068 tree type = build_typename_type (object_type, name, name,
32069 typename_type);
32070 decl = TYPE_NAME (type);
32071 }
32072
32073 parser->object_scope = object_type;
32074 parser->qualifying_scope = NULL_TREE;
32075 }
32076 else
32077 {
32078 decl = lookup_name (name, want: is_namespace ? LOOK_want::NAMESPACE
32079 : prefer_type_arg (tag_type));
32080 parser->qualifying_scope = NULL_TREE;
32081 parser->object_scope = NULL_TREE;
32082 }
32083
32084 /* If the lookup failed, let our caller know. */
32085 if (!decl || decl == error_mark_node)
32086 return error_mark_node;
32087
32088 /* If we have resolved the name of a member declaration, check to
32089 see if the declaration is accessible. When the name resolves to
32090 set of overloaded functions, accessibility is checked when
32091 overload resolution is done. If we have a TREE_LIST, then the lookup
32092 is either ambiguous or it found multiple injected-class-names, the
32093 accessibility of which is trivially satisfied.
32094
32095 During an explicit instantiation, access is not checked at all,
32096 as per [temp.explicit]. */
32097 if (DECL_P (decl))
32098 check_accessibility_of_qualified_id (decl, object_type, parser->scope,
32099 tf_warning_or_error);
32100
32101 /* Pull out the template from an injected-class-name (or multiple). */
32102 if (is_template)
32103 decl = maybe_get_template_decl_from_type_decl (decl);
32104
32105 /* If it's a TREE_LIST, the result of the lookup was ambiguous. */
32106 if (TREE_CODE (decl) == TREE_LIST)
32107 {
32108 if (ambiguous_decls)
32109 *ambiguous_decls = decl;
32110 /* The error message we have to print is too complicated for
32111 cp_parser_error, so we incorporate its actions directly. */
32112 if (!cp_parser_simulate_error (parser))
32113 {
32114 error_at (name_location, "reference to %qD is ambiguous",
32115 name);
32116 print_candidates (decl);
32117 }
32118 return error_mark_node;
32119 }
32120
32121 gcc_assert (DECL_P (decl)
32122 || TREE_CODE (decl) == OVERLOAD
32123 || TREE_CODE (decl) == SCOPE_REF
32124 || TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE
32125 || BASELINK_P (decl));
32126
32127 maybe_record_typedef_use (decl);
32128
32129 return cp_expr (decl, name_location);
32130}
32131
32132/* Like cp_parser_lookup_name, but for use in the typical case where
32133 CHECK_ACCESS is TRUE, IS_TYPE is FALSE, IS_TEMPLATE is FALSE,
32134 IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */
32135
32136static tree
32137cp_parser_lookup_name_simple (cp_parser* parser, tree name, location_t location)
32138{
32139 return cp_parser_lookup_name (parser, name,
32140 tag_type: none_type,
32141 /*is_template=*/false,
32142 /*is_namespace=*/false,
32143 /*check_dependency=*/true,
32144 /*ambiguous_decls=*/NULL,
32145 name_location: location);
32146}
32147
32148/* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
32149 the current context, return the TYPE_DECL. If TAG_NAME_P is
32150 true, the DECL indicates the class being defined in a class-head,
32151 or declared in an elaborated-type-specifier.
32152
32153 Otherwise, return DECL. */
32154
32155static tree
32156cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
32157{
32158 /* If the TEMPLATE_DECL is being declared as part of a class-head,
32159 the translation from TEMPLATE_DECL to TYPE_DECL occurs:
32160
32161 struct A {
32162 template <typename T> struct B;
32163 };
32164
32165 template <typename T> struct A::B {};
32166
32167 Similarly, in an elaborated-type-specifier:
32168
32169 namespace N { struct X{}; }
32170
32171 struct A {
32172 template <typename T> friend struct N::X;
32173 };
32174
32175 However, if the DECL refers to a class type, and we are in
32176 the scope of the class, then the name lookup automatically
32177 finds the TYPE_DECL created by build_self_reference rather
32178 than a TEMPLATE_DECL. For example, in:
32179
32180 template <class T> struct S {
32181 S s;
32182 };
32183
32184 there is no need to handle such case. */
32185
32186 if (DECL_CLASS_TEMPLATE_P (decl) && tag_name_p)
32187 return DECL_TEMPLATE_RESULT (decl);
32188
32189 return decl;
32190}
32191
32192/* If too many, or too few, template-parameter lists apply to the
32193 declarator, issue an error message. Returns TRUE if all went well,
32194 and FALSE otherwise. */
32195
32196static bool
32197cp_parser_check_declarator_template_parameters (cp_parser* parser,
32198 cp_declarator *declarator,
32199 location_t declarator_location)
32200{
32201 switch (declarator->kind)
32202 {
32203 case cdk_id:
32204 {
32205 unsigned num_templates = 0;
32206 tree scope = declarator->u.id.qualifying_scope;
32207 bool template_id_p = false;
32208
32209 if (scope)
32210 num_templates = num_template_headers_for_class (scope);
32211 else if (TREE_CODE (declarator->u.id.unqualified_name)
32212 == TEMPLATE_ID_EXPR)
32213 {
32214 /* If the DECLARATOR has the form `X<y>' then it uses one
32215 additional level of template parameters. */
32216 ++num_templates;
32217 template_id_p = true;
32218 }
32219
32220 return cp_parser_check_template_parameters
32221 (parser, num_templates, template_id_p, declarator_location,
32222 declarator);
32223 }
32224
32225 case cdk_function:
32226 case cdk_array:
32227 case cdk_pointer:
32228 case cdk_reference:
32229 case cdk_ptrmem:
32230 return (cp_parser_check_declarator_template_parameters
32231 (parser, declarator: declarator->declarator, declarator_location));
32232
32233 case cdk_decomp:
32234 case cdk_error:
32235 return true;
32236
32237 default:
32238 gcc_unreachable ();
32239 }
32240 return false;
32241}
32242
32243/* NUM_TEMPLATES were used in the current declaration. If that is
32244 invalid, return FALSE and issue an error messages. Otherwise,
32245 return TRUE. If DECLARATOR is non-NULL, then we are checking a
32246 declarator and we can print more accurate diagnostics. */
32247
32248static bool
32249cp_parser_check_template_parameters (cp_parser* parser,
32250 unsigned num_templates,
32251 bool template_id_p,
32252 location_t location,
32253 cp_declarator *declarator)
32254{
32255 /* If there are the same number of template classes and parameter
32256 lists, that's OK. */
32257 if (parser->num_template_parameter_lists == num_templates)
32258 return true;
32259 /* If there are more, but only one more, and the name ends in an identifier,
32260 then we are declaring a primary template. That's OK too. */
32261 if (!template_id_p
32262 && parser->num_template_parameter_lists == num_templates + 1)
32263 return true;
32264
32265 if (cp_parser_simulate_error (parser))
32266 return false;
32267
32268 /* If there are more template classes than parameter lists, we have
32269 something like:
32270
32271 template <class T> void S<T>::R<T>::f (); */
32272 if (parser->num_template_parameter_lists < num_templates)
32273 {
32274 if (declarator && !current_function_decl)
32275 error_at (location, "specializing member %<%T::%E%> "
32276 "requires %<template<>%> syntax",
32277 declarator->u.id.qualifying_scope,
32278 declarator->u.id.unqualified_name);
32279 else if (declarator)
32280 error_at (location, "invalid declaration of %<%T::%E%>",
32281 declarator->u.id.qualifying_scope,
32282 declarator->u.id.unqualified_name);
32283 else
32284 error_at (location, "too few template-parameter-lists");
32285 return false;
32286 }
32287 /* Otherwise, there are too many template parameter lists. We have
32288 something like:
32289
32290 template <class T> template <class U> void S::f(); */
32291 error_at (location, "too many template-parameter-lists");
32292 return false;
32293}
32294
32295/* Parse an optional `::' token indicating that the following name is
32296 from the global namespace. If so, PARSER->SCOPE is set to the
32297 GLOBAL_NAMESPACE. Otherwise, PARSER->SCOPE is set to NULL_TREE,
32298 unless CURRENT_SCOPE_VALID_P is TRUE, in which case it is left alone.
32299 Returns the new value of PARSER->SCOPE, if the `::' token is
32300 present, and NULL_TREE otherwise. */
32301
32302static tree
32303cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
32304{
32305 cp_token *token;
32306
32307 /* Peek at the next token. */
32308 token = cp_lexer_peek_token (lexer: parser->lexer);
32309 /* If we're looking at a `::' token then we're starting from the
32310 global namespace, not our current location. */
32311 if (token->type == CPP_SCOPE)
32312 {
32313 /* Consume the `::' token. */
32314 cp_lexer_consume_token (lexer: parser->lexer);
32315 /* Set the SCOPE so that we know where to start the lookup. */
32316 parser->scope = global_namespace;
32317 parser->qualifying_scope = global_namespace;
32318 parser->object_scope = NULL_TREE;
32319
32320 return parser->scope;
32321 }
32322 else if (!current_scope_valid_p)
32323 {
32324 parser->scope = NULL_TREE;
32325 parser->qualifying_scope = NULL_TREE;
32326 parser->object_scope = NULL_TREE;
32327 }
32328
32329 return NULL_TREE;
32330}
32331
32332/* Returns TRUE if the upcoming token sequence is the start of a
32333 constructor declarator or C++17 deduction guide. If FRIEND_P is true, the
32334 declarator is preceded by the `friend' specifier. The parser flags FLAGS
32335 is used to control type-specifier parsing. */
32336
32337static bool
32338cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags,
32339 bool friend_p)
32340{
32341 bool constructor_p;
32342 bool outside_class_specifier_p;
32343 tree nested_name_specifier;
32344 cp_token *next_token;
32345
32346 /* The common case is that this is not a constructor declarator, so
32347 try to avoid doing lots of work if at all possible. It's not
32348 valid declare a constructor at function scope. */
32349 if (parser->in_function_body)
32350 return false;
32351 /* And only certain tokens can begin a constructor declarator. */
32352 next_token = cp_lexer_peek_token (lexer: parser->lexer);
32353 if (next_token->type != CPP_NAME
32354 && next_token->type != CPP_SCOPE
32355 && next_token->type != CPP_NESTED_NAME_SPECIFIER
32356 && next_token->type != CPP_TEMPLATE_ID)
32357 return false;
32358
32359 /* Parse tentatively; we are going to roll back all of the tokens
32360 consumed here. */
32361 cp_parser_parse_tentatively (parser);
32362 /* Assume that we are looking at a constructor declarator. */
32363 constructor_p = true;
32364
32365 /* Look for the optional `::' operator. */
32366 cp_parser_global_scope_opt (parser,
32367 /*current_scope_valid_p=*/false);
32368 /* Look for the nested-name-specifier. */
32369 nested_name_specifier
32370 = (cp_parser_nested_name_specifier_opt (parser,
32371 /*typename_keyword_p=*/false,
32372 /*check_dependency_p=*/false,
32373 /*type_p=*/false,
32374 /*is_declaration=*/false));
32375
32376 /* Resolve the TYPENAME_TYPE, because the call above didn't do it. */
32377 if (nested_name_specifier
32378 && TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
32379 {
32380 tree s = resolve_typename_type (nested_name_specifier,
32381 /*only_current_p=*/false);
32382 if (TREE_CODE (s) != TYPENAME_TYPE)
32383 nested_name_specifier = s;
32384 }
32385
32386 outside_class_specifier_p = (!at_class_scope_p ()
32387 || !TYPE_BEING_DEFINED (current_class_type)
32388 || friend_p);
32389
32390 /* Outside of a class-specifier, there must be a
32391 nested-name-specifier. Except in C++17 mode, where we
32392 might be declaring a guiding declaration. */
32393 if (!nested_name_specifier && outside_class_specifier_p
32394 && cxx_dialect < cxx17)
32395 constructor_p = false;
32396 else if (nested_name_specifier == error_mark_node)
32397 constructor_p = false;
32398
32399 /* If we have a class scope, this is easy; DR 147 says that S::S always
32400 names the constructor, and no other qualified name could. */
32401 if (constructor_p && nested_name_specifier
32402 && CLASS_TYPE_P (nested_name_specifier))
32403 {
32404 tree id = cp_parser_unqualified_id (parser,
32405 /*template_keyword_p=*/false,
32406 /*check_dependency_p=*/false,
32407 /*declarator_p=*/true,
32408 /*optional_p=*/false);
32409 if (is_overloaded_fn (id))
32410 id = DECL_NAME (get_first_fn (id));
32411 if (!constructor_name_p (id, nested_name_specifier))
32412 constructor_p = false;
32413 }
32414 /* If we still think that this might be a constructor-declarator,
32415 look for a class-name. */
32416 else if (constructor_p)
32417 {
32418 /* If we have:
32419
32420 template <typename T> struct S {
32421 S();
32422 };
32423
32424 we must recognize that the nested `S' names a class. */
32425 if (cxx_dialect >= cxx17)
32426 cp_parser_parse_tentatively (parser);
32427
32428 tree type_decl;
32429 type_decl = cp_parser_class_name (parser,
32430 /*typename_keyword_p=*/false,
32431 /*template_keyword_p=*/false,
32432 tag_type: none_type,
32433 /*check_dependency_p=*/false,
32434 /*class_head_p=*/false,
32435 /*is_declaration=*/false);
32436
32437 if (cxx_dialect >= cxx17
32438 && !cp_parser_parse_definitely (parser))
32439 {
32440 type_decl = NULL_TREE;
32441 tree tmpl = cp_parser_template_name (parser,
32442 /*template_keyword*/template_keyword_p: false,
32443 /*check_dependency_p*/false,
32444 /*is_declaration*/false,
32445 tag_type: none_type,
32446 /*is_identifier*/NULL);
32447 if (DECL_CLASS_TEMPLATE_P (tmpl)
32448 || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))
32449 /* It's a deduction guide, return true. */;
32450 else
32451 cp_parser_simulate_error (parser);
32452 }
32453
32454 /* If there was no class-name, then this is not a constructor.
32455 Otherwise, if we are in a class-specifier and we aren't
32456 handling a friend declaration, check that its type matches
32457 current_class_type (c++/38313). Note: error_mark_node
32458 is left alone for error recovery purposes. */
32459 constructor_p = (!cp_parser_error_occurred (parser)
32460 && (outside_class_specifier_p
32461 || type_decl == NULL_TREE
32462 || type_decl == error_mark_node
32463 || same_type_p (current_class_type,
32464 TREE_TYPE (type_decl))));
32465
32466 /* If we're still considering a constructor, we have to see a `(',
32467 to begin the parameter-declaration-clause, followed by either a
32468 `)', an `...', or a decl-specifier. We need to check for a
32469 type-specifier to avoid being fooled into thinking that:
32470
32471 S (f) (int);
32472
32473 is a constructor. (It is actually a function named `f' that
32474 takes one parameter (of type `int') and returns a value of type
32475 `S'. */
32476 if (constructor_p
32477 && !cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
32478 constructor_p = false;
32479
32480 if (constructor_p
32481 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN)
32482 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_ELLIPSIS)
32483 /* A parameter declaration begins with a decl-specifier,
32484 which is either the "attribute" keyword, a storage class
32485 specifier, or (usually) a type-specifier. */
32486 && !cp_lexer_next_token_is_decl_specifier_keyword (lexer: parser->lexer)
32487 /* GNU attributes can actually appear both at the start of
32488 a parameter and parenthesized declarator.
32489 S (__attribute__((unused)) int);
32490 is a constructor, but
32491 S (__attribute__((unused)) foo) (int);
32492 is a function declaration. [[attribute]] can appear in the
32493 first form too, but not in the second form. */
32494 && !cp_next_tokens_can_be_std_attribute_p (parser))
32495 {
32496 tree type;
32497 tree pushed_scope = NULL_TREE;
32498 unsigned saved_num_template_parameter_lists;
32499
32500 if (cp_parser_allow_gnu_extensions_p (parser)
32501 && cp_next_tokens_can_be_gnu_attribute_p (parser))
32502 {
32503 unsigned int n = cp_parser_skip_gnu_attributes_opt (parser, n: 1);
32504 while (--n)
32505 cp_lexer_consume_token (lexer: parser->lexer);
32506 }
32507
32508 /* Names appearing in the type-specifier should be looked up
32509 in the scope of the class. */
32510 if (current_class_type)
32511 type = NULL_TREE;
32512 else if (type_decl)
32513 {
32514 type = TREE_TYPE (type_decl);
32515 if (TREE_CODE (type) == TYPENAME_TYPE)
32516 {
32517 type = resolve_typename_type (type,
32518 /*only_current_p=*/false);
32519 if (TREE_CODE (type) == TYPENAME_TYPE)
32520 {
32521 cp_parser_abort_tentative_parse (parser);
32522 return false;
32523 }
32524 }
32525 pushed_scope = push_scope (type);
32526 }
32527
32528 /* Inside the constructor parameter list, surrounding
32529 template-parameter-lists do not apply. */
32530 saved_num_template_parameter_lists
32531 = parser->num_template_parameter_lists;
32532 parser->num_template_parameter_lists = 0;
32533
32534 /* Look for the type-specifier. It's not optional, but its typename
32535 might be. Unless this is a friend declaration; we don't want to
32536 treat
32537
32538 friend S (T::fn)(int);
32539
32540 as a constructor, but with P0634, we might assume a type when
32541 looking for the type-specifier. It is actually a function named
32542 `T::fn' that takes one parameter (of type `int') and returns a
32543 value of type `S'. Constructors can be friends, but they must
32544 use a qualified name.
32545
32546 Parse with an empty set of declaration specifiers since we're
32547 trying to match a decl-specifier-seq of the first parameter.
32548 This must be non-null so that cp_parser_simple_type_specifier
32549 will recognize a constrained placeholder type such as:
32550 'C<int> auto' where C is a type concept. */
32551 cp_decl_specifier_seq ctor_specs;
32552 clear_decl_specs (decl_specs: &ctor_specs);
32553 cp_parser_type_specifier (parser,
32554 flags: (friend_p ? CP_PARSER_FLAGS_NONE
32555 : (flags & ~CP_PARSER_FLAGS_OPTIONAL)),
32556 /*decl_specs=*/&ctor_specs,
32557 /*is_declarator=*/is_declaration: true,
32558 /*declares_class_or_enum=*/NULL,
32559 /*is_cv_qualifier=*/NULL);
32560
32561 parser->num_template_parameter_lists
32562 = saved_num_template_parameter_lists;
32563
32564 /* Leave the scope of the class. */
32565 if (pushed_scope)
32566 pop_scope (pushed_scope);
32567
32568 constructor_p = !cp_parser_error_occurred (parser);
32569 }
32570 }
32571
32572 /* We did not really want to consume any tokens. */
32573 cp_parser_abort_tentative_parse (parser);
32574
32575 /* DR 2237 (C++20 only): A simple-template-id is no longer valid as the
32576 declarator-id of a constructor or destructor. */
32577 if (constructor_p
32578 && cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_TEMPLATE_ID)
32579 {
32580 auto_diagnostic_group d;
32581 if (emit_diagnostic (cxx_dialect >= cxx20 ? DK_PEDWARN : DK_WARNING,
32582 input_location, OPT_Wtemplate_id_cdtor,
32583 "template-id not allowed for constructor in C++20"))
32584 inform (input_location, "remove the %qs", "< >");
32585 }
32586
32587 return constructor_p;
32588}
32589
32590/* Parse the definition of the function given by the DECL_SPECIFIERS,
32591 ATTRIBUTES, and DECLARATOR. The access checks have been deferred;
32592 they must be performed once we are in the scope of the function.
32593
32594 Returns the function defined. */
32595
32596static tree
32597cp_parser_function_definition_from_specifiers_and_declarator
32598 (cp_parser* parser,
32599 cp_decl_specifier_seq *decl_specifiers,
32600 tree attributes,
32601 const cp_declarator *declarator)
32602{
32603 tree fn;
32604 bool success_p;
32605
32606 /* Begin the function-definition. */
32607 success_p = start_function (decl_specifiers, declarator, attributes);
32608
32609 /* The things we're about to see are not directly qualified by any
32610 template headers we've seen thus far. */
32611 reset_specialization ();
32612
32613 /* If there were names looked up in the decl-specifier-seq that we
32614 did not check, check them now. We must wait until we are in the
32615 scope of the function to perform the checks, since the function
32616 might be a friend. */
32617 perform_deferred_access_checks (tf_warning_or_error);
32618
32619 if (success_p)
32620 {
32621 cp_finalize_omp_declare_simd (parser, fndecl: current_function_decl);
32622 parser->omp_declare_simd = NULL;
32623 cp_finalize_oacc_routine (parser, current_function_decl, true);
32624 parser->oacc_routine = NULL;
32625 }
32626
32627 if (!success_p)
32628 {
32629 /* Skip the entire function. */
32630 cp_parser_skip_to_end_of_block_or_statement (parser);
32631 fn = error_mark_node;
32632 }
32633 else if (DECL_INITIAL (current_function_decl) != error_mark_node)
32634 {
32635 /* Seen already, skip it. An error message has already been output. */
32636 cp_parser_skip_to_end_of_block_or_statement (parser);
32637 fn = current_function_decl;
32638 current_function_decl = NULL_TREE;
32639 /* If this is a function from a class, pop the nested class. */
32640 if (current_class_name)
32641 pop_nested_class ();
32642 }
32643 else
32644 {
32645 auto_timevar tv (DECL_DECLARED_INLINE_P (current_function_decl)
32646 ? TV_PARSE_INLINE : TV_PARSE_FUNC);
32647 fn = cp_parser_function_definition_after_declarator (parser,
32648 /*inline_p=*/false);
32649 }
32650
32651 return fn;
32652}
32653
32654/* Parse the part of a function-definition that follows the
32655 declarator. INLINE_P is TRUE iff this function is an inline
32656 function defined within a class-specifier.
32657
32658 Returns the function defined. */
32659
32660static tree
32661cp_parser_function_definition_after_declarator (cp_parser* parser,
32662 bool inline_p)
32663{
32664 tree fn;
32665 bool saved_in_unbraced_linkage_specification_p;
32666 bool saved_in_function_body;
32667 unsigned saved_num_template_parameter_lists;
32668 cp_token *token;
32669 bool fully_implicit_function_template_p
32670 = parser->fully_implicit_function_template_p;
32671 parser->fully_implicit_function_template_p = false;
32672 tree implicit_template_parms
32673 = parser->implicit_template_parms;
32674 parser->implicit_template_parms = 0;
32675 cp_binding_level* implicit_template_scope
32676 = parser->implicit_template_scope;
32677 parser->implicit_template_scope = 0;
32678
32679 saved_in_function_body = parser->in_function_body;
32680 parser->in_function_body = true;
32681 /* If the next token is `return', then the code may be trying to
32682 make use of the "named return value" extension that G++ used to
32683 support. */
32684 token = cp_lexer_peek_token (lexer: parser->lexer);
32685 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_RETURN))
32686 {
32687 /* Consume the `return' keyword. */
32688 cp_lexer_consume_token (lexer: parser->lexer);
32689 /* Look for the identifier that indicates what value is to be
32690 returned. */
32691 cp_parser_identifier (parser);
32692 /* Issue an error message. */
32693 error_at (token->location,
32694 "named return values are no longer supported");
32695 /* Skip tokens until we reach the start of the function body. */
32696 while (true)
32697 {
32698 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
32699 if (token->type == CPP_OPEN_BRACE
32700 || token->type == CPP_EOF
32701 || token->type == CPP_PRAGMA_EOL)
32702 break;
32703 cp_lexer_consume_token (lexer: parser->lexer);
32704 }
32705 }
32706 /* The `extern' in `extern "C" void f () { ... }' does not apply to
32707 anything declared inside `f'. */
32708 saved_in_unbraced_linkage_specification_p
32709 = parser->in_unbraced_linkage_specification_p;
32710 parser->in_unbraced_linkage_specification_p = false;
32711 /* Inside the function, surrounding template-parameter-lists do not
32712 apply. */
32713 saved_num_template_parameter_lists
32714 = parser->num_template_parameter_lists;
32715 parser->num_template_parameter_lists = 0;
32716
32717 /* If the next token is `try', `__transaction_atomic', or
32718 `__transaction_relaxed`, then we are looking at either function-try-block
32719 or function-transaction-block. Note that all of these include the
32720 function-body. */
32721 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TRANSACTION_ATOMIC))
32722 cp_parser_function_transaction (parser, RID_TRANSACTION_ATOMIC);
32723 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer,
32724 keyword: RID_TRANSACTION_RELAXED))
32725 cp_parser_function_transaction (parser, RID_TRANSACTION_RELAXED);
32726 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TRY))
32727 cp_parser_function_try_block (parser);
32728 else
32729 cp_parser_ctor_initializer_opt_and_function_body
32730 (parser, /*in_function_try_block=*/false);
32731
32732 /* Finish the function. */
32733 fn = finish_function (inline_p);
32734
32735 if (modules_p ()
32736 && !inline_p
32737 && TYPE_P (DECL_CONTEXT (fn))
32738 && (DECL_DECLARED_INLINE_P (fn)
32739 || processing_template_decl))
32740 set_defining_module (fn);
32741
32742 /* Generate code for it, if necessary. */
32743 expand_or_defer_fn (fn);
32744
32745 /* Restore the saved values. */
32746 parser->in_unbraced_linkage_specification_p
32747 = saved_in_unbraced_linkage_specification_p;
32748 parser->num_template_parameter_lists
32749 = saved_num_template_parameter_lists;
32750 parser->in_function_body = saved_in_function_body;
32751
32752 parser->fully_implicit_function_template_p
32753 = fully_implicit_function_template_p;
32754 parser->implicit_template_parms
32755 = implicit_template_parms;
32756 parser->implicit_template_scope
32757 = implicit_template_scope;
32758
32759 if (parser->fully_implicit_function_template_p)
32760 finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
32761
32762 return fn;
32763}
32764
32765/* Parse a template-declaration body (following argument list). */
32766
32767static void
32768cp_parser_template_declaration_after_parameters (cp_parser* parser,
32769 tree parameter_list,
32770 bool member_p)
32771{
32772 tree decl = NULL_TREE;
32773 bool friend_p = false;
32774
32775 /* We just processed one more parameter list. */
32776 ++parser->num_template_parameter_lists;
32777
32778 /* Get the deferred access checks from the parameter list. These
32779 will be checked once we know what is being declared, as for a
32780 member template the checks must be performed in the scope of the
32781 class containing the member. */
32782 vec<deferred_access_check, va_gc> *checks = get_deferred_access_checks ();
32783
32784 /* Tentatively parse for a new template parameter list, which can either be
32785 the template keyword or a template introduction. */
32786 if (cp_parser_template_declaration_after_export (parser, member_p))
32787 /* OK */;
32788 else if (cxx_dialect >= cxx11
32789 && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_USING))
32790 decl = cp_parser_alias_declaration (parser);
32791 else if (flag_concepts
32792 && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_CONCEPT)
32793 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
32794 /* -fconcept-ts 'concept bool' syntax is handled below, in
32795 cp_parser_single_declaration. */
32796 decl = cp_parser_concept_definition (parser);
32797 else
32798 {
32799 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
32800 decl = cp_parser_single_declaration (parser,
32801 checks,
32802 member_p,
32803 /*explicit_specialization_p=*/false,
32804 &friend_p);
32805
32806 /* If this is a member template declaration, let the front
32807 end know. */
32808 if (member_p && !friend_p && decl)
32809 {
32810 if (TREE_CODE (decl) == TYPE_DECL)
32811 cp_parser_check_access_in_redeclaration (type: decl, location: token->location);
32812
32813 decl = finish_member_template_decl (decl);
32814 }
32815 else if (friend_p && decl
32816 && DECL_DECLARES_TYPE_P (decl))
32817 make_friend_class (current_class_type, TREE_TYPE (decl),
32818 /*complain=*/true);
32819 }
32820 /* We are done with the current parameter list. */
32821 --parser->num_template_parameter_lists;
32822
32823 pop_deferring_access_checks ();
32824
32825 /* Finish up. */
32826 finish_template_decl (parameter_list);
32827
32828 /* Check the template arguments for a literal operator template. */
32829 if (decl
32830 && DECL_DECLARES_FUNCTION_P (decl)
32831 && UDLIT_OPER_P (DECL_NAME (decl)))
32832 {
32833 bool ok = true;
32834 if (parameter_list == NULL_TREE)
32835 ok = false;
32836 else
32837 {
32838 int num_parms = TREE_VEC_LENGTH (parameter_list);
32839 if (num_parms == 1)
32840 {
32841 tree parm_list = TREE_VEC_ELT (parameter_list, 0);
32842 tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
32843 if (TREE_CODE (parm) != PARM_DECL)
32844 ok = false;
32845 else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (parm))
32846 && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
32847 /* OK, C++20 string literal operator template. We don't need
32848 to warn in lower dialects here because we will have already
32849 warned about the template parameter. */;
32850 else if (TREE_TYPE (parm) != char_type_node
32851 || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
32852 ok = false;
32853 }
32854 else if (num_parms == 2 && cxx_dialect >= cxx14)
32855 {
32856 tree parm_type = TREE_VEC_ELT (parameter_list, 0);
32857 tree type = INNERMOST_TEMPLATE_PARMS (parm_type);
32858 tree parm_list = TREE_VEC_ELT (parameter_list, 1);
32859 tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
32860 if (TREE_CODE (parm) != PARM_DECL
32861 || TREE_TYPE (parm) != TREE_TYPE (type)
32862 || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
32863 ok = false;
32864 else
32865 /* http://cplusplus.github.io/EWG/ewg-active.html#66 */
32866 pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
32867 "ISO C++ did not adopt string literal operator templa"
32868 "tes taking an argument pack of characters");
32869 }
32870 else
32871 ok = false;
32872 }
32873 if (!ok)
32874 {
32875 if (cxx_dialect > cxx17)
32876 error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
32877 "template %qD has invalid parameter list; expected "
32878 "non-type template parameter pack %<<char...>%> or "
32879 "single non-type parameter of class type",
32880 decl);
32881 else
32882 error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
32883 "template %qD has invalid parameter list; expected "
32884 "non-type template parameter pack %<<char...>%>",
32885 decl);
32886 }
32887 }
32888
32889 /* Register member declarations. */
32890 if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
32891 finish_member_declaration (decl);
32892 /* If DECL is a function template, we must return to parse it later.
32893 (Even though there is no definition, there might be default
32894 arguments that need handling.) */
32895 if (member_p && decl
32896 && DECL_DECLARES_FUNCTION_P (decl))
32897 vec_safe_push (unparsed_funs_with_definitions, obj: decl);
32898}
32899
32900/* Parse a template introduction header for a template-declaration. Returns
32901 false if tentative parse fails. */
32902
32903static bool
32904cp_parser_template_introduction (cp_parser* parser, bool member_p)
32905{
32906 cp_parser_parse_tentatively (parser);
32907
32908 tree saved_scope = parser->scope;
32909 tree saved_object_scope = parser->object_scope;
32910 tree saved_qualifying_scope = parser->qualifying_scope;
32911 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
32912
32913 cp_token *start_token = cp_lexer_peek_token (lexer: parser->lexer);
32914
32915 /* In classes don't parse valid unnamed bitfields as invalid
32916 template introductions. */
32917 if (member_p)
32918 parser->colon_corrects_to_scope_p = false;
32919
32920 /* Look for the optional `::' operator. */
32921 cp_parser_global_scope_opt (parser,
32922 /*current_scope_valid_p=*/false);
32923 /* Look for the nested-name-specifier. */
32924 cp_parser_nested_name_specifier_opt (parser,
32925 /*typename_keyword_p=*/false,
32926 /*check_dependency_p=*/true,
32927 /*type_p=*/false,
32928 /*is_declaration=*/false);
32929
32930 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
32931 tree concept_name = cp_parser_identifier (parser);
32932
32933 /* Look up the concept for which we will be matching
32934 template parameters. */
32935 tree tmpl_decl = cp_parser_lookup_name_simple (parser, name: concept_name,
32936 location: token->location);
32937 parser->scope = saved_scope;
32938 parser->object_scope = saved_object_scope;
32939 parser->qualifying_scope = saved_qualifying_scope;
32940 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
32941
32942 if (concept_name == error_mark_node
32943 || (seen_error () && !concept_definition_p (t: tmpl_decl)))
32944 cp_parser_simulate_error (parser);
32945
32946 /* Look for opening brace for introduction. */
32947 matching_braces braces;
32948 braces.require_open (parser);
32949 location_t open_loc = input_location;
32950
32951 if (!cp_parser_parse_definitely (parser))
32952 return false;
32953
32954 push_deferring_access_checks (dk_deferred);
32955
32956 /* Build vector of placeholder parameters and grab
32957 matching identifiers. */
32958 tree introduction_list = cp_parser_introduction_list (parser);
32959
32960 /* Look for closing brace for introduction. */
32961 if (!braces.require_close (parser))
32962 return true;
32963
32964 /* The introduction-list shall not be empty. */
32965 int nargs = TREE_VEC_LENGTH (introduction_list);
32966 if (nargs == 0)
32967 {
32968 /* In cp_parser_introduction_list we have already issued an error. */
32969 return true;
32970 }
32971
32972 if (tmpl_decl == error_mark_node)
32973 {
32974 cp_parser_name_lookup_error (parser, name: concept_name, decl: tmpl_decl, desired: NLE_NULL,
32975 location: token->location);
32976 return true;
32977 }
32978
32979 /* Build and associate the constraint. */
32980 location_t introduction_loc = make_location (caret: open_loc,
32981 start: start_token->location,
32982 lexer: parser->lexer);
32983 tree parms = finish_template_introduction (tmpl_decl,
32984 introduction_list,
32985 loc: introduction_loc);
32986 if (parms && parms != error_mark_node)
32987 {
32988 if (!flag_concepts_ts)
32989 pedwarn (introduction_loc, 0, "template-introductions"
32990 " are not part of C++20 concepts; use %qs to enable",
32991 "-fconcepts-ts");
32992
32993 cp_parser_template_declaration_after_parameters (parser, parameter_list: parms,
32994 member_p);
32995 return true;
32996 }
32997
32998 if (parms == NULL_TREE)
32999 error_at (token->location, "no matching concept for template-introduction");
33000
33001 return true;
33002}
33003
33004/* Parse a normal template-declaration following the template keyword. */
33005
33006static void
33007cp_parser_explicit_template_declaration (cp_parser* parser, bool member_p)
33008{
33009 tree parameter_list;
33010 bool need_lang_pop;
33011 location_t location = input_location;
33012
33013 /* Look for the `<' token. */
33014 if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
33015 return;
33016 if (at_class_scope_p () && current_function_decl)
33017 {
33018 /* 14.5.2.2 [temp.mem]
33019
33020 A local class shall not have member templates. */
33021 error_at (location,
33022 "invalid declaration of member template in local class");
33023 cp_parser_skip_to_end_of_block_or_statement (parser);
33024 return;
33025 }
33026 /* [temp]
33027
33028 A template ... shall not have C linkage. */
33029 if (current_lang_name == lang_name_c)
33030 {
33031 error_at (location, "template with C linkage");
33032 maybe_show_extern_c_location ();
33033 /* Give it C++ linkage to avoid confusing other parts of the
33034 front end. */
33035 push_lang_context (lang_name_cplusplus);
33036 need_lang_pop = true;
33037 }
33038 else
33039 need_lang_pop = false;
33040
33041 /* We cannot perform access checks on the template parameter
33042 declarations until we know what is being declared, just as we
33043 cannot check the decl-specifier list. */
33044 push_deferring_access_checks (dk_deferred);
33045
33046 /* If the next token is `>', then we have an invalid
33047 specialization. Rather than complain about an invalid template
33048 parameter, issue an error message here. */
33049 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_GREATER))
33050 {
33051 cp_parser_error (parser, gmsgid: "invalid explicit specialization");
33052 begin_specialization ();
33053 parameter_list = NULL_TREE;
33054 }
33055 else
33056 {
33057 /* Parse the template parameters. */
33058 parameter_list = cp_parser_template_parameter_list (parser);
33059 }
33060
33061 /* Look for the `>'. */
33062 cp_parser_require_end_of_template_parameter_list (parser);
33063
33064 /* Manage template requirements */
33065 if (flag_concepts)
33066 {
33067 tree reqs = get_shorthand_constraints (current_template_parms);
33068 if (tree treqs = cp_parser_requires_clause_opt (parser, lambda_p: false))
33069 reqs = combine_constraint_expressions (reqs, treqs);
33070 TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
33071 }
33072
33073 cp_parser_template_declaration_after_parameters (parser, parameter_list,
33074 member_p);
33075
33076 /* For the erroneous case of a template with C linkage, we pushed an
33077 implicit C++ linkage scope; exit that scope now. */
33078 if (need_lang_pop)
33079 pop_lang_context ();
33080}
33081
33082/* Parse a template-declaration, assuming that the `export' (and
33083 `extern') keywords, if present, has already been scanned. MEMBER_P
33084 is as for cp_parser_template_declaration. */
33085
33086static bool
33087cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
33088{
33089 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TEMPLATE))
33090 {
33091 cp_lexer_consume_token (lexer: parser->lexer);
33092 cp_parser_explicit_template_declaration (parser, member_p);
33093 return true;
33094 }
33095 else if (flag_concepts)
33096 return cp_parser_template_introduction (parser, member_p);
33097
33098 return false;
33099}
33100
33101/* Perform the deferred access checks from a template-parameter-list.
33102 CHECKS is a TREE_LIST of access checks, as returned by
33103 get_deferred_access_checks. */
33104
33105static void
33106cp_parser_perform_template_parameter_access_checks (vec<deferred_access_check, va_gc> *checks)
33107{
33108 ++processing_template_parmlist;
33109 perform_access_checks (checks, tf_warning_or_error);
33110 --processing_template_parmlist;
33111}
33112
33113/* Parse a `decl-specifier-seq [opt] init-declarator [opt] ;' or
33114 `function-definition' sequence that follows a template header.
33115 If MEMBER_P is true, this declaration appears in a class scope.
33116
33117 Returns the DECL for the declared entity. If FRIEND_P is non-NULL,
33118 *FRIEND_P is set to TRUE iff the declaration is a friend. */
33119
33120static tree
33121cp_parser_single_declaration (cp_parser* parser,
33122 vec<deferred_access_check, va_gc> *checks,
33123 bool member_p,
33124 bool explicit_specialization_p,
33125 bool* friend_p)
33126{
33127 int declares_class_or_enum;
33128 tree decl = NULL_TREE;
33129 cp_decl_specifier_seq decl_specifiers;
33130 bool function_definition_p = false;
33131 cp_token *decl_spec_token_start;
33132
33133 /* This function is only used when processing a template
33134 declaration. */
33135 gcc_assert (innermost_scope_kind () == sk_template_parms
33136 || innermost_scope_kind () == sk_template_spec);
33137
33138 /* Defer access checks until we know what is being declared. */
33139 push_deferring_access_checks (dk_deferred);
33140
33141 /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
33142 alternative. */
33143 decl_spec_token_start = cp_lexer_peek_token (lexer: parser->lexer);
33144 cp_parser_decl_specifier_seq (parser,
33145 flags: (CP_PARSER_FLAGS_OPTIONAL
33146 | CP_PARSER_FLAGS_TYPENAME_OPTIONAL),
33147 decl_specs: &decl_specifiers,
33148 declares_class_or_enum: &declares_class_or_enum);
33149
33150 cp_omp_declare_simd_data odsd;
33151 if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
33152 cp_parser_handle_directive_omp_attributes (parser,
33153 pattrs: &decl_specifiers.attributes,
33154 data: &odsd, start: true);
33155
33156 if (friend_p)
33157 *friend_p = cp_parser_friend_p (&decl_specifiers);
33158
33159 /* There are no template typedefs. */
33160 if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
33161 {
33162 error_at (decl_spec_token_start->location,
33163 "template declaration of %<typedef%>");
33164 decl = error_mark_node;
33165 }
33166
33167 /* Gather up the access checks that occurred the
33168 decl-specifier-seq. */
33169 stop_deferring_access_checks ();
33170
33171 /* Check for the declaration of a template class. */
33172 if (declares_class_or_enum)
33173 {
33174 if (cp_parser_declares_only_class_p (parser)
33175 || (declares_class_or_enum & 2))
33176 {
33177 decl = shadow_tag (&decl_specifiers);
33178
33179 /* In this case:
33180
33181 struct C {
33182 friend template <typename T> struct A<T>::B;
33183 };
33184
33185 A<T>::B will be represented by a TYPENAME_TYPE, and
33186 therefore not recognized by shadow_tag. */
33187 if (friend_p && *friend_p
33188 && !decl
33189 && decl_specifiers.type
33190 && TYPE_P (decl_specifiers.type))
33191 decl = decl_specifiers.type;
33192
33193 if (decl && decl != error_mark_node)
33194 decl = TYPE_NAME (decl);
33195 else
33196 decl = error_mark_node;
33197
33198 /* If this is a declaration, but not a definition, associate
33199 any constraints with the type declaration. Constraints
33200 are associated with definitions in cp_parser_class_specifier. */
33201 if (declares_class_or_enum == 1)
33202 associate_classtype_constraints (TREE_TYPE (decl));
33203
33204 /* Perform access checks for template parameters. */
33205 cp_parser_perform_template_parameter_access_checks (checks);
33206
33207 /* Give a helpful diagnostic for
33208 template <class T> struct A { } a;
33209 if we aren't already recovering from an error. */
33210 if (!cp_parser_declares_only_class_p (parser)
33211 && !seen_error ())
33212 {
33213 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
33214 "a class template declaration must not declare "
33215 "anything else");
33216 cp_parser_skip_to_end_of_block_or_statement (parser);
33217 goto out;
33218 }
33219 }
33220 }
33221
33222 /* Complain about missing 'typename' or other invalid type names. */
33223 if (!decl_specifiers.any_type_specifiers_p
33224 && cp_parser_parse_and_diagnose_invalid_type_name (parser))
33225 {
33226 /* cp_parser_parse_and_diagnose_invalid_type_name calls
33227 cp_parser_skip_to_end_of_block_or_statement, so don't try to parse
33228 the rest of this declaration. */
33229 decl = error_mark_node;
33230 goto out;
33231 }
33232
33233 /* If it's not a template class, try for a template function. If
33234 the next token is a `;', then this declaration does not declare
33235 anything. But, if there were errors in the decl-specifiers, then
33236 the error might well have come from an attempted class-specifier.
33237 In that case, there's no need to warn about a missing declarator. */
33238 if (!decl
33239 && (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON)
33240 || decl_specifiers.type != error_mark_node))
33241 {
33242 int flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
33243 /* We don't delay parsing for friends, though CWG 2510 may change
33244 that. */
33245 if (member_p && !(friend_p && *friend_p))
33246 flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT;
33247 decl = cp_parser_init_declarator (parser,
33248 flags,
33249 decl_specifiers: &decl_specifiers,
33250 checks,
33251 /*function_definition_allowed_p=*/true,
33252 member_p,
33253 declares_class_or_enum,
33254 function_definition_p: &function_definition_p,
33255 NULL, NULL, NULL);
33256
33257 /* 7.1.1-1 [dcl.stc]
33258
33259 A storage-class-specifier shall not be specified in an explicit
33260 specialization... */
33261 if (decl
33262 && explicit_specialization_p
33263 && decl_specifiers.storage_class != sc_none)
33264 {
33265 error_at (decl_spec_token_start->location,
33266 "explicit template specialization cannot have a storage class");
33267 decl = error_mark_node;
33268 }
33269
33270 if (decl && VAR_P (decl))
33271 check_template_variable (decl);
33272 }
33273
33274 /* Look for a trailing `;' after the declaration. */
33275 if (!function_definition_p
33276 && (decl == error_mark_node
33277 || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)))
33278 cp_parser_skip_to_end_of_block_or_statement (parser);
33279
33280 out:
33281 pop_deferring_access_checks ();
33282
33283 /* Clear any current qualification; whatever comes next is the start
33284 of something new. */
33285 parser->scope = NULL_TREE;
33286 parser->qualifying_scope = NULL_TREE;
33287 parser->object_scope = NULL_TREE;
33288
33289 cp_finalize_omp_declare_simd (parser, data: &odsd);
33290
33291 return decl;
33292}
33293
33294/* Parse a cast-expression that is not the operand of a unary "&". */
33295
33296static cp_expr
33297cp_parser_simple_cast_expression (cp_parser *parser)
33298{
33299 return cp_parser_cast_expression (parser, /*address_p=*/false,
33300 /*cast_p=*/false, /*decltype*/decltype_p: false, NULL);
33301}
33302
33303/* Parse a functional cast to TYPE. Returns an expression
33304 representing the cast. */
33305
33306static cp_expr
33307cp_parser_functional_cast (cp_parser* parser, tree type)
33308{
33309 vec<tree, va_gc> *vec;
33310 tree expression_list;
33311 cp_expr cast;
33312
33313 location_t start_loc = input_location;
33314
33315 if (!type)
33316 type = error_mark_node;
33317
33318 if (TREE_CODE (type) == TYPE_DECL
33319 && is_auto (TREE_TYPE (type)))
33320 type = TREE_TYPE (type);
33321
33322 if (is_auto (type)
33323 && !AUTO_IS_DECLTYPE (type)
33324 && !PLACEHOLDER_TYPE_CONSTRAINTS (type)
33325 && !CLASS_PLACEHOLDER_TEMPLATE (type))
33326 /* auto(x) and auto{x} need to use a level-less auto. */
33327 type = make_cast_auto ();
33328
33329 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
33330 {
33331 cp_lexer_set_source_position (lexer: parser->lexer);
33332 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
33333 expression_list = cp_parser_braced_list (parser);
33334 CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
33335 if (TREE_CODE (type) == TYPE_DECL)
33336 type = TREE_TYPE (type);
33337
33338 cast = finish_compound_literal (type, expression_list,
33339 tf_warning_or_error, fcl_functional);
33340 /* Create a location of the form:
33341 type_name{i, f}
33342 ^~~~~~~~~~~~~~~
33343 with caret == start at the start of the type name,
33344 finishing at the closing brace. */
33345 location_t combined_loc = make_location (caret: start_loc, start: start_loc,
33346 lexer: parser->lexer);
33347 cast.set_location (combined_loc);
33348 return cast;
33349 }
33350
33351
33352 vec = cp_parser_parenthesized_expression_list (parser, is_attribute_list: non_attr,
33353 /*cast_p=*/true,
33354 /*allow_expansion_p=*/true,
33355 /*non_constant_p=*/NULL);
33356 if (vec == NULL)
33357 expression_list = error_mark_node;
33358 else
33359 {
33360 expression_list = build_tree_list_vec (vec);
33361 release_tree_vector (vec);
33362 }
33363
33364 /* Create a location of the form:
33365 float(i)
33366 ^~~~~~~~
33367 with caret == start at the start of the type name,
33368 finishing at the closing paren. */
33369 location_t combined_loc = make_location (caret: start_loc, start: start_loc,
33370 lexer: parser->lexer);
33371 cast = build_functional_cast (combined_loc, type, expression_list,
33372 tf_warning_or_error);
33373
33374 /* [expr.const]/1: In an integral constant expression "only type
33375 conversions to integral or enumeration type can be used". */
33376 if (TREE_CODE (type) == TYPE_DECL)
33377 type = TREE_TYPE (type);
33378 if (cast != error_mark_node
33379 && !cast_valid_in_integral_constant_expression_p (type)
33380 && cp_parser_non_integral_constant_expression (parser,
33381 thing: NIC_CONSTRUCTOR))
33382 return error_mark_node;
33383
33384 return cast;
33385}
33386
33387/* Save the tokens that make up the body of a member function defined
33388 in a class-specifier. The DECL_SPECIFIERS and DECLARATOR have
33389 already been parsed. The ATTRIBUTES are any GNU "__attribute__"
33390 specifiers applied to the declaration. Returns the FUNCTION_DECL
33391 for the member function. */
33392
33393static tree
33394cp_parser_save_member_function_body (cp_parser* parser,
33395 cp_decl_specifier_seq *decl_specifiers,
33396 cp_declarator *declarator,
33397 tree attributes)
33398{
33399 cp_token *first;
33400 cp_token *last;
33401 tree fn;
33402 bool function_try_block = false;
33403
33404 /* Create the FUNCTION_DECL. */
33405 fn = grokmethod (decl_specifiers, declarator, attributes);
33406 cp_finalize_omp_declare_simd (parser, fndecl: fn);
33407 cp_finalize_oacc_routine (parser, fn, true);
33408 /* If something went badly wrong, bail out now. */
33409 if (fn == error_mark_node)
33410 {
33411 /* If there's a function-body, skip it. */
33412 if (cp_parser_token_starts_function_definition_p
33413 (cp_lexer_peek_token (lexer: parser->lexer)))
33414 cp_parser_skip_to_end_of_block_or_statement (parser);
33415 return error_mark_node;
33416 }
33417
33418 /* Remember it, if there are default args to post process. */
33419 cp_parser_save_default_args (parser, fn);
33420
33421 /* Save away the tokens that make up the body of the
33422 function. */
33423 first = parser->lexer->next_token;
33424
33425 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TRANSACTION_RELAXED))
33426 cp_lexer_consume_token (lexer: parser->lexer);
33427 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer,
33428 keyword: RID_TRANSACTION_ATOMIC))
33429 {
33430 cp_lexer_consume_token (lexer: parser->lexer);
33431 /* Match cp_parser_txn_attribute_opt [[ identifier ]]. */
33432 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_SQUARE)
33433 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_SQUARE)
33434 && (cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_NAME)
33435 || cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_KEYWORD))
33436 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 4, type: CPP_CLOSE_SQUARE)
33437 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 5, type: CPP_CLOSE_SQUARE))
33438 {
33439 cp_lexer_consume_token (lexer: parser->lexer);
33440 cp_lexer_consume_token (lexer: parser->lexer);
33441 cp_lexer_consume_token (lexer: parser->lexer);
33442 cp_lexer_consume_token (lexer: parser->lexer);
33443 cp_lexer_consume_token (lexer: parser->lexer);
33444 }
33445 else
33446 while (cp_next_tokens_can_be_gnu_attribute_p (parser)
33447 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_PAREN))
33448 {
33449 cp_lexer_consume_token (lexer: parser->lexer);
33450 if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
33451 break;
33452 }
33453 }
33454
33455 /* Handle function try blocks. */
33456 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TRY))
33457 {
33458 cp_lexer_consume_token (lexer: parser->lexer);
33459 function_try_block = true;
33460 }
33461 /* We can have braced-init-list mem-initializers before the fn body. */
33462 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
33463 {
33464 cp_lexer_consume_token (lexer: parser->lexer);
33465 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_BRACE))
33466 {
33467 /* cache_group will stop after an un-nested { } pair, too. */
33468 if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
33469 break;
33470
33471 /* variadic mem-inits have ... after the ')'. */
33472 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
33473 cp_lexer_consume_token (lexer: parser->lexer);
33474 }
33475 }
33476 cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
33477 /* Handle function try blocks. */
33478 if (function_try_block)
33479 while (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_CATCH))
33480 cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
33481 last = parser->lexer->next_token;
33482
33483 /* Save away the inline definition; we will process it when the
33484 class is complete. */
33485 DECL_PENDING_INLINE_INFO (fn) = cp_token_cache_new (first, last);
33486 DECL_PENDING_INLINE_P (fn) = 1;
33487
33488 /* We need to know that this was defined in the class, so that
33489 friend templates are handled correctly. */
33490 DECL_INITIALIZED_IN_CLASS_P (fn) = 1;
33491
33492 /* Add FN to the queue of functions to be parsed later. */
33493 vec_safe_push (unparsed_funs_with_definitions, obj: fn);
33494
33495 return fn;
33496}
33497
33498/* Save the tokens that make up the in-class initializer for a non-static
33499 data member. Returns a DEFERRED_PARSE. */
33500
33501static tree
33502cp_parser_save_nsdmi (cp_parser* parser)
33503{
33504 return cp_parser_cache_defarg (parser, /*nsdmi=*/true);
33505}
33506
33507/* Parse a template-argument-list, as well as the trailing ">" (but
33508 not the opening "<"). See cp_parser_template_argument_list for the
33509 return value. */
33510
33511static tree
33512cp_parser_enclosed_template_argument_list (cp_parser* parser)
33513{
33514 tree arguments;
33515 tree saved_scope;
33516 tree saved_qualifying_scope;
33517 tree saved_object_scope;
33518 bool saved_greater_than_is_operator_p;
33519
33520 /* [temp.names]
33521
33522 When parsing a template-id, the first non-nested `>' is taken as
33523 the end of the template-argument-list rather than a greater-than
33524 operator. */
33525 saved_greater_than_is_operator_p
33526 = parser->greater_than_is_operator_p;
33527 parser->greater_than_is_operator_p = false;
33528 /* Parsing the argument list may modify SCOPE, so we save it
33529 here. */
33530 saved_scope = parser->scope;
33531 saved_qualifying_scope = parser->qualifying_scope;
33532 saved_object_scope = parser->object_scope;
33533 /* We need to evaluate the template arguments, even though this
33534 template-id may be nested within a "sizeof". */
33535 cp_evaluated ev;
33536 /* Parse the template-argument-list itself. */
33537 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_GREATER)
33538 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_RSHIFT)
33539 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_GREATER_EQ)
33540 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_RSHIFT_EQ))
33541 {
33542 arguments = make_tree_vec (0);
33543 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (arguments, 0);
33544 }
33545 else
33546 arguments = cp_parser_template_argument_list (parser);
33547 /* Look for the `>' that ends the template-argument-list. If we find
33548 a '>>' instead, it's probably just a typo. */
33549 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_RSHIFT))
33550 {
33551 if (cxx_dialect != cxx98)
33552 {
33553 /* In C++0x, a `>>' in a template argument list or cast
33554 expression is considered to be two separate `>'
33555 tokens. So, change the current token to a `>', but don't
33556 consume it: it will be consumed later when the outer
33557 template argument list (or cast expression) is parsed.
33558 Note that this replacement of `>' for `>>' is necessary
33559 even if we are parsing tentatively: in the tentative
33560 case, after calling
33561 cp_parser_enclosed_template_argument_list we will always
33562 throw away all of the template arguments and the first
33563 closing `>', either because the template argument list
33564 was erroneous or because we are replacing those tokens
33565 with a CPP_TEMPLATE_ID token. The second `>' (which will
33566 not have been thrown away) is needed either to close an
33567 outer template argument list or to complete a new-style
33568 cast. */
33569 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
33570 token->type = CPP_GREATER;
33571 }
33572 else if (!saved_greater_than_is_operator_p)
33573 {
33574 /* If we're in a nested template argument list, the '>>' has
33575 to be a typo for '> >'. We emit the error message, but we
33576 continue parsing and we push a '>' as next token, so that
33577 the argument list will be parsed correctly. Note that the
33578 global source location is still on the token before the
33579 '>>', so we need to say explicitly where we want it. */
33580 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
33581 gcc_rich_location richloc (token->location);
33582 richloc.add_fixit_replace (new_content: "> >");
33583 error_at (&richloc, "%<>>%> should be %<> >%> "
33584 "within a nested template argument list");
33585
33586 token->type = CPP_GREATER;
33587 }
33588 else
33589 {
33590 /* If this is not a nested template argument list, the '>>'
33591 is a typo for '>'. Emit an error message and continue.
33592 Same deal about the token location, but here we can get it
33593 right by consuming the '>>' before issuing the diagnostic. */
33594 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
33595 error_at (token->location,
33596 "spurious %<>>%>, use %<>%> to terminate "
33597 "a template argument list");
33598 }
33599 }
33600 /* Similarly for >>= and >=. */
33601 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_GREATER_EQ)
33602 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_RSHIFT_EQ))
33603 {
33604 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
33605 gcc_rich_location richloc (token->location);
33606 enum cpp_ttype new_type;
33607 const char *replacement;
33608 if (token->type == CPP_GREATER_EQ)
33609 {
33610 replacement = "> =";
33611 new_type = CPP_EQ;
33612 }
33613 else if (!saved_greater_than_is_operator_p)
33614 {
33615 if (cxx_dialect != cxx98)
33616 replacement = ">> =";
33617 else
33618 replacement = "> > =";
33619 new_type = CPP_GREATER;
33620 }
33621 else
33622 {
33623 replacement = "> >=";
33624 new_type = CPP_GREATER_EQ;
33625 }
33626 richloc.add_fixit_replace (new_content: replacement);
33627 error_at (&richloc, "%qs should be %qs to terminate a template "
33628 "argument list",
33629 cpp_type2name (token->type, flags: token->flags), replacement);
33630 token->type = new_type;
33631 }
33632 else
33633 cp_parser_require_end_of_template_parameter_list (parser);
33634 /* The `>' token might be a greater-than operator again now. */
33635 parser->greater_than_is_operator_p
33636 = saved_greater_than_is_operator_p;
33637 /* Restore the SAVED_SCOPE. */
33638 parser->scope = saved_scope;
33639 parser->qualifying_scope = saved_qualifying_scope;
33640 parser->object_scope = saved_object_scope;
33641
33642 return arguments;
33643}
33644
33645/* MEMBER_FUNCTION is a member function, or a friend. If default
33646 arguments, or the body of the function have not yet been parsed,
33647 parse them now. */
33648
33649static void
33650cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
33651{
33652 auto_timevar tv (TV_PARSE_INMETH);
33653
33654 /* If this member is a template, get the underlying
33655 FUNCTION_DECL. */
33656 if (DECL_FUNCTION_TEMPLATE_P (member_function))
33657 member_function = DECL_TEMPLATE_RESULT (member_function);
33658
33659 /* There should not be any class definitions in progress at this
33660 point; the bodies of members are only parsed outside of all class
33661 definitions. */
33662 gcc_assert (parser->num_classes_being_defined == 0);
33663 /* While we're parsing the member functions we might encounter more
33664 classes. We want to handle them right away, but we don't want
33665 them getting mixed up with functions that are currently in the
33666 queue. */
33667 push_unparsed_function_queues (parser);
33668
33669 /* Make sure that any template parameters are in scope. */
33670 maybe_begin_member_template_processing (member_function);
33671
33672 /* If the body of the function has not yet been parsed, parse it
33673 now. Except if the tokens have been purged (PR c++/39751). */
33674 if (DECL_PENDING_INLINE_P (member_function)
33675 && !DECL_PENDING_INLINE_INFO (member_function)->first->purged_p)
33676 {
33677 tree function_scope;
33678 cp_token_cache *tokens;
33679
33680 /* The function is no longer pending; we are processing it. */
33681 tokens = DECL_PENDING_INLINE_INFO (member_function);
33682 DECL_PENDING_INLINE_INFO (member_function) = NULL;
33683 DECL_PENDING_INLINE_P (member_function) = 0;
33684
33685 /* If this is a local class, enter the scope of the containing
33686 function. */
33687 function_scope = current_function_decl;
33688 if (function_scope)
33689 push_function_context ();
33690
33691 /* Push the body of the function onto the lexer stack. */
33692 cp_parser_push_lexer_for_tokens (parser, cache: tokens);
33693
33694 /* Let the front end know that we going to be defining this
33695 function. */
33696 start_preparsed_function (member_function, NULL_TREE,
33697 SF_PRE_PARSED | SF_INCLASS_INLINE);
33698
33699 /* #pragma omp declare reduction needs special parsing. */
33700 if (DECL_OMP_DECLARE_REDUCTION_P (member_function))
33701 {
33702 parser->lexer->in_pragma = true;
33703 cp_parser_omp_declare_reduction_exprs (member_function, parser);
33704 finish_function (/*inline_p=*/true);
33705 cp_check_omp_declare_reduction (member_function);
33706 }
33707 else
33708 /* Now, parse the body of the function. */
33709 cp_parser_function_definition_after_declarator (parser,
33710 /*inline_p=*/true);
33711
33712 /* Leave the scope of the containing function. */
33713 if (function_scope)
33714 pop_function_context ();
33715 cp_parser_pop_lexer (parser);
33716 }
33717
33718 /* Remove any template parameters from the symbol table. */
33719 maybe_end_member_template_processing ();
33720
33721 /* Restore the queue. */
33722 pop_unparsed_function_queues (parser);
33723}
33724
33725/* If DECL contains any default args, remember it on the unparsed
33726 functions queue. */
33727
33728static void
33729cp_parser_save_default_args (cp_parser* parser, tree decl)
33730{
33731 tree probe;
33732
33733 for (probe = TYPE_ARG_TYPES (TREE_TYPE (decl));
33734 probe;
33735 probe = TREE_CHAIN (probe))
33736 if (TREE_PURPOSE (probe))
33737 {
33738 cp_default_arg_entry entry = {current_class_type, .decl: decl};
33739 vec_safe_push (unparsed_funs_with_default_args, obj: entry);
33740 break;
33741 }
33742
33743 /* Remember if there is a noexcept-specifier to post process. */
33744 tree spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
33745 if (UNPARSED_NOEXCEPT_SPEC_P (spec))
33746 vec_safe_push (unparsed_noexcepts, obj: decl);
33747
33748 /* Contracts are deferred. */
33749 for (tree attr = DECL_ATTRIBUTES (decl); attr; attr = TREE_CHAIN (attr))
33750 if (cxx_contract_attribute_p (attr))
33751 {
33752 vec_safe_push (unparsed_contracts, obj: decl);
33753 break;
33754 }
33755}
33756
33757/* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
33758 which is either a FIELD_DECL or PARM_DECL. Parse it and return
33759 the result. For a PARM_DECL, PARMTYPE is the corresponding type
33760 from the parameter-type-list. */
33761
33762static tree
33763cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
33764 tree default_arg, tree parmtype)
33765{
33766 cp_token_cache *tokens;
33767 tree parsed_arg;
33768
33769 if (default_arg == error_mark_node)
33770 return error_mark_node;
33771
33772 /* Push the saved tokens for the default argument onto the parser's
33773 lexer stack. */
33774 tokens = DEFPARSE_TOKENS (default_arg);
33775 cp_parser_push_lexer_for_tokens (parser, cache: tokens);
33776
33777 start_lambda_scope (decl);
33778
33779 /* Parse the default argument. */
33780 parsed_arg = cp_parser_initializer (parser);
33781 if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg))
33782 maybe_warn_cpp0x (str: CPP0X_INITIALIZER_LISTS);
33783
33784 finish_lambda_scope ();
33785
33786 if (parsed_arg == error_mark_node)
33787 cp_parser_skip_to_end_of_statement (parser);
33788
33789 if (!processing_template_decl)
33790 {
33791 /* In a non-template class, check conversions now. In a template,
33792 we'll wait and instantiate these as needed. */
33793 if (TREE_CODE (decl) == PARM_DECL)
33794 parsed_arg = check_default_argument (parmtype, parsed_arg,
33795 tf_warning_or_error);
33796 else if (maybe_reject_flexarray_init (decl, parsed_arg))
33797 parsed_arg = error_mark_node;
33798 else
33799 parsed_arg = digest_nsdmi_init (decl, parsed_arg, tf_warning_or_error);
33800 }
33801
33802 /* If the token stream has not been completely used up, then
33803 there was extra junk after the end of the default
33804 argument. */
33805 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EOF))
33806 {
33807 if (TREE_CODE (decl) == PARM_DECL)
33808 cp_parser_error (parser, gmsgid: "expected %<,%>");
33809 else
33810 cp_parser_error (parser, gmsgid: "expected %<;%>");
33811 }
33812
33813 /* Revert to the main lexer. */
33814 cp_parser_pop_lexer (parser);
33815
33816 return parsed_arg;
33817}
33818
33819/* FIELD is a non-static data member with an initializer which we saved for
33820 later; parse it now. */
33821
33822static void
33823cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
33824{
33825 tree def;
33826
33827 maybe_begin_member_template_processing (field);
33828
33829 push_unparsed_function_queues (parser);
33830 def = cp_parser_late_parse_one_default_arg (parser, decl: field,
33831 DECL_INITIAL (field),
33832 NULL_TREE);
33833 pop_unparsed_function_queues (parser);
33834
33835 maybe_end_member_template_processing ();
33836
33837 DECL_INITIAL (field) = def;
33838}
33839
33840/* FN is a FUNCTION_DECL which may contains a parameter with an
33841 unparsed DEFERRED_PARSE. Parse the default args now. This function
33842 assumes that the current scope is the scope in which the default
33843 argument should be processed. */
33844
33845static void
33846cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
33847{
33848 unsigned char saved_local_variables_forbidden_p;
33849
33850 /* While we're parsing the default args, we might (due to the
33851 statement expression extension) encounter more classes. We want
33852 to handle them right away, but we don't want them getting mixed
33853 up with default args that are currently in the queue. */
33854 push_unparsed_function_queues (parser);
33855
33856 /* Local variable names (and the `this' keyword) may not appear
33857 in a default argument. */
33858 saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
33859 parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
33860
33861 push_defarg_context (fn);
33862
33863 begin_scope (sk_function_parms, fn);
33864
33865 /* Gather the PARM_DECLs into a vec so we can keep track of them when
33866 pushdecl clears DECL_CHAIN. */
33867 releasing_vec parms;
33868 for (tree parmdecl = DECL_ARGUMENTS (fn); parmdecl;
33869 parmdecl = DECL_CHAIN (parmdecl))
33870 vec_safe_push (r&: parms, t: parmdecl);
33871
33872 tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
33873 for (int i = 0;
33874 parm && parm != void_list_node;
33875 parm = TREE_CHAIN (parm),
33876 ++i)
33877 {
33878 tree default_arg = TREE_PURPOSE (parm);
33879 tree parsed_arg;
33880
33881 tree parmdecl = parms[i];
33882 pushdecl (parmdecl);
33883
33884 if (!default_arg)
33885 continue;
33886
33887 if (TREE_CODE (default_arg) != DEFERRED_PARSE)
33888 /* This can happen for a friend declaration for a function
33889 already declared with default arguments. */
33890 continue;
33891
33892 parsed_arg
33893 = cp_parser_late_parse_one_default_arg (parser, decl: parmdecl,
33894 default_arg,
33895 TREE_VALUE (parm));
33896 TREE_PURPOSE (parm) = parsed_arg;
33897
33898 /* Update any instantiations we've already created. */
33899 for (tree copy : DEFPARSE_INSTANTIATIONS (default_arg))
33900 TREE_PURPOSE (copy) = parsed_arg;
33901 }
33902
33903 pop_bindings_and_leave_scope ();
33904
33905 /* Restore DECL_CHAINs after clobbering by pushdecl. */
33906 parm = NULL_TREE;
33907 for (int i = parms->length () - 1; i >= 0; --i)
33908 {
33909 DECL_CHAIN (parms[i]) = parm;
33910 parm = parms[i];
33911 }
33912
33913 pop_defarg_context ();
33914
33915 /* Make sure no default arg is missing. */
33916 check_default_args (fn);
33917
33918 /* Restore the state of local_variables_forbidden_p. */
33919 parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
33920
33921 /* Restore the queue. */
33922 pop_unparsed_function_queues (parser);
33923}
33924
33925/* Subroutine of cp_parser_sizeof_operand, for handling C++11
33926
33927 sizeof ... ( identifier )
33928
33929 where the 'sizeof' token has already been consumed. */
33930
33931static tree
33932cp_parser_sizeof_pack (cp_parser *parser)
33933{
33934 /* Consume the `...'. */
33935 cp_lexer_consume_token (lexer: parser->lexer);
33936 maybe_warn_variadic_templates ();
33937
33938 matching_parens parens;
33939 bool paren = cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN);
33940 if (paren)
33941 parens.consume_open (parser);
33942 else
33943 permerror (cp_lexer_peek_token (lexer: parser->lexer)->location,
33944 "%<sizeof...%> argument must be surrounded by parentheses");
33945
33946 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
33947 tree name = cp_parser_identifier (parser);
33948 if (name == error_mark_node)
33949 return error_mark_node;
33950 /* The name is not qualified. */
33951 parser->scope = NULL_TREE;
33952 parser->qualifying_scope = NULL_TREE;
33953 parser->object_scope = NULL_TREE;
33954 tree expr = cp_parser_lookup_name_simple (parser, name, location: token->location);
33955 if (expr == error_mark_node)
33956 cp_parser_name_lookup_error (parser, name, decl: expr, desired: NLE_NULL,
33957 location: token->location);
33958 if (TREE_CODE (expr) == TYPE_DECL || TREE_CODE (expr) == TEMPLATE_DECL)
33959 expr = TREE_TYPE (expr);
33960 else if (TREE_CODE (expr) == CONST_DECL)
33961 expr = DECL_INITIAL (expr);
33962 expr = make_pack_expansion (expr);
33963 if (expr != error_mark_node)
33964 PACK_EXPANSION_SIZEOF_P (expr) = true;
33965
33966 if (paren)
33967 parens.require_close (parser);
33968
33969 return expr;
33970}
33971
33972/* Parse the operand of `sizeof' (or a similar operator). Returns
33973 either a TYPE or an expression, depending on the form of the
33974 input. The KEYWORD indicates which kind of expression we have
33975 encountered. */
33976
33977static tree
33978cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
33979{
33980 tree expr = NULL_TREE;
33981 const char *saved_message;
33982 const char *saved_message_arg;
33983 bool saved_integral_constant_expression_p;
33984 bool saved_non_integral_constant_expression_p;
33985
33986 /* If it's a `...', then we are computing the length of a parameter
33987 pack. */
33988 if (keyword == RID_SIZEOF
33989 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
33990 return cp_parser_sizeof_pack (parser);
33991
33992 /* Types cannot be defined in a `sizeof' expression. Save away the
33993 old message. */
33994 saved_message = parser->type_definition_forbidden_message;
33995 saved_message_arg = parser->type_definition_forbidden_message_arg;
33996 parser->type_definition_forbidden_message
33997 = G_("types may not be defined in %qs expressions");
33998 parser->type_definition_forbidden_message_arg
33999 = IDENTIFIER_POINTER (ridpointers[keyword]);
34000
34001 /* The restrictions on constant-expressions do not apply inside
34002 sizeof expressions. */
34003 saved_integral_constant_expression_p
34004 = parser->integral_constant_expression_p;
34005 saved_non_integral_constant_expression_p
34006 = parser->non_integral_constant_expression_p;
34007 parser->integral_constant_expression_p = false;
34008
34009 auto cleanup = make_temp_override
34010 (var&: parser->auto_is_implicit_function_template_parm_p, overrider: false);
34011
34012 /* Do not actually evaluate the expression. */
34013 ++cp_unevaluated_operand;
34014 ++c_inhibit_evaluation_warnings;
34015 /* If it's a `(', then we might be looking at the type-id
34016 construction. */
34017 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
34018 {
34019 tree type = NULL_TREE;
34020
34021 tentative_firewall firewall (parser);
34022
34023 /* We can't be sure yet whether we're looking at a type-id or an
34024 expression. */
34025 cp_parser_parse_tentatively (parser);
34026
34027 matching_parens parens;
34028 parens.consume_open (parser);
34029
34030 /* Note: as a GNU Extension, compound literals are considered
34031 postfix-expressions as they are in C99, so they are valid
34032 arguments to sizeof. See comment in cp_parser_cast_expression
34033 for details. */
34034 if (cp_parser_compound_literal_p (parser))
34035 cp_parser_simulate_error (parser);
34036 else
34037 {
34038 bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
34039 parser->in_type_id_in_expr_p = true;
34040 /* Look for the type-id. */
34041 type = cp_parser_type_id (parser);
34042 /* Look for the closing `)'. */
34043 parens.require_close (parser);
34044 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
34045 }
34046
34047 /* If all went well, then we're done. */
34048 if (cp_parser_parse_definitely (parser))
34049 expr = type;
34050 else
34051 {
34052 /* Commit to the tentative_firewall so we get syntax errors. */
34053 cp_parser_commit_to_tentative_parse (parser);
34054
34055 expr = cp_parser_unary_expression (parser);
34056 }
34057 }
34058 else
34059 expr = cp_parser_unary_expression (parser);
34060
34061 /* Go back to evaluating expressions. */
34062 --cp_unevaluated_operand;
34063 --c_inhibit_evaluation_warnings;
34064
34065 /* And restore the old one. */
34066 parser->type_definition_forbidden_message = saved_message;
34067 parser->type_definition_forbidden_message_arg = saved_message_arg;
34068 parser->integral_constant_expression_p
34069 = saved_integral_constant_expression_p;
34070 parser->non_integral_constant_expression_p
34071 = saved_non_integral_constant_expression_p;
34072
34073 return expr;
34074}
34075
34076/* If the current declaration has no declarator, return true. */
34077
34078static bool
34079cp_parser_declares_only_class_p (cp_parser *parser)
34080{
34081 /* If the next token is a `;' or a `,' then there is no
34082 declarator. */
34083 return (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)
34084 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA));
34085}
34086
34087/* Update the DECL_SPECS to reflect the storage class indicated by
34088 KEYWORD. */
34089
34090static void
34091cp_parser_set_storage_class (cp_parser *parser,
34092 cp_decl_specifier_seq *decl_specs,
34093 enum rid keyword,
34094 cp_token *token)
34095{
34096 cp_storage_class storage_class;
34097
34098 switch (keyword)
34099 {
34100 case RID_AUTO:
34101 storage_class = sc_auto;
34102 break;
34103 case RID_REGISTER:
34104 storage_class = sc_register;
34105 break;
34106 case RID_STATIC:
34107 storage_class = sc_static;
34108 break;
34109 case RID_EXTERN:
34110 storage_class = sc_extern;
34111 break;
34112 case RID_MUTABLE:
34113 storage_class = sc_mutable;
34114 break;
34115 default:
34116 gcc_unreachable ();
34117 }
34118
34119 if (parser->in_unbraced_linkage_specification_p)
34120 {
34121 error_at (token->location, "invalid use of %qD in linkage specification",
34122 ridpointers[keyword]);
34123 return;
34124 }
34125 else if (decl_specs->storage_class != sc_none)
34126 {
34127 if (decl_specs->conflicting_specifiers_p)
34128 return;
34129 gcc_rich_location richloc (token->location);
34130 richloc.add_location_if_nearby (loc: decl_specs->locations[ds_storage_class]);
34131 if (decl_specs->storage_class == storage_class)
34132 error_at (&richloc, "duplicate %qD specifier", ridpointers[keyword]);
34133 else
34134 error_at (&richloc,
34135 "%qD specifier conflicts with %qs",
34136 ridpointers[keyword],
34137 cp_storage_class_name[decl_specs->storage_class]);
34138 decl_specs->conflicting_specifiers_p = true;
34139 return;
34140 }
34141
34142 if ((keyword == RID_EXTERN || keyword == RID_STATIC)
34143 && decl_spec_seq_has_spec_p (decl_specs, ds_thread)
34144 && decl_specs->gnu_thread_keyword_p)
34145 {
34146 pedwarn (decl_specs->locations[ds_thread], 0,
34147 "%<__thread%> before %qD", ridpointers[keyword]);
34148 }
34149
34150 decl_specs->storage_class = storage_class;
34151 set_and_check_decl_spec_loc (decl_specs, ds: ds_storage_class, token);
34152
34153 /* A storage class specifier cannot be applied alongside a typedef
34154 specifier. If there is a typedef specifier present then set
34155 conflicting_specifiers_p which will trigger an error later
34156 on in grokdeclarator. */
34157 if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
34158 && !decl_specs->conflicting_specifiers_p)
34159 {
34160 gcc_rich_location richloc (token->location);
34161 richloc.add_location_if_nearby (loc: decl_specs->locations[ds_typedef]);
34162 error_at (&richloc,
34163 "%qD specifier conflicts with %<typedef%>",
34164 ridpointers[keyword]);
34165 decl_specs->conflicting_specifiers_p = true;
34166 }
34167}
34168
34169/* Update the DECL_SPECS to reflect the TYPE_SPEC. If TYPE_DEFINITION_P
34170 is true, the type is a class or enum definition. */
34171
34172static void
34173cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
34174 tree type_spec,
34175 cp_token *token,
34176 bool type_definition_p)
34177{
34178 decl_specs->any_specifiers_p = true;
34179
34180 /* If the user tries to redeclare bool, char8_t, char16_t, char32_t, or
34181 wchar_t (with, for example, in "typedef int wchar_t;") we remember that
34182 this is what happened. In system headers, we ignore these
34183 declarations so that G++ can work with system headers that are not
34184 C++-safe. */
34185 if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
34186 && !type_definition_p
34187 && TYPE_P (type_spec)
34188 && (type_spec == boolean_type_node
34189 || type_spec == char8_type_node
34190 || type_spec == char16_type_node
34191 || type_spec == char32_type_node
34192 || extended_float_type_p (type: type_spec)
34193 || type_spec == wchar_type_node)
34194 && (decl_specs->type
34195 || decl_spec_seq_has_spec_p (decl_specs, ds_long)
34196 || decl_spec_seq_has_spec_p (decl_specs, ds_short)
34197 || decl_spec_seq_has_spec_p (decl_specs, ds_unsigned)
34198 || decl_spec_seq_has_spec_p (decl_specs, ds_signed)))
34199 {
34200 decl_specs->redefined_builtin_type = type_spec;
34201 set_and_check_decl_spec_loc (decl_specs,
34202 ds: ds_redefined_builtin_type_spec,
34203 token);
34204 if (!decl_specs->type)
34205 {
34206 decl_specs->type = type_spec;
34207 decl_specs->type_definition_p = false;
34208 set_and_check_decl_spec_loc (decl_specs,ds: ds_type_spec, token);
34209 }
34210 }
34211 else if (decl_specs->type)
34212 decl_specs->multiple_types_p = true;
34213 else
34214 {
34215 decl_specs->type = type_spec;
34216 decl_specs->type_definition_p = type_definition_p;
34217 decl_specs->redefined_builtin_type = NULL_TREE;
34218 set_and_check_decl_spec_loc (decl_specs, ds: ds_type_spec, token);
34219 }
34220}
34221
34222/* True iff TOKEN is the GNU keyword __thread. */
34223
34224static bool
34225token_is__thread (cp_token *token)
34226{
34227 gcc_assert (token->keyword == RID_THREAD);
34228 return id_equal (id: token->u.value, str: "__thread");
34229}
34230
34231/* Set the location for a declarator specifier and check if it is
34232 duplicated.
34233
34234 DECL_SPECS is the sequence of declarator specifiers onto which to
34235 set the location.
34236
34237 DS is the single declarator specifier to set which location is to
34238 be set onto the existing sequence of declarators.
34239
34240 LOCATION is the location for the declarator specifier to
34241 consider. */
34242
34243static void
34244set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
34245 cp_decl_spec ds, cp_token *token)
34246{
34247 gcc_assert (ds < ds_last);
34248
34249 if (decl_specs == NULL)
34250 return;
34251
34252 location_t location = token->location;
34253
34254 if (decl_specs->locations[ds] == 0)
34255 {
34256 decl_specs->locations[ds] = location;
34257 if (ds == ds_thread)
34258 decl_specs->gnu_thread_keyword_p = token_is__thread (token);
34259 }
34260 else
34261 {
34262 if (ds == ds_long)
34263 {
34264 if (decl_specs->locations[ds_long_long] != 0)
34265 error_at (location,
34266 "%<long long long%> is too long for GCC");
34267 else
34268 {
34269 decl_specs->locations[ds_long_long] = location;
34270 pedwarn_cxx98 (location,
34271 OPT_Wlong_long,
34272 "ISO C++ 1998 does not support %<long long%>");
34273 }
34274 }
34275 else if (ds == ds_thread)
34276 {
34277 bool gnu = token_is__thread (token);
34278 gcc_rich_location richloc (location);
34279 if (gnu != decl_specs->gnu_thread_keyword_p)
34280 {
34281 richloc.add_range (loc: decl_specs->locations[ds_thread]);
34282 error_at (&richloc,
34283 "both %<__thread%> and %<thread_local%> specified");
34284 }
34285 else
34286 {
34287 richloc.add_fixit_remove ();
34288 error_at (&richloc, "duplicate %qD", token->u.value);
34289 }
34290 }
34291 else
34292 {
34293 /* These correspond to cp-tree.h:cp_decl_spec,
34294 changes here should also be reflected there. */
34295 static const char *const decl_spec_names[] = {
34296 "signed",
34297 "unsigned",
34298 "short",
34299 "long",
34300 "const",
34301 "volatile",
34302 "restrict",
34303 "inline",
34304 "virtual",
34305 "explicit",
34306 "friend",
34307 "typedef",
34308 "using",
34309 "constexpr",
34310 "__complex",
34311 "constinit",
34312 "consteval",
34313 "this"
34314 };
34315 gcc_rich_location richloc (location);
34316 richloc.add_fixit_remove ();
34317 error_at (&richloc, "duplicate %qs", decl_spec_names[ds]);
34318 }
34319 }
34320}
34321
34322/* Return true iff the declarator specifier DS is present in the
34323 sequence of declarator specifiers DECL_SPECS. */
34324
34325bool
34326decl_spec_seq_has_spec_p (const cp_decl_specifier_seq * decl_specs,
34327 cp_decl_spec ds)
34328{
34329 gcc_assert (ds < ds_last);
34330
34331 if (decl_specs == NULL)
34332 return false;
34333
34334 return decl_specs->locations[ds] != 0;
34335}
34336
34337/* DECL_SPECIFIERS is the representation of a decl-specifier-seq.
34338 Returns TRUE iff `friend' appears among the DECL_SPECIFIERS. */
34339
34340static bool
34341cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers)
34342{
34343 return decl_spec_seq_has_spec_p (decl_specs: decl_specifiers, ds: ds_friend);
34344}
34345
34346/* Issue an error message indicating that TOKEN_DESC was expected.
34347 If KEYWORD is true, it indicated this function is called by
34348 cp_parser_require_keword and the required token can only be
34349 a indicated keyword.
34350
34351 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
34352 within any error as the location of an "opening" token matching
34353 the close token TYPE (e.g. the location of the '(' when TOKEN_DESC is
34354 RT_CLOSE_PAREN). */
34355
34356static void
34357cp_parser_required_error (cp_parser *parser,
34358 required_token token_desc,
34359 bool keyword,
34360 location_t matching_location)
34361{
34362 if (cp_parser_simulate_error (parser))
34363 return;
34364
34365 const char *gmsgid = NULL;
34366 switch (token_desc)
34367 {
34368 case RT_NEW:
34369 gmsgid = G_("expected %<new%>");
34370 break;
34371 case RT_DELETE:
34372 gmsgid = G_("expected %<delete%>");
34373 break;
34374 case RT_RETURN:
34375 gmsgid = G_("expected %<return%>");
34376 break;
34377 case RT_WHILE:
34378 gmsgid = G_("expected %<while%>");
34379 break;
34380 case RT_EXTERN:
34381 gmsgid = G_("expected %<extern%>");
34382 break;
34383 case RT_STATIC_ASSERT:
34384 gmsgid = G_("expected %<static_assert%>");
34385 break;
34386 case RT_DECLTYPE:
34387 gmsgid = G_("expected %<decltype%>");
34388 break;
34389 case RT_OPERATOR:
34390 gmsgid = G_("expected %<operator%>");
34391 break;
34392 case RT_CLASS:
34393 gmsgid = G_("expected %<class%>");
34394 break;
34395 case RT_TEMPLATE:
34396 gmsgid = G_("expected %<template%>");
34397 break;
34398 case RT_NAMESPACE:
34399 gmsgid = G_("expected %<namespace%>");
34400 break;
34401 case RT_USING:
34402 gmsgid = G_("expected %<using%>");
34403 break;
34404 case RT_ASM:
34405 gmsgid = G_("expected %<asm%>");
34406 break;
34407 case RT_TRY:
34408 gmsgid = G_("expected %<try%>");
34409 break;
34410 case RT_CATCH:
34411 gmsgid = G_("expected %<catch%>");
34412 break;
34413 case RT_THROW:
34414 gmsgid = G_("expected %<throw%>");
34415 break;
34416 case RT_AUTO:
34417 gmsgid = G_("expected %<auto%>");
34418 break;
34419 case RT_LABEL:
34420 gmsgid = G_("expected %<__label__%>");
34421 break;
34422 case RT_AT_TRY:
34423 gmsgid = G_("expected %<@try%>");
34424 break;
34425 case RT_AT_SYNCHRONIZED:
34426 gmsgid = G_("expected %<@synchronized%>");
34427 break;
34428 case RT_AT_THROW:
34429 gmsgid = G_("expected %<@throw%>");
34430 break;
34431 case RT_TRANSACTION_ATOMIC:
34432 gmsgid = G_("expected %<__transaction_atomic%>");
34433 break;
34434 case RT_TRANSACTION_RELAXED:
34435 gmsgid = G_("expected %<__transaction_relaxed%>");
34436 break;
34437 case RT_CO_YIELD:
34438 gmsgid = G_("expected %<co_yield%>");
34439 break;
34440 default:
34441 break;
34442 }
34443
34444 if (!gmsgid && !keyword)
34445 {
34446 switch (token_desc)
34447 {
34448 case RT_SEMICOLON:
34449 gmsgid = G_("expected %<;%>");
34450 break;
34451 case RT_OPEN_PAREN:
34452 gmsgid = G_("expected %<(%>");
34453 break;
34454 case RT_CLOSE_BRACE:
34455 gmsgid = G_("expected %<}%>");
34456 break;
34457 case RT_OPEN_BRACE:
34458 gmsgid = G_("expected %<{%>");
34459 break;
34460 case RT_CLOSE_SQUARE:
34461 gmsgid = G_("expected %<]%>");
34462 break;
34463 case RT_OPEN_SQUARE:
34464 gmsgid = G_("expected %<[%>");
34465 break;
34466 case RT_COMMA:
34467 gmsgid = G_("expected %<,%>");
34468 break;
34469 case RT_SCOPE:
34470 gmsgid = G_("expected %<::%>");
34471 break;
34472 case RT_LESS:
34473 gmsgid = G_("expected %<<%>");
34474 break;
34475 case RT_GREATER:
34476 gmsgid = G_("expected %<>%>");
34477 break;
34478 case RT_EQ:
34479 gmsgid = G_("expected %<=%>");
34480 break;
34481 case RT_ELLIPSIS:
34482 gmsgid = G_("expected %<...%>");
34483 break;
34484 case RT_MULT:
34485 gmsgid = G_("expected %<*%>");
34486 break;
34487 case RT_COMPL:
34488 gmsgid = G_("expected %<~%>");
34489 break;
34490 case RT_COLON:
34491 gmsgid = G_("expected %<:%>");
34492 break;
34493 case RT_COLON_SCOPE:
34494 gmsgid = G_("expected %<:%> or %<::%>");
34495 break;
34496 case RT_CLOSE_PAREN:
34497 gmsgid = G_("expected %<)%>");
34498 break;
34499 case RT_COMMA_CLOSE_PAREN:
34500 gmsgid = G_("expected %<,%> or %<)%>");
34501 break;
34502 case RT_PRAGMA_EOL:
34503 gmsgid = G_("expected end of line");
34504 break;
34505 case RT_NAME:
34506 gmsgid = G_("expected identifier");
34507 break;
34508 case RT_SELECT:
34509 gmsgid = G_("expected selection-statement");
34510 break;
34511 case RT_ITERATION:
34512 gmsgid = G_("expected iteration-statement");
34513 break;
34514 case RT_JUMP:
34515 gmsgid = G_("expected jump-statement");
34516 break;
34517 case RT_CLASS_KEY:
34518 gmsgid = G_("expected class-key");
34519 break;
34520 case RT_CLASS_TYPENAME_TEMPLATE:
34521 gmsgid = G_("expected %<class%>, %<typename%>, or %<template%>");
34522 break;
34523 default:
34524 gcc_unreachable ();
34525 }
34526 }
34527
34528 if (gmsgid)
34529 cp_parser_error_1 (parser, gmsgid, missing_token_desc: token_desc, matching_location);
34530}
34531
34532
34533/* If the next token is of the indicated TYPE, consume it. Otherwise,
34534 issue an error message indicating that TOKEN_DESC was expected.
34535
34536 Returns the token consumed, if the token had the appropriate type.
34537 Otherwise, returns NULL.
34538
34539 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
34540 within any error as the location of an "opening" token matching
34541 the close token TYPE (e.g. the location of the '(' when TOKEN_DESC is
34542 RT_CLOSE_PAREN). */
34543
34544static cp_token *
34545cp_parser_require (cp_parser* parser,
34546 enum cpp_ttype type,
34547 required_token token_desc,
34548 location_t matching_location)
34549{
34550 if (cp_lexer_next_token_is (lexer: parser->lexer, type))
34551 return cp_lexer_consume_token (lexer: parser->lexer);
34552 else
34553 {
34554 /* Output the MESSAGE -- unless we're parsing tentatively. */
34555 if (!cp_parser_simulate_error (parser))
34556 cp_parser_required_error (parser, token_desc, /*keyword=*/false,
34557 matching_location);
34558 return NULL;
34559 }
34560}
34561
34562/* Skip an entire parameter list from start to finish. The next token must
34563 be the initial "<" of the parameter list. Returns true on success and
34564 false otherwise. */
34565
34566static bool
34567cp_parser_skip_entire_template_parameter_list (cp_parser* parser)
34568{
34569 /* Consume the "<" because cp_parser_skip_to_end_of_template_parameter_list
34570 requires it. */
34571 cp_lexer_consume_token (lexer: parser->lexer);
34572 return cp_parser_skip_to_end_of_template_parameter_list (parser);
34573}
34574
34575/* Ensure we are at the end of a template parameter list. If we are, return.
34576 If we are not, something has gone wrong, in which case issue an error and
34577 skip to end of the parameter list. */
34578
34579static void
34580cp_parser_require_end_of_template_parameter_list (cp_parser* parser)
34581{
34582 /* Are we ready, yet? If not, issue error message. */
34583 if (cp_parser_require (parser, type: CPP_GREATER, token_desc: RT_GREATER))
34584 return;
34585
34586 cp_parser_skip_to_end_of_template_parameter_list (parser);
34587}
34588
34589/* You should only call this function from inside a template parameter list
34590 (i.e. the current token should at least be the initial "<" of the
34591 parameter list). If you are skipping the entire list, it may be better to
34592 use cp_parser_skip_entire_template_parameter_list.
34593
34594 Tokens are skipped until the final ">" is found, or if we see
34595 '{', '}', ';', or if we find an unbalanced ')' or ']'.
34596
34597 Returns true if we successfully reached the end, and false if
34598 something unexpected happened (e.g. end of file). */
34599
34600static bool
34601cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
34602{
34603 /* Current level of '< ... >'. */
34604 unsigned level = 0;
34605 /* Ignore '<' and '>' nested inside '( ... )' or '[ ... ]'. */
34606 unsigned nesting_depth = 0;
34607
34608 /* Skip tokens until the desired token is found. */
34609 while (true)
34610 {
34611 /* Peek at the next token. */
34612 switch (cp_lexer_peek_token (lexer: parser->lexer)->type)
34613 {
34614 case CPP_LESS:
34615 if (!nesting_depth)
34616 ++level;
34617 break;
34618
34619 case CPP_RSHIFT:
34620 if (cxx_dialect == cxx98)
34621 /* C++0x views the `>>' operator as two `>' tokens, but
34622 C++98 does not. */
34623 break;
34624 else if (!nesting_depth && level-- == 0)
34625 {
34626 /* We've hit a `>>' where the first `>' closes the
34627 template argument list, and the second `>' is
34628 spurious. Just consume the `>>' and stop; we've
34629 already produced at least one error. */
34630 cp_lexer_consume_token (lexer: parser->lexer);
34631 return false;
34632 }
34633 /* Fall through for C++0x, so we handle the second `>' in
34634 the `>>'. */
34635 gcc_fallthrough ();
34636
34637 case CPP_GREATER:
34638 if (!nesting_depth && level-- == 0)
34639 {
34640 /* We've reached the token we want, consume it and stop. */
34641 cp_lexer_consume_token (lexer: parser->lexer);
34642 return true;
34643 }
34644 break;
34645
34646 case CPP_OPEN_PAREN:
34647 case CPP_OPEN_SQUARE:
34648 ++nesting_depth;
34649 break;
34650
34651 case CPP_CLOSE_PAREN:
34652 case CPP_CLOSE_SQUARE:
34653 if (nesting_depth-- == 0)
34654 return false;
34655 break;
34656
34657 case CPP_EOF:
34658 case CPP_PRAGMA_EOL:
34659 case CPP_SEMICOLON:
34660 case CPP_OPEN_BRACE:
34661 case CPP_CLOSE_BRACE:
34662 /* The '>' was probably forgotten, don't look further. */
34663 return false;
34664
34665 default:
34666 break;
34667 }
34668
34669 /* Consume this token. */
34670 cp_lexer_consume_token (lexer: parser->lexer);
34671 }
34672}
34673
34674/* If the next token is the indicated keyword, consume it. Otherwise,
34675 issue an error message indicating that TOKEN_DESC was expected.
34676
34677 Returns the token consumed, if the token had the appropriate type.
34678 Otherwise, returns NULL. */
34679
34680static cp_token *
34681cp_parser_require_keyword (cp_parser* parser,
34682 enum rid keyword,
34683 required_token token_desc)
34684{
34685 cp_token *token = cp_parser_require (parser, type: CPP_KEYWORD, token_desc);
34686
34687 if (token && token->keyword != keyword)
34688 {
34689 cp_parser_required_error (parser, token_desc, /*keyword=*/true,
34690 UNKNOWN_LOCATION);
34691 return NULL;
34692 }
34693
34694 return token;
34695}
34696
34697/* Returns TRUE iff TOKEN is a token that can begin the body of a
34698 function-definition. */
34699
34700static bool
34701cp_parser_token_starts_function_definition_p (cp_token* token)
34702{
34703 return (/* An ordinary function-body begins with an `{'. */
34704 token->type == CPP_OPEN_BRACE
34705 /* A ctor-initializer begins with a `:'. */
34706 || token->type == CPP_COLON
34707 /* A function-try-block begins with `try'. */
34708 || token->keyword == RID_TRY
34709 /* A function-transaction-block begins with `__transaction_atomic'
34710 or `__transaction_relaxed'. */
34711 || token->keyword == RID_TRANSACTION_ATOMIC
34712 || token->keyword == RID_TRANSACTION_RELAXED
34713 /* The named return value extension begins with `return'. */
34714 || token->keyword == RID_RETURN);
34715}
34716
34717/* Returns TRUE iff the next token is the ":" or "{" beginning a class
34718 definition. */
34719
34720static bool
34721cp_parser_next_token_starts_class_definition_p (cp_parser *parser)
34722{
34723 cp_token *token;
34724
34725 token = cp_lexer_peek_token (lexer: parser->lexer);
34726 return (token->type == CPP_OPEN_BRACE
34727 || (token->type == CPP_COLON
34728 && !parser->colon_doesnt_start_class_def_p));
34729}
34730
34731/* Returns TRUE iff the next token is the "," or ">" (or `>>', in
34732 C++0x) ending a template-argument. */
34733
34734static bool
34735cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
34736{
34737 cp_token *token;
34738
34739 token = cp_lexer_peek_token (lexer: parser->lexer);
34740 return (token->type == CPP_COMMA
34741 || token->type == CPP_GREATER
34742 || token->type == CPP_ELLIPSIS
34743 || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)
34744 /* For better diagnostics, treat >>= like that too, that
34745 shouldn't appear non-nested in template arguments. */
34746 || token->type == CPP_RSHIFT_EQ);
34747}
34748
34749/* Returns TRUE iff the n-th token is a "<", or the n-th is a "[" and the
34750 (n+1)-th is a ":" (which is a possible digraph typo for "< ::"). */
34751
34752static bool
34753cp_parser_nth_token_starts_template_argument_list_p (cp_parser * parser,
34754 size_t n)
34755{
34756 cp_token *token;
34757
34758 token = cp_lexer_peek_nth_token (lexer: parser->lexer, n);
34759 if (token->type == CPP_LESS)
34760 return true;
34761 /* Check for the sequence `<::' in the original code. It would be lexed as
34762 `[:', where `[' is a digraph, and there is no whitespace before
34763 `:'. */
34764 if (token->type == CPP_OPEN_SQUARE && token->flags & DIGRAPH)
34765 {
34766 cp_token *token2;
34767 token2 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: n+1);
34768 if (token2->type == CPP_COLON && !(token2->flags & PREV_WHITE))
34769 return true;
34770 }
34771 return false;
34772}
34773
34774/* Returns the kind of tag indicated by TOKEN, if it is a class-key,
34775 or none_type otherwise. */
34776
34777static enum tag_types
34778cp_parser_token_is_class_key (cp_token* token)
34779{
34780 switch (token->keyword)
34781 {
34782 case RID_CLASS:
34783 return class_type;
34784 case RID_STRUCT:
34785 return record_type;
34786 case RID_UNION:
34787 return union_type;
34788
34789 default:
34790 return none_type;
34791 }
34792}
34793
34794/* Returns the kind of tag indicated by TOKEN, if it is a type-parameter-key,
34795 or none_type otherwise or if the token is null. */
34796
34797static enum tag_types
34798cp_parser_token_is_type_parameter_key (cp_token* token)
34799{
34800 if (!token)
34801 return none_type;
34802
34803 switch (token->keyword)
34804 {
34805 case RID_CLASS:
34806 return class_type;
34807 case RID_TYPENAME:
34808 return typename_type;
34809
34810 default:
34811 return none_type;
34812 }
34813}
34814
34815/* Diagnose redundant enum-keys. */
34816
34817static void
34818cp_parser_maybe_warn_enum_key (cp_parser *parser, location_t key_loc,
34819 tree type, rid scoped_key)
34820{
34821 if (!warn_redundant_tags)
34822 return;
34823
34824 tree type_decl = TYPE_MAIN_DECL (type);
34825 tree name = DECL_NAME (type_decl);
34826 /* Look up the NAME to see if it unambiguously refers to the TYPE. */
34827 push_deferring_access_checks (dk_no_check);
34828 tree decl = cp_parser_lookup_name_simple (parser, name, location: input_location);
34829 pop_deferring_access_checks ();
34830
34831 /* The enum-key is redundant for uses of the TYPE that are not
34832 declarations and for which name lookup returns just the type
34833 itself. */
34834 if (decl != type_decl)
34835 return;
34836
34837 if (scoped_key != RID_CLASS
34838 && scoped_key != RID_STRUCT
34839 && current_lang_name != lang_name_cplusplus
34840 && current_namespace == global_namespace)
34841 {
34842 /* Avoid issuing the diagnostic for apparently redundant (unscoped)
34843 enum tag in shared C/C++ code in files (such as headers) included
34844 in the main source file. */
34845 const line_map_ordinary *map = NULL;
34846 linemap_resolve_location (line_table, loc: key_loc,
34847 lrk: LRK_MACRO_DEFINITION_LOCATION,
34848 loc_map: &map);
34849 if (!MAIN_FILE_P (ord_map: map))
34850 return;
34851 }
34852
34853 gcc_rich_location richloc (key_loc);
34854 richloc.add_fixit_remove (where: key_loc);
34855 warning_at (&richloc, OPT_Wredundant_tags,
34856 "redundant enum-key %<enum%s%> in reference to %q#T",
34857 (scoped_key == RID_CLASS ? " class"
34858 : scoped_key == RID_STRUCT ? " struct" : ""), type);
34859}
34860
34861/* Describes the set of declarations of a struct, class, or class template
34862 or its specializations. Used for -Wmismatched-tags. */
34863
34864class class_decl_loc_t
34865{
34866 public:
34867
34868 class_decl_loc_t ()
34869 : locvec (), idxdef (), def_class_key ()
34870 {
34871 locvec.create (nelems: 4);
34872 }
34873
34874 /* Constructs an object for a single declaration of a class with
34875 CLASS_KEY at the current location in the current function (or
34876 at another scope). KEY_REDUNDANT is true if the class-key may
34877 be omitted in the current context without an ambiguity with
34878 another symbol with the same name.
34879 DEF_P is true for a class declaration that is a definition.
34880 CURLOC is the associated location. */
34881 class_decl_loc_t (tag_types class_key, bool key_redundant, bool def_p,
34882 location_t curloc = input_location)
34883 : locvec (), idxdef (def_p ? 0 : UINT_MAX), def_class_key (class_key)
34884 {
34885 locvec.create (nelems: 4);
34886 class_key_loc_t ckl (current_function_decl, curloc, class_key,
34887 key_redundant);
34888 locvec.quick_push (obj: ckl);
34889 }
34890
34891 /* Copy, assign, and destroy the object. Necessary because LOCVEC
34892 isn't safely copyable and assignable and doesn't release storage
34893 on its own. */
34894 class_decl_loc_t (const class_decl_loc_t &rhs)
34895 : locvec (rhs.locvec.copy ()), idxdef (rhs.idxdef),
34896 def_class_key (rhs.def_class_key)
34897 { }
34898
34899 class_decl_loc_t& operator= (const class_decl_loc_t &rhs)
34900 {
34901 if (this == &rhs)
34902 return *this;
34903 locvec.release ();
34904 locvec = rhs.locvec.copy ();
34905 idxdef = rhs.idxdef;
34906 def_class_key = rhs.def_class_key;
34907 return *this;
34908 }
34909
34910 ~class_decl_loc_t ()
34911 {
34912 locvec.release ();
34913 }
34914
34915 /* Issues -Wmismatched-tags for a single class. */
34916 void diag_mismatched_tags (tree);
34917
34918 /* Issues -Wmismatched-tags for all classes. */
34919 static void diag_mismatched_tags ();
34920
34921 /* Adds TYPE_DECL to the collection of class decls and diagnoses
34922 redundant tags (if -Wredundant-tags is enabled). */
34923 static void add (cp_parser *, location_t, tag_types, tree, bool, bool);
34924
34925 /* Either adds this decl to the collection of class decls
34926 or diagnoses it, whichever is appropriate. */
34927 void add_or_diag_mismatched_tag (tree, tag_types, bool, bool);
34928
34929private:
34930
34931 tree function (unsigned i) const
34932 {
34933 return locvec[i].func;
34934 }
34935
34936 location_t location (unsigned i) const
34937 {
34938 return locvec[i].loc;
34939 }
34940
34941 bool key_redundant (unsigned i) const
34942 {
34943 return locvec[i].key_redundant;
34944 }
34945
34946 tag_types class_key (unsigned i) const
34947 {
34948 return locvec[i].class_key;
34949 }
34950
34951 /* True if a definition for the class has been seen. */
34952 bool def_p () const
34953 {
34954 return idxdef < locvec.length ();
34955 }
34956
34957 /* The location of a single mention of a class type with the given
34958 class-key. */
34959 struct class_key_loc_t
34960 {
34961 class_key_loc_t (tree func, location_t loc, tag_types key, bool redundant)
34962 : func (func), loc (loc), class_key (key), key_redundant (redundant)
34963 { }
34964
34965 /* The function the type is mentioned in. */
34966 tree func;
34967 /* The exact location. */
34968 location_t loc;
34969 /* The class-key used in the mention of the type. */
34970 tag_types class_key;
34971 /* True when the class-key could be omitted at this location
34972 without an ambiguity with another symbol of the same name. */
34973 bool key_redundant;
34974 };
34975 /* Avoid using auto_vec here since it's not safe to copy due to pr90904. */
34976 vec <class_key_loc_t> locvec;
34977 /* LOCVEC index of the definition or UINT_MAX if none exists. */
34978 unsigned idxdef;
34979 /* The class-key the class was last declared with or none_type when
34980 it has been declared with a mismatched key. */
34981 tag_types def_class_key;
34982
34983 /* A mapping between a TYPE_DECL for a class and the class_decl_loc_t
34984 description above. */
34985 typedef hash_map<tree_decl_hash, class_decl_loc_t> class_to_loc_map_t;
34986 static class_to_loc_map_t class2loc;
34987};
34988
34989class_decl_loc_t::class_to_loc_map_t class_decl_loc_t::class2loc;
34990
34991/* Issue an error message if the CLASS_KEY does not match the TYPE.
34992 DEF_P is expected to be set for a definition of class TYPE. DECL_P
34993 is set for a declaration of class TYPE and clear for a reference to
34994 it that is not a declaration of it. */
34995
34996static void
34997cp_parser_check_class_key (cp_parser *parser, location_t key_loc,
34998 tag_types class_key, tree type, bool def_p,
34999 bool decl_p)
35000{
35001 if (type == error_mark_node)
35002 return;
35003
35004 bool seen_as_union = TREE_CODE (type) == UNION_TYPE;
35005 if (seen_as_union != (class_key == union_type))
35006 {
35007 if (permerror (input_location, "%qs tag used in naming %q#T",
35008 class_key == union_type ? "union"
35009 : class_key == record_type ? "struct" : "class",
35010 type))
35011 inform (DECL_SOURCE_LOCATION (TYPE_NAME (type)),
35012 "%q#T was previously declared here", type);
35013 return;
35014 }
35015
35016 if (!warn_mismatched_tags && !warn_redundant_tags)
35017 return;
35018
35019 /* Only consider the true class-keys below and ignore typename_type,
35020 etc. that are not C++ class-keys. */
35021 if (class_key != class_type
35022 && class_key != record_type
35023 && class_key != union_type)
35024 return;
35025
35026 class_decl_loc_t::add (parser, key_loc, class_key, type, def_p, decl_p);
35027}
35028
35029/* Returns the template or specialization of one to which the RECORD_TYPE
35030 TYPE corresponds. */
35031
35032static tree
35033specialization_of (tree type)
35034{
35035 tree ret = type;
35036
35037 /* Determine the template or its partial specialization to which TYPE
35038 corresponds. */
35039 if (tree ti = most_specialized_partial_spec (type, tf_none))
35040 if (ti != error_mark_node)
35041 ret = TREE_TYPE (TI_TEMPLATE (ti));
35042
35043 if (ret == type)
35044 ret = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (type);
35045
35046 return TYPE_MAIN_DECL (ret);
35047}
35048
35049
35050/* Adds the class TYPE to the collection of class decls and diagnoses
35051 redundant tags (if -Wredundant-tags is enabled).
35052 DEF_P is expected to be set for a definition of class TYPE. DECL_P
35053 is set for a (likely, based on syntactic context) declaration of class
35054 TYPE and clear for a reference to it that is not a declaration of it. */
35055
35056void
35057class_decl_loc_t::add (cp_parser *parser, location_t key_loc,
35058 tag_types class_key, tree type, bool def_p, bool decl_p)
35059{
35060 tree type_decl = TYPE_MAIN_DECL (type);
35061 tree name = DECL_NAME (type_decl);
35062 /* Look up the NAME to see if it unambiguously refers to the TYPE
35063 and set KEY_REDUNDANT if so. */
35064 push_deferring_access_checks (dk_no_check);
35065 tree decl = cp_parser_lookup_name_simple (parser, name, location: input_location);
35066 pop_deferring_access_checks ();
35067
35068 /* The class-key is redundant for uses of the CLASS_TYPE that are
35069 neither definitions of it nor declarations, and for which name
35070 lookup returns just the type itself. */
35071 bool key_redundant = (!def_p && !decl_p
35072 && (decl == type_decl
35073 || TREE_CODE (decl) == TEMPLATE_DECL
35074 || (CLASS_TYPE_P (type)
35075 && TYPE_BEING_DEFINED (type))));
35076
35077 if (key_redundant
35078 && class_key != class_type
35079 && current_lang_name != lang_name_cplusplus
35080 && current_namespace == global_namespace)
35081 {
35082 /* Avoid issuing the diagnostic for apparently redundant struct
35083 and union class-keys in shared C/C++ code in files (such as
35084 headers) included in the main source file. */
35085 const line_map_ordinary *map = NULL;
35086 linemap_resolve_location (line_table, loc: key_loc,
35087 lrk: LRK_MACRO_DEFINITION_LOCATION,
35088 loc_map: &map);
35089 if (!MAIN_FILE_P (ord_map: map))
35090 key_redundant = false;
35091 }
35092
35093 /* Set if a declaration of TYPE has previously been seen or if it must
35094 exist in a precompiled header. */
35095 bool exist;
35096 class_decl_loc_t *rdl = &class2loc.get_or_insert (k: type_decl, existed: &exist);
35097 if (!exist)
35098 {
35099 tree type = TREE_TYPE (type_decl);
35100 if (def_p || !COMPLETE_TYPE_P (type))
35101 {
35102 /* TYPE_DECL is the first declaration or definition of the type
35103 (outside precompiled headers -- see below). Just create
35104 a new entry for it and return unless it's a declaration
35105 involving a template that may need to be diagnosed by
35106 -Wredundant-tags. */
35107 *rdl = class_decl_loc_t (class_key, false, def_p);
35108 if (TREE_CODE (decl) != TEMPLATE_DECL)
35109 return;
35110 }
35111 else
35112 {
35113 /* TYPE was previously defined in some unknown precompiled header.
35114 Simply add a record of its definition at an unknown location and
35115 proceed below to add a reference to it at the current location.
35116 (Declarations in precompiled headers that are not definitions
35117 are ignored.) */
35118 tag_types def_key
35119 = CLASSTYPE_DECLARED_CLASS (type) ? class_type : record_type;
35120 location_t def_loc = DECL_SOURCE_LOCATION (type_decl);
35121 *rdl = class_decl_loc_t (def_key, false, true, def_loc);
35122 exist = true;
35123 }
35124 }
35125
35126 /* A prior declaration of TYPE_DECL has been seen. */
35127
35128 if (key_redundant)
35129 {
35130 gcc_rich_location richloc (key_loc);
35131 richloc.add_fixit_remove (where: key_loc);
35132 warning_at (&richloc, OPT_Wredundant_tags,
35133 "redundant class-key %qs in reference to %q#T",
35134 class_key == union_type ? "union"
35135 : class_key == record_type ? "struct" : "class",
35136 type);
35137 }
35138
35139 if (!exist)
35140 /* Do nothing if this is the first declaration of the type. */
35141 return;
35142
35143 if (rdl->idxdef != UINT_MAX && rdl->def_class_key == class_key)
35144 /* Do nothing if the class-key in this declaration matches
35145 the definition. */
35146 return;
35147
35148 rdl->add_or_diag_mismatched_tag (type_decl, class_key, key_redundant,
35149 def_p);
35150}
35151
35152/* Either adds this DECL corresponding to the TYPE_DECL to the collection
35153 of class decls or diagnoses it, whichever is appropriate. */
35154
35155void
35156class_decl_loc_t::add_or_diag_mismatched_tag (tree type_decl,
35157 tag_types class_key,
35158 bool redundant,
35159 bool def_p)
35160{
35161 /* Reset the CLASS_KEY associated with this type on mismatch.
35162 This is an optimization that lets the diagnostic code skip
35163 over classes that use the same class-key in all declarations. */
35164 if (def_class_key != class_key)
35165 def_class_key = none_type;
35166
35167 /* Set IDXDEF to the index of the vector corresponding to
35168 the definition. */
35169 if (def_p)
35170 idxdef = locvec.length ();
35171
35172 /* Append a record of this declaration to the vector. */
35173 class_key_loc_t ckl (current_function_decl, input_location, class_key,
35174 redundant);
35175 locvec.safe_push (obj: ckl);
35176
35177 if (idxdef == UINT_MAX)
35178 return;
35179
35180 /* As a space optimization diagnose declarations of a class
35181 whose definition has been seen and purge the LOCVEC of
35182 all entries except the definition. */
35183 diag_mismatched_tags (type_decl);
35184 if (idxdef)
35185 {
35186 class_decl_loc_t::class_key_loc_t ent = locvec[idxdef];
35187 locvec.release ();
35188 locvec.reserve (nelems: 2);
35189 locvec.safe_push (obj: ent);
35190 idxdef = 0;
35191 }
35192 else
35193 /* Pop the entry pushed above for this declaration. */
35194 locvec.pop ();
35195}
35196
35197/* Issues -Wmismatched-tags for a single class. */
35198
35199void
35200class_decl_loc_t::diag_mismatched_tags (tree type_decl)
35201{
35202 if (!warn_mismatched_tags)
35203 return;
35204
35205 /* Number of uses of the class. */
35206 const unsigned ndecls = locvec.length ();
35207
35208 /* The class (or template) declaration guiding the decisions about
35209 the diagnostic. For ordinary classes it's the same as THIS. For
35210 uses of instantiations of templates other than their declarations
35211 it points to the record for the declaration of the corresponding
35212 primary template or partial specialization. */
35213 class_decl_loc_t *cdlguide = this;
35214
35215 tree type = TREE_TYPE (type_decl);
35216 if (CLASS_TYPE_P (type) && CLASSTYPE_IMPLICIT_INSTANTIATION (type))
35217 {
35218 /* For implicit instantiations of a primary template look up
35219 the primary or partial specialization and use it as
35220 the expected class-key rather than using the class-key of
35221 the first reference to the instantiation. The primary must
35222 be (and inevitably is) at index zero. */
35223 tree spec = specialization_of (type);
35224 cdlguide = class2loc.get (k: spec);
35225 /* It's possible that we didn't find SPEC. Consider:
35226
35227 template<typename T> struct A {
35228 template<typename U> struct W { };
35229 };
35230 struct A<int>::W<int> w; // #1
35231
35232 where while parsing A and #1 we've stashed
35233 A<T>
35234 A<T>::W<U>
35235 A<int>::W<int>
35236 into CLASS2LOC. If TYPE is A<int>::W<int>, specialization_of
35237 will yield A<int>::W<U> which may be in CLASS2LOC if we had
35238 an A<int> class specialization, but otherwise won't be in it.
35239 So try to look up A<T>::W<U>. */
35240 if (!cdlguide)
35241 {
35242 spec = DECL_TEMPLATE_RESULT (most_general_template (spec));
35243 cdlguide = class2loc.get (k: spec);
35244 }
35245 /* Now we really should have found something. */
35246 gcc_assert (cdlguide != NULL);
35247 }
35248 /* Skip declarations that consistently use the same class-key. */
35249 else if (def_class_key != none_type)
35250 return;
35251
35252 /* Set if a definition for the class has been seen. */
35253 const bool def_p = cdlguide->def_p ();
35254
35255 /* The index of the declaration whose class-key this declaration
35256 is expected to match. It's either the class-key of the class
35257 definition if one exists or the first declaration otherwise. */
35258 const unsigned idxguide = def_p ? cdlguide->idxdef : 0;
35259
35260 /* The class-key the class is expected to be declared with: it's
35261 either the key used in its definition or the first declaration
35262 if no definition has been provided.
35263 For implicit instantiations of a primary template it's
35264 the class-key used to declare the primary with. The primary
35265 must be at index zero. */
35266 const tag_types xpect_key = cdlguide->class_key (i: idxguide);
35267
35268 unsigned idx = 0;
35269 /* Advance IDX to the first declaration that either is not
35270 a definition or that doesn't match the first declaration
35271 if no definition is provided. */
35272 while (class_key (i: idx) == xpect_key)
35273 if (++idx == ndecls)
35274 return;
35275
35276 /* Save the current function before changing it below. */
35277 tree save_func = current_function_decl;
35278 /* Set the function declaration to print in diagnostic context. */
35279 current_function_decl = function (i: idx);
35280
35281 const char *xmatchkstr = xpect_key == record_type ? "class" : "struct";
35282 const char *xpectkstr = xpect_key == record_type ? "struct" : "class";
35283
35284 location_t loc = location (i: idx);
35285 bool key_redundant_p = key_redundant (i: idx);
35286 auto_diagnostic_group d;
35287 /* Issue a warning for the first mismatched declaration.
35288 Avoid using "%#qT" since the class-key for the same type will
35289 be the same regardless of which one was used in the declaraion. */
35290 if (warning_at (loc, OPT_Wmismatched_tags,
35291 "%qT declared with a mismatched class-key %qs",
35292 type_decl, xmatchkstr))
35293 {
35294 /* Suggest how to avoid the warning for each instance since
35295 the guidance may be different depending on context. */
35296 inform (loc,
35297 (key_redundant_p
35298 ? G_("remove the class-key or replace it with %qs")
35299 : G_("replace the class-key with %qs")),
35300 xpectkstr);
35301
35302 /* Also point to the first declaration or definition that guided
35303 the decision to issue the warning above. */
35304 inform (cdlguide->location (i: idxguide),
35305 (def_p
35306 ? G_("%qT defined as %qs here")
35307 : G_("%qT first declared as %qs here")),
35308 type_decl, xpectkstr);
35309 }
35310
35311 /* Issue warnings for the remaining inconsistent declarations. */
35312 for (unsigned i = idx + 1; i != ndecls; ++i)
35313 {
35314 tag_types clskey = class_key (i);
35315 /* Skip over the declarations that match either the definition
35316 if one was provided or the first declaration. */
35317 if (clskey == xpect_key)
35318 continue;
35319
35320 loc = location (i);
35321 key_redundant_p = key_redundant (i);
35322 /* Set the function declaration to print in diagnostic context. */
35323 current_function_decl = function (i);
35324 if (warning_at (loc, OPT_Wmismatched_tags,
35325 "%qT declared with a mismatched class-key %qs",
35326 type_decl, xmatchkstr))
35327 /* Suggest how to avoid the warning for each instance since
35328 the guidance may be different depending on context. */
35329 inform (loc,
35330 (key_redundant_p
35331 ? G_("remove the class-key or replace it with %qs")
35332 : G_("replace the class-key with %qs")),
35333 xpectkstr);
35334 }
35335
35336 /* Restore the current function in case it was replaced above. */
35337 current_function_decl = save_func;
35338}
35339
35340/* Issues -Wmismatched-tags for all classes. Called at the end
35341 of processing a translation unit, after declarations of all class
35342 types and their uses have been recorded. */
35343
35344void
35345class_decl_loc_t::diag_mismatched_tags ()
35346{
35347 /* CLASS2LOC should be empty if both -Wmismatched-tags and
35348 -Wredundant-tags are disabled. */
35349 gcc_assert (warn_mismatched_tags
35350 || warn_redundant_tags
35351 || class2loc.is_empty ());
35352
35353 /* Save the current function before changing on return. It should
35354 be null at this point. */
35355 temp_override<tree> cleanup (current_function_decl);
35356
35357 if (warn_mismatched_tags)
35358 {
35359 /* Iterate over the collected class/struct/template declarations. */
35360 typedef class_to_loc_map_t::iterator iter_t;
35361 for (iter_t it = class2loc.begin (); it != class2loc.end (); ++it)
35362 {
35363 tree type_decl = (*it).first;
35364 class_decl_loc_t &recloc = (*it).second;
35365 recloc.diag_mismatched_tags (type_decl);
35366 }
35367 }
35368
35369 class2loc.empty ();
35370}
35371
35372/* Issue an error message if DECL is redeclared with different
35373 access than its original declaration [class.access.spec/3].
35374 This applies to nested classes, nested class templates and
35375 enumerations [class.mem/1]. */
35376
35377static void
35378cp_parser_check_access_in_redeclaration (tree decl, location_t location)
35379{
35380 if (!decl
35381 || (!(CLASS_TYPE_P (TREE_TYPE (decl))
35382 && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
35383 && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE))
35384 return;
35385
35386 if ((TREE_PRIVATE (decl)
35387 != (current_access_specifier == access_private_node))
35388 || (TREE_PROTECTED (decl)
35389 != (current_access_specifier == access_protected_node)))
35390 error_at (location, "%qD redeclared with different access", decl);
35391}
35392
35393/* Look for the `template' keyword, as a syntactic disambiguator.
35394 Return TRUE iff it is present, in which case it will be
35395 consumed. */
35396
35397static bool
35398cp_parser_optional_template_keyword (cp_parser *parser)
35399{
35400 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TEMPLATE))
35401 {
35402 /* In C++98 the `template' keyword can only be used within templates;
35403 outside templates the parser can always figure out what is a
35404 template and what is not. In C++11, per the resolution of DR 468,
35405 `template' is allowed in cases where it is not strictly necessary. */
35406 if (!processing_template_decl
35407 && pedantic && cxx_dialect == cxx98)
35408 {
35409 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
35410 pedwarn (token->location, OPT_Wpedantic,
35411 "in C++98 %<template%> (as a disambiguator) is only "
35412 "allowed within templates");
35413 /* If this part of the token stream is rescanned, the same
35414 error message would be generated. So, we purge the token
35415 from the stream. */
35416 cp_lexer_purge_token (lexer: parser->lexer);
35417 return false;
35418 }
35419 else
35420 {
35421 /* Consume the `template' keyword. */
35422 cp_lexer_consume_token (lexer: parser->lexer);
35423 return true;
35424 }
35425 }
35426 return false;
35427}
35428
35429/* The next token is a CPP_NESTED_NAME_SPECIFIER. Consume the token,
35430 set PARSER->SCOPE, and perform other related actions. */
35431
35432static void
35433cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
35434{
35435 struct tree_check *check_value;
35436
35437 /* Get the stored value. */
35438 check_value = cp_lexer_consume_token (lexer: parser->lexer)->u.tree_check_value;
35439 /* Set the scope from the stored value. */
35440 parser->scope = saved_checks_value (check_value);
35441 parser->qualifying_scope = check_value->qualifying_scope;
35442 parser->object_scope = parser->context->object_type;
35443 parser->context->object_type = NULL_TREE;
35444}
35445
35446/* Consume tokens up through a non-nested END token. Returns TRUE if we
35447 encounter the end of a block before what we were looking for. */
35448
35449static bool
35450cp_parser_cache_group (cp_parser *parser,
35451 enum cpp_ttype end,
35452 unsigned depth)
35453{
35454 while (true)
35455 {
35456 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
35457
35458 /* Abort a parenthesized expression if we encounter a semicolon. */
35459 if ((end == CPP_CLOSE_PAREN || depth == 0)
35460 && token->type == CPP_SEMICOLON)
35461 return true;
35462 /* If we've reached the end of the file, stop. */
35463 if (token->type == CPP_EOF
35464 || (end != CPP_PRAGMA_EOL
35465 && token->type == CPP_PRAGMA_EOL))
35466 return true;
35467 if (token->type == CPP_CLOSE_BRACE && depth == 0)
35468 /* We've hit the end of an enclosing block, so there's been some
35469 kind of syntax error. */
35470 return true;
35471
35472 /* Consume the token. */
35473 cp_lexer_consume_token (lexer: parser->lexer);
35474 /* See if it starts a new group. */
35475 if (token->type == CPP_OPEN_BRACE)
35476 {
35477 cp_parser_cache_group (parser, end: CPP_CLOSE_BRACE, depth: depth + 1);
35478 /* In theory this should probably check end == '}', but
35479 cp_parser_save_member_function_body needs it to exit
35480 after either '}' or ')' when called with ')'. */
35481 if (depth == 0)
35482 return false;
35483 }
35484 else if (token->type == CPP_OPEN_PAREN)
35485 {
35486 cp_parser_cache_group (parser, end: CPP_CLOSE_PAREN, depth: depth + 1);
35487 if (depth == 0 && end == CPP_CLOSE_PAREN)
35488 return false;
35489 }
35490 else if (token->type == CPP_PRAGMA)
35491 cp_parser_cache_group (parser, end: CPP_PRAGMA_EOL, depth: depth + 1);
35492 else if (token->type == end)
35493 return false;
35494 }
35495}
35496
35497/* Like above, for caching a default argument or NSDMI. Both of these are
35498 terminated by a non-nested comma, but it can be unclear whether or not a
35499 comma is nested in a template argument list unless we do more parsing.
35500 In order to handle this ambiguity, when we encounter a ',' after a '<'
35501 we try to parse what follows as a parameter-declaration-list (in the
35502 case of a default argument) or a member-declarator (in the case of an
35503 NSDMI). If that succeeds, then we stop caching. */
35504
35505static tree
35506cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
35507{
35508 unsigned depth = 0;
35509 int maybe_template_id = 0;
35510 cp_token *first_token;
35511 cp_token *token;
35512 tree default_argument;
35513
35514 /* Add tokens until we have processed the entire default
35515 argument. We add the range [first_token, token). */
35516 first_token = cp_lexer_peek_token (lexer: parser->lexer);
35517 if (first_token->type == CPP_OPEN_BRACE)
35518 {
35519 /* For list-initialization, this is straightforward. */
35520 cp_parser_cache_group (parser, end: CPP_CLOSE_BRACE, /*depth=*/0);
35521 token = cp_lexer_peek_token (lexer: parser->lexer);
35522 }
35523 else while (true)
35524 {
35525 bool done = false;
35526
35527 /* Peek at the next token. */
35528 token = cp_lexer_peek_token (lexer: parser->lexer);
35529 /* What we do depends on what token we have. */
35530 switch (token->type)
35531 {
35532 /* In valid code, a default argument must be
35533 immediately followed by a `,' `)', or `...'. */
35534 case CPP_COMMA:
35535 if (depth == 0 && maybe_template_id)
35536 {
35537 /* If we've seen a '<', we might be in a
35538 template-argument-list. Until Core issue 325 is
35539 resolved, we don't know how this situation ought
35540 to be handled, so try to DTRT. We check whether
35541 what comes after the comma is a valid parameter
35542 declaration list. If it is, then the comma ends
35543 the default argument; otherwise the default
35544 argument continues. */
35545 bool error = false;
35546 cp_token *peek;
35547
35548 /* Set ITALP so cp_parser_parameter_declaration_list
35549 doesn't decide to commit to this parse. */
35550 bool saved_italp = parser->in_template_argument_list_p;
35551 parser->in_template_argument_list_p = true;
35552
35553 cp_parser_parse_tentatively (parser);
35554
35555 if (nsdmi)
35556 {
35557 /* Parse declarators until we reach a non-comma or
35558 somthing that cannot be an initializer.
35559 Just checking whether we're looking at a single
35560 declarator is insufficient. Consider:
35561 int var = tuple<T,U>::x;
35562 The template parameter 'U' looks exactly like a
35563 declarator. */
35564 do
35565 {
35566 int ctor_dtor_or_conv_p;
35567 cp_lexer_consume_token (lexer: parser->lexer);
35568 cp_parser_declarator (parser, dcl_kind: CP_PARSER_DECLARATOR_NAMED,
35569 flags: CP_PARSER_FLAGS_NONE,
35570 ctor_dtor_or_conv_p: &ctor_dtor_or_conv_p,
35571 /*parenthesized_p=*/NULL,
35572 /*member_p=*/true,
35573 /*friend_p=*/false,
35574 /*static_p=*/false);
35575 peek = cp_lexer_peek_token (lexer: parser->lexer);
35576 if (cp_parser_error_occurred (parser))
35577 break;
35578 }
35579 while (peek->type == CPP_COMMA);
35580 /* If we met an '=' or ';' then the original comma
35581 was the end of the NSDMI. Otherwise assume
35582 we're still in the NSDMI. */
35583 error = (peek->type != CPP_EQ
35584 && peek->type != CPP_SEMICOLON);
35585 }
35586 else
35587 {
35588 cp_lexer_consume_token (lexer: parser->lexer);
35589 begin_scope (sk_function_parms, NULL_TREE);
35590 tree t = cp_parser_parameter_declaration_list
35591 (parser, flags: CP_PARSER_FLAGS_NONE,
35592 /*pending_decls*/nullptr);
35593 if (t == error_mark_node)
35594 error = true;
35595 pop_bindings_and_leave_scope ();
35596 }
35597 if (!cp_parser_error_occurred (parser) && !error)
35598 done = true;
35599 cp_parser_abort_tentative_parse (parser);
35600
35601 parser->in_template_argument_list_p = saved_italp;
35602 break;
35603 }
35604 /* FALLTHRU */
35605 case CPP_CLOSE_PAREN:
35606 case CPP_ELLIPSIS:
35607 /* If we run into a non-nested `;', `}', or `]',
35608 then the code is invalid -- but the default
35609 argument is certainly over. */
35610 case CPP_SEMICOLON:
35611 case CPP_CLOSE_BRACE:
35612 case CPP_CLOSE_SQUARE:
35613 if (depth == 0
35614 /* Handle correctly int n = sizeof ... ( p ); */
35615 && token->type != CPP_ELLIPSIS)
35616 done = true;
35617 /* Update DEPTH, if necessary. */
35618 else if (token->type == CPP_CLOSE_PAREN
35619 || token->type == CPP_CLOSE_BRACE
35620 || token->type == CPP_CLOSE_SQUARE)
35621 --depth;
35622 break;
35623
35624 case CPP_OPEN_PAREN:
35625 case CPP_OPEN_SQUARE:
35626 case CPP_OPEN_BRACE:
35627 ++depth;
35628 break;
35629
35630 case CPP_LESS:
35631 if (depth == 0)
35632 /* This might be the comparison operator, or it might
35633 start a template argument list. */
35634 ++maybe_template_id;
35635 break;
35636
35637 case CPP_RSHIFT:
35638 if (cxx_dialect == cxx98)
35639 break;
35640 /* Fall through for C++0x, which treats the `>>'
35641 operator like two `>' tokens in certain
35642 cases. */
35643 gcc_fallthrough ();
35644
35645 case CPP_GREATER:
35646 if (depth == 0)
35647 {
35648 /* This might be an operator, or it might close a
35649 template argument list. But if a previous '<'
35650 started a template argument list, this will have
35651 closed it, so we can't be in one anymore. */
35652 maybe_template_id -= 1 + (token->type == CPP_RSHIFT);
35653 if (maybe_template_id < 0)
35654 maybe_template_id = 0;
35655 }
35656 break;
35657
35658 /* If we run out of tokens, issue an error message. */
35659 case CPP_EOF:
35660 case CPP_PRAGMA_EOL:
35661 error_at (token->location, "file ends in default argument");
35662 return error_mark_node;
35663
35664 case CPP_NAME:
35665 case CPP_SCOPE:
35666 /* In these cases, we should look for template-ids.
35667 For example, if the default argument is
35668 `X<int, double>()', we need to do name lookup to
35669 figure out whether or not `X' is a template; if
35670 so, the `,' does not end the default argument.
35671
35672 That is not yet done. */
35673 break;
35674
35675 default:
35676 break;
35677 }
35678
35679 /* If we've reached the end, stop. */
35680 if (done)
35681 break;
35682
35683 /* Add the token to the token block. */
35684 token = cp_lexer_consume_token (lexer: parser->lexer);
35685 }
35686
35687 /* Create a DEFERRED_PARSE to represent the unparsed default
35688 argument. */
35689 default_argument = make_node (DEFERRED_PARSE);
35690 DEFPARSE_TOKENS (default_argument)
35691 = cp_token_cache_new (first: first_token, last: token);
35692 DEFPARSE_INSTANTIATIONS (default_argument) = NULL;
35693
35694 return default_argument;
35695}
35696
35697/* A location to use for diagnostics about an unparsed DEFERRED_PARSE. */
35698
35699location_t
35700defparse_location (tree default_argument)
35701{
35702 cp_token_cache *tokens = DEFPARSE_TOKENS (default_argument);
35703 location_t start = tokens->first->location;
35704 location_t end = tokens->last->location;
35705 return make_location (caret: start, start, finish: end);
35706}
35707
35708/* Begin parsing tentatively. We always save tokens while parsing
35709 tentatively so that if the tentative parsing fails we can restore the
35710 tokens. */
35711
35712static void
35713cp_parser_parse_tentatively (cp_parser* parser)
35714{
35715 /* Enter a new parsing context. */
35716 parser->context = cp_parser_context_new (next: parser->context);
35717 /* Begin saving tokens. */
35718 cp_lexer_save_tokens (lexer: parser->lexer);
35719 /* In order to avoid repetitive access control error messages,
35720 access checks are queued up until we are no longer parsing
35721 tentatively. */
35722 push_deferring_access_checks (dk_deferred);
35723}
35724
35725/* Commit to the currently active tentative parse. */
35726
35727static void
35728cp_parser_commit_to_tentative_parse (cp_parser* parser)
35729{
35730 cp_parser_context *context;
35731 cp_lexer *lexer;
35732
35733 /* Mark all of the levels as committed. */
35734 lexer = parser->lexer;
35735 for (context = parser->context; context->next; context = context->next)
35736 {
35737 if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
35738 break;
35739 context->status = CP_PARSER_STATUS_KIND_COMMITTED;
35740 while (!cp_lexer_saving_tokens (lexer))
35741 lexer = lexer->next;
35742 cp_lexer_commit_tokens (lexer);
35743 }
35744}
35745
35746/* Commit to the topmost currently active tentative parse.
35747
35748 Note that this function shouldn't be called when there are
35749 irreversible side-effects while in a tentative state. For
35750 example, we shouldn't create a permanent entry in the symbol
35751 table, or issue an error message that might not apply if the
35752 tentative parse is aborted. */
35753
35754static void
35755cp_parser_commit_to_topmost_tentative_parse (cp_parser* parser)
35756{
35757 cp_parser_context *context = parser->context;
35758 cp_lexer *lexer = parser->lexer;
35759
35760 if (context)
35761 {
35762 if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
35763 return;
35764 context->status = CP_PARSER_STATUS_KIND_COMMITTED;
35765
35766 while (!cp_lexer_saving_tokens (lexer))
35767 lexer = lexer->next;
35768 cp_lexer_commit_tokens (lexer);
35769 }
35770}
35771
35772/* Abort the currently active tentative parse. All consumed tokens
35773 will be rolled back, and no diagnostics will be issued. */
35774
35775static void
35776cp_parser_abort_tentative_parse (cp_parser* parser)
35777{
35778 gcc_assert (parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED
35779 || errorcount > 0);
35780 cp_parser_simulate_error (parser);
35781 /* Now, pretend that we want to see if the construct was
35782 successfully parsed. */
35783 cp_parser_parse_definitely (parser);
35784}
35785
35786/* Stop parsing tentatively. If a parse error has occurred, restore the
35787 token stream. Otherwise, commit to the tokens we have consumed.
35788 Returns true if no error occurred; false otherwise. */
35789
35790static bool
35791cp_parser_parse_definitely (cp_parser* parser)
35792{
35793 bool error_occurred;
35794 cp_parser_context *context;
35795
35796 /* Remember whether or not an error occurred, since we are about to
35797 destroy that information. */
35798 error_occurred = cp_parser_error_occurred (parser);
35799 /* Remove the topmost context from the stack. */
35800 context = parser->context;
35801 parser->context = context->next;
35802 /* If no parse errors occurred, commit to the tentative parse. */
35803 if (!error_occurred)
35804 {
35805 /* Commit to the tokens read tentatively, unless that was
35806 already done. */
35807 if (context->status != CP_PARSER_STATUS_KIND_COMMITTED)
35808 cp_lexer_commit_tokens (lexer: parser->lexer);
35809
35810 pop_to_parent_deferring_access_checks ();
35811 }
35812 /* Otherwise, if errors occurred, roll back our state so that things
35813 are just as they were before we began the tentative parse. */
35814 else
35815 {
35816 cp_lexer_rollback_tokens (lexer: parser->lexer);
35817 pop_deferring_access_checks ();
35818 }
35819 /* Add the context to the front of the free list. */
35820 context->next = cp_parser_context_free_list;
35821 cp_parser_context_free_list = context;
35822
35823 return !error_occurred;
35824}
35825
35826/* Returns true if we are parsing tentatively and are not committed to
35827 this tentative parse. */
35828
35829static bool
35830cp_parser_uncommitted_to_tentative_parse_p (cp_parser* parser)
35831{
35832 return (cp_parser_parsing_tentatively (parser)
35833 && parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED);
35834}
35835
35836/* Returns nonzero iff an error has occurred during the most recent
35837 tentative parse. */
35838
35839static bool
35840cp_parser_error_occurred (cp_parser* parser)
35841{
35842 return (cp_parser_parsing_tentatively (parser)
35843 && parser->context->status == CP_PARSER_STATUS_KIND_ERROR);
35844}
35845
35846/* Returns nonzero if GNU extensions are allowed. */
35847
35848static bool
35849cp_parser_allow_gnu_extensions_p (cp_parser* parser)
35850{
35851 return parser->allow_gnu_extensions_p;
35852}
35853
35854/* Objective-C++ Productions */
35855
35856
35857/* Parse an Objective-C expression, which feeds into a primary-expression
35858 above.
35859
35860 objc-expression:
35861 objc-message-expression
35862 objc-string-literal
35863 objc-encode-expression
35864 objc-protocol-expression
35865 objc-selector-expression
35866
35867 Returns a tree representation of the expression. */
35868
35869static cp_expr
35870cp_parser_objc_expression (cp_parser* parser)
35871{
35872 /* Try to figure out what kind of declaration is present. */
35873 cp_token *kwd = cp_lexer_peek_token (lexer: parser->lexer);
35874
35875 switch (kwd->type)
35876 {
35877 case CPP_OPEN_SQUARE:
35878 return cp_parser_objc_message_expression (parser);
35879
35880 case CPP_OBJC_STRING:
35881 kwd = cp_lexer_consume_token (lexer: parser->lexer);
35882 return objc_build_string_object (kwd->u.value);
35883
35884 case CPP_KEYWORD:
35885 switch (kwd->keyword)
35886 {
35887 case RID_AT_ENCODE:
35888 return cp_parser_objc_encode_expression (parser);
35889
35890 case RID_AT_PROTOCOL:
35891 return cp_parser_objc_protocol_expression (parser);
35892
35893 case RID_AT_SELECTOR:
35894 return cp_parser_objc_selector_expression (parser);
35895
35896 default:
35897 break;
35898 }
35899 /* FALLTHRU */
35900 default:
35901 error_at (kwd->location,
35902 "misplaced %<@%D%> Objective-C++ construct",
35903 kwd->u.value);
35904 cp_parser_skip_to_end_of_block_or_statement (parser);
35905 }
35906
35907 return error_mark_node;
35908}
35909
35910/* Parse an Objective-C message expression.
35911
35912 objc-message-expression:
35913 [ objc-message-receiver objc-message-args ]
35914
35915 Returns a representation of an Objective-C message. */
35916
35917static tree
35918cp_parser_objc_message_expression (cp_parser* parser)
35919{
35920 tree receiver, messageargs;
35921
35922 parser->objective_c_message_context_p = true;
35923 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
35924 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '['. */
35925 receiver = cp_parser_objc_message_receiver (parser);
35926 messageargs = cp_parser_objc_message_args (parser);
35927 location_t end_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
35928 cp_parser_require (parser, type: CPP_CLOSE_SQUARE, token_desc: RT_CLOSE_SQUARE);
35929
35930 tree result = objc_build_message_expr (receiver, messageargs);
35931
35932 /* Construct a location e.g.
35933 [self func1:5]
35934 ^~~~~~~~~~~~~~
35935 ranging from the '[' to the ']', with the caret at the start. */
35936 location_t combined_loc = make_location (caret: start_loc, start: start_loc, finish: end_loc);
35937 protected_set_expr_location (result, combined_loc);
35938
35939 parser->objective_c_message_context_p = false;
35940 return result;
35941}
35942
35943/* Parse an objc-message-receiver.
35944
35945 objc-message-receiver:
35946 expression
35947 simple-type-specifier
35948
35949 Returns a representation of the type or expression. */
35950
35951static tree
35952cp_parser_objc_message_receiver (cp_parser* parser)
35953{
35954 tree rcv;
35955
35956 /* An Objective-C message receiver may be either (1) a type
35957 or (2) an expression. */
35958 cp_parser_parse_tentatively (parser);
35959 rcv = cp_parser_expression (parser);
35960
35961 /* If that worked out, fine. */
35962 if (cp_parser_parse_definitely (parser))
35963 return rcv;
35964
35965 cp_parser_parse_tentatively (parser);
35966 rcv = cp_parser_simple_type_specifier (parser,
35967 /*decl_specs=*/NULL,
35968 flags: CP_PARSER_FLAGS_NONE);
35969
35970 if (cp_parser_parse_definitely (parser))
35971 return objc_get_class_reference (rcv);
35972
35973 cp_parser_error (parser, gmsgid: "objective-c++ message receiver expected");
35974 return error_mark_node;
35975}
35976
35977/* Parse the arguments and selectors comprising an Objective-C message.
35978
35979 objc-message-args:
35980 objc-selector
35981 objc-selector-args
35982 objc-selector-args , objc-comma-args
35983
35984 objc-selector-args:
35985 objc-selector [opt] : assignment-expression
35986 objc-selector-args objc-selector [opt] : assignment-expression
35987
35988 objc-comma-args:
35989 assignment-expression
35990 objc-comma-args , assignment-expression
35991
35992 Returns a TREE_LIST, with TREE_PURPOSE containing a list of
35993 selector arguments and TREE_VALUE containing a list of comma
35994 arguments. */
35995
35996static tree
35997cp_parser_objc_message_args (cp_parser* parser)
35998{
35999 tree sel_args = NULL_TREE, addl_args = NULL_TREE;
36000 bool maybe_unary_selector_p = true;
36001 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36002
36003 while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
36004 {
36005 tree selector = NULL_TREE, arg;
36006
36007 if (token->type != CPP_COLON)
36008 selector = cp_parser_objc_selector (parser);
36009
36010 /* Detect if we have a unary selector. */
36011 if (maybe_unary_selector_p
36012 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COLON))
36013 return build_tree_list (selector, NULL_TREE);
36014
36015 maybe_unary_selector_p = false;
36016 cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON);
36017 arg = cp_parser_assignment_expression (parser);
36018
36019 sel_args
36020 = chainon (sel_args,
36021 build_tree_list (selector, arg));
36022
36023 token = cp_lexer_peek_token (lexer: parser->lexer);
36024 }
36025
36026 /* Handle non-selector arguments, if any. */
36027 while (token->type == CPP_COMMA)
36028 {
36029 tree arg;
36030
36031 cp_lexer_consume_token (lexer: parser->lexer);
36032 arg = cp_parser_assignment_expression (parser);
36033
36034 addl_args
36035 = chainon (addl_args,
36036 build_tree_list (NULL_TREE, arg));
36037
36038 token = cp_lexer_peek_token (lexer: parser->lexer);
36039 }
36040
36041 if (sel_args == NULL_TREE && addl_args == NULL_TREE)
36042 {
36043 cp_parser_error (parser, gmsgid: "objective-c++ message argument(s) are expected");
36044 return build_tree_list (error_mark_node, error_mark_node);
36045 }
36046
36047 return build_tree_list (sel_args, addl_args);
36048}
36049
36050/* Parse an Objective-C encode expression.
36051
36052 objc-encode-expression:
36053 @encode objc-typename
36054
36055 Returns an encoded representation of the type argument. */
36056
36057static cp_expr
36058cp_parser_objc_encode_expression (cp_parser* parser)
36059{
36060 tree type;
36061 cp_token *token;
36062 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
36063
36064 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@encode'. */
36065 matching_parens parens;
36066 parens.require_open (parser);
36067 token = cp_lexer_peek_token (lexer: parser->lexer);
36068 type = complete_type (cp_parser_type_id (parser));
36069 parens.require_close (parser);
36070
36071 if (!type)
36072 {
36073 error_at (token->location,
36074 "%<@encode%> must specify a type as an argument");
36075 return error_mark_node;
36076 }
36077
36078 /* This happens if we find @encode(T) (where T is a template
36079 typename or something dependent on a template typename) when
36080 parsing a template. In that case, we can't compile it
36081 immediately, but we rather create an AT_ENCODE_EXPR which will
36082 need to be instantiated when the template is used.
36083 */
36084 if (dependent_type_p (type))
36085 {
36086 tree value = build_min (AT_ENCODE_EXPR, size_type_node, type);
36087 TREE_READONLY (value) = 1;
36088 return value;
36089 }
36090
36091
36092 /* Build a location of the form:
36093 @encode(int)
36094 ^~~~~~~~~~~~
36095 with caret==start at the @ token, finishing at the close paren. */
36096 location_t combined_loc = make_location (caret: start_loc, start: start_loc, lexer: parser->lexer);
36097
36098 return cp_expr (objc_build_encode_expr (type), combined_loc);
36099}
36100
36101/* Parse an Objective-C @defs expression. */
36102
36103static tree
36104cp_parser_objc_defs_expression (cp_parser *parser)
36105{
36106 tree name;
36107
36108 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@defs'. */
36109 matching_parens parens;
36110 parens.require_open (parser);
36111 name = cp_parser_identifier (parser);
36112 parens.require_close (parser);
36113
36114 return objc_get_class_ivars (name);
36115}
36116
36117/* Parse an Objective-C protocol expression.
36118
36119 objc-protocol-expression:
36120 @protocol ( identifier )
36121
36122 Returns a representation of the protocol expression. */
36123
36124static tree
36125cp_parser_objc_protocol_expression (cp_parser* parser)
36126{
36127 tree proto;
36128 location_t start_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
36129
36130 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@protocol'. */
36131 matching_parens parens;
36132 parens.require_open (parser);
36133 proto = cp_parser_identifier (parser);
36134 parens.require_close (parser);
36135
36136 /* Build a location of the form:
36137 @protocol(prot)
36138 ^~~~~~~~~~~~~~~
36139 with caret==start at the @ token, finishing at the close paren. */
36140 location_t combined_loc = make_location (caret: start_loc, start: start_loc, lexer: parser->lexer);
36141 tree result = objc_build_protocol_expr (proto);
36142 protected_set_expr_location (result, combined_loc);
36143 return result;
36144}
36145
36146/* Parse an Objective-C selector expression.
36147
36148 objc-selector-expression:
36149 @selector ( objc-method-signature )
36150
36151 objc-method-signature:
36152 objc-selector
36153 objc-selector-seq
36154
36155 objc-selector-seq:
36156 objc-selector :
36157 objc-selector-seq objc-selector :
36158
36159 Returns a representation of the method selector. */
36160
36161static tree
36162cp_parser_objc_selector_expression (cp_parser* parser)
36163{
36164 tree sel_seq = NULL_TREE;
36165 bool maybe_unary_selector_p = true;
36166 cp_token *token;
36167 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
36168
36169 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@selector'. */
36170 matching_parens parens;
36171 parens.require_open (parser);
36172 token = cp_lexer_peek_token (lexer: parser->lexer);
36173
36174 while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON
36175 || token->type == CPP_SCOPE)
36176 {
36177 tree selector = NULL_TREE;
36178
36179 if (token->type != CPP_COLON
36180 || token->type == CPP_SCOPE)
36181 selector = cp_parser_objc_selector (parser);
36182
36183 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COLON)
36184 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SCOPE))
36185 {
36186 /* Detect if we have a unary selector. */
36187 if (maybe_unary_selector_p)
36188 {
36189 sel_seq = selector;
36190 goto finish_selector;
36191 }
36192 else
36193 {
36194 cp_parser_error (parser, gmsgid: "expected %<:%>");
36195 }
36196 }
36197 maybe_unary_selector_p = false;
36198 token = cp_lexer_consume_token (lexer: parser->lexer);
36199
36200 if (token->type == CPP_SCOPE)
36201 {
36202 sel_seq
36203 = chainon (sel_seq,
36204 build_tree_list (selector, NULL_TREE));
36205 sel_seq
36206 = chainon (sel_seq,
36207 build_tree_list (NULL_TREE, NULL_TREE));
36208 }
36209 else
36210 sel_seq
36211 = chainon (sel_seq,
36212 build_tree_list (selector, NULL_TREE));
36213
36214 token = cp_lexer_peek_token (lexer: parser->lexer);
36215 }
36216
36217 finish_selector:
36218 parens.require_close (parser);
36219
36220
36221 /* Build a location of the form:
36222 @selector(func)
36223 ^~~~~~~~~~~~~~~
36224 with caret==start at the @ token, finishing at the close paren. */
36225 location_t combined_loc = make_location (caret: loc, start: loc, lexer: parser->lexer);
36226 tree result = objc_build_selector_expr (combined_loc, sel_seq);
36227 /* TODO: objc_build_selector_expr doesn't always honor the location. */
36228 protected_set_expr_location (result, combined_loc);
36229 return result;
36230}
36231
36232/* Parse a list of identifiers.
36233
36234 objc-identifier-list:
36235 identifier
36236 objc-identifier-list , identifier
36237
36238 Returns a TREE_LIST of identifier nodes. */
36239
36240static tree
36241cp_parser_objc_identifier_list (cp_parser* parser)
36242{
36243 tree identifier;
36244 tree list;
36245 cp_token *sep;
36246
36247 identifier = cp_parser_identifier (parser);
36248 if (identifier == error_mark_node)
36249 return error_mark_node;
36250
36251 list = build_tree_list (NULL_TREE, identifier);
36252 sep = cp_lexer_peek_token (lexer: parser->lexer);
36253
36254 while (sep->type == CPP_COMMA)
36255 {
36256 cp_lexer_consume_token (lexer: parser->lexer); /* Eat ','. */
36257 identifier = cp_parser_identifier (parser);
36258 if (identifier == error_mark_node)
36259 return list;
36260
36261 list = chainon (list, build_tree_list (NULL_TREE,
36262 identifier));
36263 sep = cp_lexer_peek_token (lexer: parser->lexer);
36264 }
36265
36266 return list;
36267}
36268
36269/* Parse an Objective-C alias declaration.
36270
36271 objc-alias-declaration:
36272 @compatibility_alias identifier identifier ;
36273
36274 This function registers the alias mapping with the Objective-C front end.
36275 It returns nothing. */
36276
36277static void
36278cp_parser_objc_alias_declaration (cp_parser* parser)
36279{
36280 tree alias, orig;
36281
36282 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@compatibility_alias'. */
36283 alias = cp_parser_identifier (parser);
36284 orig = cp_parser_identifier (parser);
36285 objc_declare_alias (alias, orig);
36286 cp_parser_consume_semicolon_at_end_of_statement (parser);
36287}
36288
36289/* Parse an Objective-C class forward-declaration.
36290
36291 objc-class-declaration:
36292 @class objc-identifier-list ;
36293
36294 The function registers the forward declarations with the Objective-C
36295 front end. It returns nothing. */
36296
36297static void
36298cp_parser_objc_class_declaration (cp_parser* parser)
36299{
36300 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@class'. */
36301 while (true)
36302 {
36303 tree id;
36304
36305 id = cp_parser_identifier (parser);
36306 if (id == error_mark_node)
36307 break;
36308
36309 objc_declare_class (id);
36310
36311 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
36312 cp_lexer_consume_token (lexer: parser->lexer);
36313 else
36314 break;
36315 }
36316 cp_parser_consume_semicolon_at_end_of_statement (parser);
36317}
36318
36319/* Parse a list of Objective-C protocol references.
36320
36321 objc-protocol-refs-opt:
36322 objc-protocol-refs [opt]
36323
36324 objc-protocol-refs:
36325 < objc-identifier-list >
36326
36327 Returns a TREE_LIST of identifiers, if any. */
36328
36329static tree
36330cp_parser_objc_protocol_refs_opt (cp_parser* parser)
36331{
36332 tree protorefs = NULL_TREE;
36333
36334 if(cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_LESS))
36335 {
36336 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '<'. */
36337 protorefs = cp_parser_objc_identifier_list (parser);
36338 cp_parser_require (parser, type: CPP_GREATER, token_desc: RT_GREATER);
36339 }
36340
36341 return protorefs;
36342}
36343
36344/* Parse a Objective-C visibility specification. */
36345
36346static void
36347cp_parser_objc_visibility_spec (cp_parser* parser)
36348{
36349 cp_token *vis = cp_lexer_peek_token (lexer: parser->lexer);
36350
36351 switch (vis->keyword)
36352 {
36353 case RID_AT_PRIVATE:
36354 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
36355 break;
36356 case RID_AT_PROTECTED:
36357 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
36358 break;
36359 case RID_AT_PUBLIC:
36360 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
36361 break;
36362 case RID_AT_PACKAGE:
36363 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
36364 break;
36365 default:
36366 return;
36367 }
36368
36369 /* Eat '@private'/'@protected'/'@public'. */
36370 cp_lexer_consume_token (lexer: parser->lexer);
36371}
36372
36373/* Parse an Objective-C method type. Return 'true' if it is a class
36374 (+) method, and 'false' if it is an instance (-) method. */
36375
36376static inline bool
36377cp_parser_objc_method_type (cp_parser* parser)
36378{
36379 if (cp_lexer_consume_token (lexer: parser->lexer)->type == CPP_PLUS)
36380 return true;
36381 else
36382 return false;
36383}
36384
36385/* Parse an Objective-C protocol qualifier. */
36386
36387static tree
36388cp_parser_objc_protocol_qualifiers (cp_parser* parser)
36389{
36390 tree quals = NULL_TREE, node;
36391 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36392
36393 node = token->u.value;
36394
36395 while (node && identifier_p (t: node)
36396 && (node == ridpointers [(int) RID_IN]
36397 || node == ridpointers [(int) RID_OUT]
36398 || node == ridpointers [(int) RID_INOUT]
36399 || node == ridpointers [(int) RID_BYCOPY]
36400 || node == ridpointers [(int) RID_BYREF]
36401 || node == ridpointers [(int) RID_ONEWAY]))
36402 {
36403 quals = tree_cons (NULL_TREE, node, quals);
36404 cp_lexer_consume_token (lexer: parser->lexer);
36405 token = cp_lexer_peek_token (lexer: parser->lexer);
36406 node = token->u.value;
36407 }
36408
36409 return quals;
36410}
36411
36412/* Parse an Objective-C typename. */
36413
36414static tree
36415cp_parser_objc_typename (cp_parser* parser)
36416{
36417 tree type_name = NULL_TREE;
36418
36419 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
36420 {
36421 tree proto_quals, cp_type = NULL_TREE;
36422
36423 matching_parens parens;
36424 parens.consume_open (parser); /* Eat '('. */
36425 proto_quals = cp_parser_objc_protocol_qualifiers (parser);
36426
36427 /* An ObjC type name may consist of just protocol qualifiers, in which
36428 case the type shall default to 'id'. */
36429 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
36430 {
36431 cp_type = cp_parser_type_id (parser);
36432
36433 /* If the type could not be parsed, an error has already
36434 been produced. For error recovery, behave as if it had
36435 not been specified, which will use the default type
36436 'id'. */
36437 if (cp_type == error_mark_node)
36438 {
36439 cp_type = NULL_TREE;
36440 /* We need to skip to the closing parenthesis as
36441 cp_parser_type_id() does not seem to do it for
36442 us. */
36443 cp_parser_skip_to_closing_parenthesis (parser,
36444 /*recovering=*/true,
36445 /*or_comma=*/false,
36446 /*consume_paren=*/false);
36447 }
36448 }
36449
36450 parens.require_close (parser);
36451 type_name = build_tree_list (proto_quals, cp_type);
36452 }
36453
36454 return type_name;
36455}
36456
36457/* Check to see if TYPE refers to an Objective-C selector name. */
36458
36459static bool
36460cp_parser_objc_selector_p (enum cpp_ttype type)
36461{
36462 return (type == CPP_NAME || type == CPP_KEYWORD
36463 || type == CPP_AND_AND || type == CPP_AND_EQ || type == CPP_AND
36464 || type == CPP_OR || type == CPP_COMPL || type == CPP_NOT
36465 || type == CPP_NOT_EQ || type == CPP_OR_OR || type == CPP_OR_EQ
36466 || type == CPP_XOR || type == CPP_XOR_EQ);
36467}
36468
36469/* Parse an Objective-C selector. */
36470
36471static tree
36472cp_parser_objc_selector (cp_parser* parser)
36473{
36474 cp_token *token = cp_lexer_consume_token (lexer: parser->lexer);
36475
36476 if (!cp_parser_objc_selector_p (type: token->type))
36477 {
36478 error_at (token->location, "invalid Objective-C++ selector name");
36479 return error_mark_node;
36480 }
36481
36482 /* C++ operator names are allowed to appear in ObjC selectors. */
36483 switch (token->type)
36484 {
36485 case CPP_AND_AND: return get_identifier ("and");
36486 case CPP_AND_EQ: return get_identifier ("and_eq");
36487 case CPP_AND: return get_identifier ("bitand");
36488 case CPP_OR: return get_identifier ("bitor");
36489 case CPP_COMPL: return get_identifier ("compl");
36490 case CPP_NOT: return get_identifier ("not");
36491 case CPP_NOT_EQ: return get_identifier ("not_eq");
36492 case CPP_OR_OR: return get_identifier ("or");
36493 case CPP_OR_EQ: return get_identifier ("or_eq");
36494 case CPP_XOR: return get_identifier ("xor");
36495 case CPP_XOR_EQ: return get_identifier ("xor_eq");
36496 default: return token->u.value;
36497 }
36498}
36499
36500/* Parse an Objective-C params list. */
36501
36502static tree
36503cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
36504{
36505 tree params = NULL_TREE;
36506 bool maybe_unary_selector_p = true;
36507 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36508
36509 while (cp_parser_objc_selector_p (type: token->type) || token->type == CPP_COLON)
36510 {
36511 tree selector = NULL_TREE, type_name, identifier;
36512 tree parm_attr = NULL_TREE;
36513
36514 if (token->keyword == RID_ATTRIBUTE)
36515 break;
36516
36517 if (token->type != CPP_COLON)
36518 selector = cp_parser_objc_selector (parser);
36519
36520 /* Detect if we have a unary selector. */
36521 if (maybe_unary_selector_p
36522 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COLON))
36523 {
36524 params = selector; /* Might be followed by attributes. */
36525 break;
36526 }
36527
36528 maybe_unary_selector_p = false;
36529 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
36530 {
36531 /* Something went quite wrong. There should be a colon
36532 here, but there is not. Stop parsing parameters. */
36533 break;
36534 }
36535 type_name = cp_parser_objc_typename (parser);
36536 /* New ObjC allows attributes on parameters too. */
36537 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_ATTRIBUTE))
36538 parm_attr = cp_parser_attributes_opt (parser);
36539 identifier = cp_parser_identifier (parser);
36540
36541 params
36542 = chainon (params,
36543 objc_build_keyword_decl (selector,
36544 type_name,
36545 identifier,
36546 parm_attr));
36547
36548 token = cp_lexer_peek_token (lexer: parser->lexer);
36549 }
36550
36551 if (params == NULL_TREE)
36552 {
36553 cp_parser_error (parser, gmsgid: "objective-c++ method declaration is expected");
36554 return error_mark_node;
36555 }
36556
36557 /* We allow tail attributes for the method. */
36558 if (token->keyword == RID_ATTRIBUTE)
36559 {
36560 *attributes = cp_parser_attributes_opt (parser);
36561 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)
36562 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
36563 return params;
36564 cp_parser_error (parser,
36565 gmsgid: "method attributes must be specified at the end");
36566 return error_mark_node;
36567 }
36568
36569 if (params == NULL_TREE)
36570 {
36571 cp_parser_error (parser, gmsgid: "objective-c++ method declaration is expected");
36572 return error_mark_node;
36573 }
36574 return params;
36575}
36576
36577/* Parse the non-keyword Objective-C params. */
36578
36579static tree
36580cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp,
36581 tree* attributes)
36582{
36583 tree params = make_node (TREE_LIST);
36584 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36585 *ellipsisp = false; /* Initially, assume no ellipsis. */
36586
36587 while (token->type == CPP_COMMA)
36588 {
36589 cp_parameter_declarator *parmdecl;
36590 tree parm;
36591
36592 cp_lexer_consume_token (lexer: parser->lexer); /* Eat ','. */
36593 token = cp_lexer_peek_token (lexer: parser->lexer);
36594
36595 if (token->type == CPP_ELLIPSIS)
36596 {
36597 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '...'. */
36598 *ellipsisp = true;
36599 token = cp_lexer_peek_token (lexer: parser->lexer);
36600 break;
36601 }
36602
36603 /* TODO: parse attributes for tail parameters. */
36604 parmdecl = cp_parser_parameter_declaration (parser, flags: CP_PARSER_FLAGS_NONE,
36605 template_parm_p: false, NULL);
36606 parm = grokdeclarator (parmdecl->declarator,
36607 &parmdecl->decl_specifiers,
36608 PARM, /*initialized=*/0,
36609 /*attrlist=*/NULL);
36610
36611 chainon (params, build_tree_list (NULL_TREE, parm));
36612 token = cp_lexer_peek_token (lexer: parser->lexer);
36613 }
36614
36615 /* We allow tail attributes for the method. */
36616 if (token->keyword == RID_ATTRIBUTE)
36617 {
36618 if (*attributes == NULL_TREE)
36619 {
36620 *attributes = cp_parser_attributes_opt (parser);
36621 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)
36622 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
36623 return params;
36624 }
36625 else
36626 /* We have an error, but parse the attributes, so that we can
36627 carry on. */
36628 *attributes = cp_parser_attributes_opt (parser);
36629
36630 cp_parser_error (parser,
36631 gmsgid: "method attributes must be specified at the end");
36632 return error_mark_node;
36633 }
36634
36635 return params;
36636}
36637
36638/* Parse a linkage specification, a pragma, an extra semicolon or a block. */
36639
36640static void
36641cp_parser_objc_interstitial_code (cp_parser* parser)
36642{
36643 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36644
36645 /* If the next token is `extern' and the following token is a string
36646 literal, then we have a linkage specification. */
36647 if (token->keyword == RID_EXTERN
36648 && cp_parser_is_pure_string_literal
36649 (token: cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)))
36650 cp_parser_linkage_specification (parser, NULL_TREE);
36651 /* Handle #pragma, if any. */
36652 else if (token->type == CPP_PRAGMA)
36653 cp_parser_pragma (parser, pragma_objc_icode, NULL);
36654 /* Allow stray semicolons. */
36655 else if (token->type == CPP_SEMICOLON)
36656 cp_lexer_consume_token (lexer: parser->lexer);
36657 /* Mark methods as optional or required, when building protocols. */
36658 else if (token->keyword == RID_AT_OPTIONAL)
36659 {
36660 cp_lexer_consume_token (lexer: parser->lexer);
36661 objc_set_method_opt (true);
36662 }
36663 else if (token->keyword == RID_AT_REQUIRED)
36664 {
36665 cp_lexer_consume_token (lexer: parser->lexer);
36666 objc_set_method_opt (false);
36667 }
36668 else if (token->keyword == RID_NAMESPACE)
36669 cp_parser_namespace_definition (parser);
36670 /* Other stray characters must generate errors. */
36671 else if (token->type == CPP_OPEN_BRACE || token->type == CPP_CLOSE_BRACE)
36672 {
36673 cp_lexer_consume_token (lexer: parser->lexer);
36674 error ("stray %qs between Objective-C++ methods",
36675 token->type == CPP_OPEN_BRACE ? "{" : "}");
36676 }
36677 /* Finally, try to parse a block-declaration, or a function-definition. */
36678 else
36679 cp_parser_block_declaration (parser, /*statement_p=*/false);
36680}
36681
36682/* Parse a method signature. */
36683
36684static tree
36685cp_parser_objc_method_signature (cp_parser* parser, tree* attributes)
36686{
36687 tree rettype, kwdparms, optparms;
36688 bool ellipsis = false;
36689 bool is_class_method;
36690
36691 is_class_method = cp_parser_objc_method_type (parser);
36692 rettype = cp_parser_objc_typename (parser);
36693 *attributes = NULL_TREE;
36694 kwdparms = cp_parser_objc_method_keyword_params (parser, attributes);
36695 if (kwdparms == error_mark_node)
36696 return error_mark_node;
36697 optparms = cp_parser_objc_method_tail_params_opt (parser, ellipsisp: &ellipsis, attributes);
36698 if (optparms == error_mark_node)
36699 return error_mark_node;
36700
36701 return objc_build_method_signature (is_class_method, rettype, kwdparms, optparms, ellipsis);
36702}
36703
36704static bool
36705cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
36706{
36707 tree tattr;
36708 cp_lexer_save_tokens (lexer: parser->lexer);
36709 tattr = cp_parser_attributes_opt (parser);
36710 gcc_assert (tattr) ;
36711
36712 /* If the attributes are followed by a method introducer, this is not allowed.
36713 Dump the attributes and flag the situation. */
36714 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_PLUS)
36715 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MINUS))
36716 return true;
36717
36718 /* Otherwise, the attributes introduce some interstitial code, possibly so
36719 rewind to allow that check. */
36720 cp_lexer_rollback_tokens (lexer: parser->lexer);
36721 return false;
36722}
36723
36724/* Parse an Objective-C method prototype list. */
36725
36726static void
36727cp_parser_objc_method_prototype_list (cp_parser* parser)
36728{
36729 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36730
36731 while (token->keyword != RID_AT_END && token->type != CPP_EOF)
36732 {
36733 if (token->type == CPP_PLUS || token->type == CPP_MINUS)
36734 {
36735 tree attributes, sig;
36736 bool is_class_method;
36737 if (token->type == CPP_PLUS)
36738 is_class_method = true;
36739 else
36740 is_class_method = false;
36741 sig = cp_parser_objc_method_signature (parser, attributes: &attributes);
36742 if (sig == error_mark_node)
36743 {
36744 cp_parser_skip_to_end_of_block_or_statement (parser);
36745 token = cp_lexer_peek_token (lexer: parser->lexer);
36746 continue;
36747 }
36748 objc_add_method_declaration (is_class_method, sig, attributes);
36749 cp_parser_consume_semicolon_at_end_of_statement (parser);
36750 }
36751 else if (token->keyword == RID_AT_PROPERTY)
36752 cp_parser_objc_at_property_declaration (parser);
36753 else if (token->keyword == RID_ATTRIBUTE
36754 && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
36755 warning_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
36756 OPT_Wattributes,
36757 "prefix attributes are ignored for methods");
36758 else
36759 /* Allow for interspersed non-ObjC++ code. */
36760 cp_parser_objc_interstitial_code (parser);
36761
36762 token = cp_lexer_peek_token (lexer: parser->lexer);
36763 }
36764
36765 if (token->type != CPP_EOF)
36766 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@end'. */
36767 else
36768 cp_parser_error (parser, gmsgid: "expected %<@end%>");
36769
36770 objc_finish_interface ();
36771}
36772
36773/* Parse an Objective-C method definition list. */
36774
36775static void
36776cp_parser_objc_method_definition_list (cp_parser* parser)
36777{
36778 for (;;)
36779 {
36780 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36781
36782 if (token->keyword == RID_AT_END)
36783 {
36784 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@end'. */
36785 break;
36786 }
36787 else if (token->type == CPP_EOF)
36788 {
36789 cp_parser_error (parser, gmsgid: "expected %<@end%>");
36790 break;
36791 }
36792 else if (token->type == CPP_PLUS || token->type == CPP_MINUS)
36793 {
36794 bool is_class_method = token->type == CPP_PLUS;
36795
36796 push_deferring_access_checks (dk_deferred);
36797 tree attribute;
36798 tree sig = cp_parser_objc_method_signature (parser, attributes: &attribute);
36799 if (sig == error_mark_node)
36800 cp_parser_skip_to_end_of_block_or_statement (parser);
36801 else
36802 {
36803 objc_start_method_definition (is_class_method, sig,
36804 attribute, NULL_TREE);
36805
36806 /* For historical reasons, we accept an optional semicolon. */
36807 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
36808 cp_lexer_consume_token (lexer: parser->lexer);
36809
36810 perform_deferred_access_checks (tf_warning_or_error);
36811 stop_deferring_access_checks ();
36812 tree meth
36813 = cp_parser_function_definition_after_declarator (parser, inline_p: false);
36814 pop_deferring_access_checks ();
36815 objc_finish_method_definition (meth);
36816 }
36817 }
36818 /* The following case will be removed once @synthesize is
36819 completely implemented. */
36820 else if (token->keyword == RID_AT_PROPERTY)
36821 cp_parser_objc_at_property_declaration (parser);
36822 else if (token->keyword == RID_AT_SYNTHESIZE)
36823 cp_parser_objc_at_synthesize_declaration (parser);
36824 else if (token->keyword == RID_AT_DYNAMIC)
36825 cp_parser_objc_at_dynamic_declaration (parser);
36826 else if (token->keyword == RID_ATTRIBUTE
36827 && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
36828 warning_at (token->location, OPT_Wattributes,
36829 "prefix attributes are ignored for methods");
36830 else
36831 /* Allow for interspersed non-ObjC++ code. */
36832 cp_parser_objc_interstitial_code (parser);
36833 }
36834
36835 objc_finish_implementation ();
36836}
36837
36838/* Parse Objective-C ivars. */
36839
36840static void
36841cp_parser_objc_class_ivars (cp_parser* parser)
36842{
36843 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
36844
36845 if (token->type != CPP_OPEN_BRACE)
36846 return; /* No ivars specified. */
36847
36848 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '{'. */
36849 token = cp_lexer_peek_token (lexer: parser->lexer);
36850
36851 while (token->type != CPP_CLOSE_BRACE
36852 && token->keyword != RID_AT_END && token->type != CPP_EOF)
36853 {
36854 cp_decl_specifier_seq declspecs;
36855 int decl_class_or_enum_p;
36856 tree prefix_attributes;
36857
36858 cp_parser_objc_visibility_spec (parser);
36859
36860 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
36861 break;
36862
36863 cp_parser_decl_specifier_seq (parser,
36864 flags: CP_PARSER_FLAGS_OPTIONAL,
36865 decl_specs: &declspecs,
36866 declares_class_or_enum: &decl_class_or_enum_p);
36867
36868 /* auto, register, static, extern, mutable. */
36869 if (declspecs.storage_class != sc_none)
36870 {
36871 cp_parser_error (parser, gmsgid: "invalid type for instance variable");
36872 declspecs.storage_class = sc_none;
36873 }
36874
36875 /* thread_local. */
36876 if (decl_spec_seq_has_spec_p (decl_specs: &declspecs, ds: ds_thread))
36877 {
36878 cp_parser_error (parser, gmsgid: "invalid type for instance variable");
36879 declspecs.locations[ds_thread] = 0;
36880 }
36881
36882 /* typedef. */
36883 if (decl_spec_seq_has_spec_p (decl_specs: &declspecs, ds: ds_typedef))
36884 {
36885 cp_parser_error (parser, gmsgid: "invalid type for instance variable");
36886 declspecs.locations[ds_typedef] = 0;
36887 }
36888
36889 prefix_attributes = declspecs.attributes;
36890 declspecs.attributes = NULL_TREE;
36891
36892 /* Keep going until we hit the `;' at the end of the
36893 declaration. */
36894 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
36895 {
36896 tree width = NULL_TREE, attributes, first_attribute, decl;
36897 cp_declarator *declarator = NULL;
36898 int ctor_dtor_or_conv_p;
36899
36900 /* Check for a (possibly unnamed) bitfield declaration. */
36901 token = cp_lexer_peek_token (lexer: parser->lexer);
36902 if (token->type == CPP_COLON)
36903 goto eat_colon;
36904
36905 if (token->type == CPP_NAME
36906 && (cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
36907 == CPP_COLON))
36908 {
36909 /* Get the name of the bitfield. */
36910 declarator = make_id_declarator (NULL_TREE,
36911 unqualified_name: cp_parser_identifier (parser),
36912 sfk: sfk_none, id_location: token->location);
36913
36914 eat_colon:
36915 cp_lexer_consume_token (lexer: parser->lexer); /* Eat ':'. */
36916 /* Get the width of the bitfield. */
36917 width
36918 = cp_parser_constant_expression (parser);
36919 }
36920 else
36921 {
36922 /* Parse the declarator. */
36923 declarator
36924 = cp_parser_declarator (parser, dcl_kind: CP_PARSER_DECLARATOR_NAMED,
36925 flags: CP_PARSER_FLAGS_NONE,
36926 ctor_dtor_or_conv_p: &ctor_dtor_or_conv_p,
36927 /*parenthesized_p=*/NULL,
36928 /*member_p=*/false,
36929 /*friend_p=*/false,
36930 /*static_p=*/false);
36931 }
36932
36933 /* Look for attributes that apply to the ivar. */
36934 attributes = cp_parser_attributes_opt (parser);
36935 /* Remember which attributes are prefix attributes and
36936 which are not. */
36937 first_attribute = attributes;
36938 /* Combine the attributes. */
36939 attributes = attr_chainon (attrs: prefix_attributes, attr: attributes);
36940
36941 if (width)
36942 /* Create the bitfield declaration. */
36943 decl = grokbitfield (declarator, &declspecs,
36944 width, NULL_TREE, attributes);
36945 else
36946 decl = grokfield (declarator, &declspecs,
36947 NULL_TREE, /*init_const_expr_p=*/false,
36948 NULL_TREE, attributes);
36949
36950 /* Add the instance variable. */
36951 if (decl != error_mark_node && decl != NULL_TREE)
36952 objc_add_instance_variable (decl);
36953
36954 /* Reset PREFIX_ATTRIBUTES. */
36955 if (attributes != error_mark_node)
36956 {
36957 while (attributes && TREE_CHAIN (attributes) != first_attribute)
36958 attributes = TREE_CHAIN (attributes);
36959 if (attributes)
36960 TREE_CHAIN (attributes) = NULL_TREE;
36961 }
36962
36963 token = cp_lexer_peek_token (lexer: parser->lexer);
36964
36965 if (token->type == CPP_COMMA)
36966 {
36967 cp_lexer_consume_token (lexer: parser->lexer); /* Eat ','. */
36968 continue;
36969 }
36970 break;
36971 }
36972
36973 cp_parser_consume_semicolon_at_end_of_statement (parser);
36974 token = cp_lexer_peek_token (lexer: parser->lexer);
36975 }
36976
36977 if (token->keyword == RID_AT_END)
36978 cp_parser_error (parser, gmsgid: "expected %<}%>");
36979
36980 /* Do not consume the RID_AT_END, so it will be read again as terminating
36981 the @interface of @implementation. */
36982 if (token->keyword != RID_AT_END && token->type != CPP_EOF)
36983 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '}'. */
36984
36985 /* For historical reasons, we accept an optional semicolon. */
36986 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
36987 cp_lexer_consume_token (lexer: parser->lexer);
36988}
36989
36990/* Parse an Objective-C protocol declaration. */
36991
36992static void
36993cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
36994{
36995 tree proto, protorefs;
36996 cp_token *tok;
36997
36998 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@protocol'. */
36999 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NAME))
37000 {
37001 tok = cp_lexer_peek_token (lexer: parser->lexer);
37002 error_at (tok->location, "identifier expected after %<@protocol%>");
37003 cp_parser_consume_semicolon_at_end_of_statement (parser);
37004 return;
37005 }
37006
37007 /* See if we have a forward declaration or a definition. */
37008 tok = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2);
37009
37010 /* Try a forward declaration first. */
37011 if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON)
37012 {
37013 while (true)
37014 {
37015 tree id;
37016
37017 id = cp_parser_identifier (parser);
37018 if (id == error_mark_node)
37019 break;
37020
37021 objc_declare_protocol (id, attributes);
37022
37023 if(cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
37024 cp_lexer_consume_token (lexer: parser->lexer);
37025 else
37026 break;
37027 }
37028 cp_parser_consume_semicolon_at_end_of_statement (parser);
37029 }
37030
37031 /* Ok, we got a full-fledged definition (or at least should). */
37032 else
37033 {
37034 proto = cp_parser_identifier (parser);
37035 protorefs = cp_parser_objc_protocol_refs_opt (parser);
37036 objc_start_protocol (proto, protorefs, attributes);
37037 cp_parser_objc_method_prototype_list (parser);
37038 }
37039}
37040
37041/* Parse an Objective-C superclass or category. */
37042
37043static void
37044cp_parser_objc_superclass_or_category (cp_parser *parser,
37045 bool iface_p,
37046 tree *super,
37047 tree *categ, bool *is_class_extension)
37048{
37049 cp_token *next = cp_lexer_peek_token (lexer: parser->lexer);
37050
37051 *super = *categ = NULL_TREE;
37052 *is_class_extension = false;
37053 if (next->type == CPP_COLON)
37054 {
37055 cp_lexer_consume_token (lexer: parser->lexer); /* Eat ':'. */
37056 *super = cp_parser_identifier (parser);
37057 }
37058 else if (next->type == CPP_OPEN_PAREN)
37059 {
37060 matching_parens parens;
37061 parens.consume_open (parser); /* Eat '('. */
37062
37063 /* If there is no category name, and this is an @interface, we
37064 have a class extension. */
37065 if (iface_p && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
37066 {
37067 *categ = NULL_TREE;
37068 *is_class_extension = true;
37069 }
37070 else
37071 *categ = cp_parser_identifier (parser);
37072
37073 parens.require_close (parser);
37074 }
37075}
37076
37077/* Parse an Objective-C class interface. */
37078
37079static void
37080cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
37081{
37082 tree name, super, categ, protos;
37083 bool is_class_extension;
37084
37085 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@interface'. */
37086 location_t nam_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
37087 name = cp_parser_identifier (parser);
37088 if (name == error_mark_node)
37089 {
37090 /* It's hard to recover because even if valid @interface stuff
37091 is to follow, we can't compile it (or validate it) if we
37092 don't even know which class it refers to. Let's assume this
37093 was a stray '@interface' token in the stream and skip it.
37094 */
37095 return;
37096 }
37097 cp_parser_objc_superclass_or_category (parser, iface_p: true, super: &super, categ: &categ,
37098 is_class_extension: &is_class_extension);
37099 protos = cp_parser_objc_protocol_refs_opt (parser);
37100
37101 /* We have either a class or a category on our hands. */
37102 if (categ || is_class_extension)
37103 objc_start_category_interface (name, categ, protos, attributes);
37104 else
37105 {
37106 objc_start_class_interface (name, nam_loc, super, protos, attributes);
37107 /* Handle instance variable declarations, if any. */
37108 cp_parser_objc_class_ivars (parser);
37109 objc_continue_interface ();
37110 }
37111
37112 cp_parser_objc_method_prototype_list (parser);
37113}
37114
37115/* Parse an Objective-C class implementation. */
37116
37117static void
37118cp_parser_objc_class_implementation (cp_parser* parser)
37119{
37120 tree name, super, categ;
37121 bool is_class_extension;
37122
37123 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@implementation'. */
37124 name = cp_parser_identifier (parser);
37125 if (name == error_mark_node)
37126 {
37127 /* It's hard to recover because even if valid @implementation
37128 stuff is to follow, we can't compile it (or validate it) if
37129 we don't even know which class it refers to. Let's assume
37130 this was a stray '@implementation' token in the stream and
37131 skip it.
37132 */
37133 return;
37134 }
37135 cp_parser_objc_superclass_or_category (parser, iface_p: false, super: &super, categ: &categ,
37136 is_class_extension: &is_class_extension);
37137
37138 /* We have either a class or a category on our hands. */
37139 if (categ)
37140 objc_start_category_implementation (name, categ);
37141 else
37142 {
37143 objc_start_class_implementation (name, super);
37144 /* Handle instance variable declarations, if any. */
37145 cp_parser_objc_class_ivars (parser);
37146 objc_continue_implementation ();
37147 }
37148
37149 cp_parser_objc_method_definition_list (parser);
37150}
37151
37152/* Consume the @end token and finish off the implementation. */
37153
37154static void
37155cp_parser_objc_end_implementation (cp_parser* parser)
37156{
37157 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@end'. */
37158 objc_finish_implementation ();
37159}
37160
37161/* Parse an Objective-C declaration. */
37162
37163static void
37164cp_parser_objc_declaration (cp_parser* parser, tree attributes)
37165{
37166 /* Try to figure out what kind of declaration is present. */
37167 cp_token *kwd = cp_lexer_peek_token (lexer: parser->lexer);
37168
37169 if (attributes)
37170 switch (kwd->keyword)
37171 {
37172 case RID_AT_ALIAS:
37173 case RID_AT_CLASS:
37174 case RID_AT_END:
37175 error_at (kwd->location, "attributes may not be specified before"
37176 " the %<@%D%> Objective-C++ keyword",
37177 kwd->u.value);
37178 attributes = NULL;
37179 break;
37180 case RID_AT_IMPLEMENTATION:
37181 warning_at (kwd->location, OPT_Wattributes,
37182 "prefix attributes are ignored before %<@%D%>",
37183 kwd->u.value);
37184 attributes = NULL;
37185 default:
37186 break;
37187 }
37188
37189 switch (kwd->keyword)
37190 {
37191 case RID_AT_ALIAS:
37192 cp_parser_objc_alias_declaration (parser);
37193 break;
37194 case RID_AT_CLASS:
37195 cp_parser_objc_class_declaration (parser);
37196 break;
37197 case RID_AT_PROTOCOL:
37198 cp_parser_objc_protocol_declaration (parser, attributes);
37199 break;
37200 case RID_AT_INTERFACE:
37201 cp_parser_objc_class_interface (parser, attributes);
37202 break;
37203 case RID_AT_IMPLEMENTATION:
37204 cp_parser_objc_class_implementation (parser);
37205 break;
37206 case RID_AT_END:
37207 cp_parser_objc_end_implementation (parser);
37208 break;
37209 default:
37210 error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
37211 kwd->u.value);
37212 cp_parser_skip_to_end_of_block_or_statement (parser);
37213 }
37214}
37215
37216/* Parse an Objective-C try-catch-finally statement.
37217
37218 objc-try-catch-finally-stmt:
37219 @try compound-statement objc-catch-clause-seq [opt]
37220 objc-finally-clause [opt]
37221
37222 objc-catch-clause-seq:
37223 objc-catch-clause objc-catch-clause-seq [opt]
37224
37225 objc-catch-clause:
37226 @catch ( objc-exception-declaration ) compound-statement
37227
37228 objc-finally-clause:
37229 @finally compound-statement
37230
37231 objc-exception-declaration:
37232 parameter-declaration
37233 '...'
37234
37235 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
37236
37237 Returns NULL_TREE.
37238
37239 PS: This function is identical to c_parser_objc_try_catch_finally_statement
37240 for C. Keep them in sync. */
37241
37242static tree
37243cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
37244{
37245 location_t location;
37246 tree stmt;
37247
37248 cp_parser_require_keyword (parser, keyword: RID_AT_TRY, token_desc: RT_AT_TRY);
37249 location = cp_lexer_peek_token (lexer: parser->lexer)->location;
37250 objc_maybe_warn_exceptions (location);
37251 /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST
37252 node, lest it get absorbed into the surrounding block. */
37253 stmt = push_stmt_list ();
37254 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_NORMAL, function_body: false);
37255 objc_begin_try_stmt (location, pop_stmt_list (stmt));
37256
37257 while (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_AT_CATCH))
37258 {
37259 cp_parameter_declarator *parm;
37260 tree parameter_declaration = error_mark_node;
37261 bool seen_open_paren = false;
37262 matching_parens parens;
37263
37264 cp_lexer_consume_token (lexer: parser->lexer);
37265 if (parens.require_open (parser))
37266 seen_open_paren = true;
37267 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_ELLIPSIS))
37268 {
37269 /* We have "@catch (...)" (where the '...' are literally
37270 what is in the code). Skip the '...'.
37271 parameter_declaration is set to NULL_TREE, and
37272 objc_being_catch_clauses() knows that that means
37273 '...'. */
37274 cp_lexer_consume_token (lexer: parser->lexer);
37275 parameter_declaration = NULL_TREE;
37276 }
37277 else
37278 {
37279 /* We have "@catch (NSException *exception)" or something
37280 like that. Parse the parameter declaration. */
37281 parm = cp_parser_parameter_declaration (parser, flags: CP_PARSER_FLAGS_NONE,
37282 template_parm_p: false, NULL);
37283 if (parm == NULL)
37284 parameter_declaration = error_mark_node;
37285 else
37286 parameter_declaration = grokdeclarator (parm->declarator,
37287 &parm->decl_specifiers,
37288 PARM, /*initialized=*/0,
37289 /*attrlist=*/NULL);
37290 }
37291 if (seen_open_paren)
37292 parens.require_close (parser);
37293 else
37294 {
37295 /* If there was no open parenthesis, we are recovering from
37296 an error, and we are trying to figure out what mistake
37297 the user has made. */
37298
37299 /* If there is an immediate closing parenthesis, the user
37300 probably forgot the opening one (ie, they typed "@catch
37301 NSException *e)". Parse the closing parenthesis and keep
37302 going. */
37303 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
37304 cp_lexer_consume_token (lexer: parser->lexer);
37305
37306 /* If these is no immediate closing parenthesis, the user
37307 probably doesn't know that parenthesis are required at
37308 all (ie, they typed "@catch NSException *e"). So, just
37309 forget about the closing parenthesis and keep going. */
37310 }
37311 objc_begin_catch_clause (parameter_declaration);
37312 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_NORMAL, function_body: false);
37313 objc_finish_catch_clause ();
37314 }
37315 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_AT_FINALLY))
37316 {
37317 cp_lexer_consume_token (lexer: parser->lexer);
37318 location = cp_lexer_peek_token (lexer: parser->lexer)->location;
37319 /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST
37320 node, lest it get absorbed into the surrounding block. */
37321 stmt = push_stmt_list ();
37322 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_NORMAL, function_body: false);
37323 objc_build_finally_clause (location, pop_stmt_list (stmt));
37324 }
37325
37326 return objc_finish_try_stmt ();
37327}
37328
37329/* Parse an Objective-C synchronized statement.
37330
37331 objc-synchronized-stmt:
37332 @synchronized ( expression ) compound-statement
37333
37334 Returns NULL_TREE. */
37335
37336static tree
37337cp_parser_objc_synchronized_statement (cp_parser *parser)
37338{
37339 location_t location;
37340 tree lock, stmt;
37341
37342 cp_parser_require_keyword (parser, keyword: RID_AT_SYNCHRONIZED, token_desc: RT_AT_SYNCHRONIZED);
37343
37344 location = cp_lexer_peek_token (lexer: parser->lexer)->location;
37345 objc_maybe_warn_exceptions (location);
37346 matching_parens parens;
37347 parens.require_open (parser);
37348 lock = cp_parser_expression (parser);
37349 parens.require_close (parser);
37350
37351 /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
37352 node, lest it get absorbed into the surrounding block. */
37353 stmt = push_stmt_list ();
37354 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_NORMAL, function_body: false);
37355
37356 return objc_build_synchronized (location, lock, pop_stmt_list (stmt));
37357}
37358
37359/* Parse an Objective-C throw statement.
37360
37361 objc-throw-stmt:
37362 @throw assignment-expression [opt] ;
37363
37364 Returns a constructed '@throw' statement. */
37365
37366static tree
37367cp_parser_objc_throw_statement (cp_parser *parser)
37368{
37369 tree expr = NULL_TREE;
37370 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
37371
37372 cp_parser_require_keyword (parser, keyword: RID_AT_THROW, token_desc: RT_AT_THROW);
37373
37374 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
37375 expr = cp_parser_expression (parser);
37376
37377 cp_parser_consume_semicolon_at_end_of_statement (parser);
37378
37379 return objc_build_throw_stmt (loc, expr);
37380}
37381
37382/* Parse an Objective-C statement. */
37383
37384static tree
37385cp_parser_objc_statement (cp_parser * parser)
37386{
37387 /* Try to figure out what kind of declaration is present. */
37388 cp_token *kwd = cp_lexer_peek_token (lexer: parser->lexer);
37389
37390 switch (kwd->keyword)
37391 {
37392 case RID_AT_TRY:
37393 return cp_parser_objc_try_catch_finally_statement (parser);
37394 case RID_AT_SYNCHRONIZED:
37395 return cp_parser_objc_synchronized_statement (parser);
37396 case RID_AT_THROW:
37397 return cp_parser_objc_throw_statement (parser);
37398 default:
37399 error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
37400 kwd->u.value);
37401 cp_parser_skip_to_end_of_block_or_statement (parser);
37402 }
37403
37404 return error_mark_node;
37405}
37406
37407/* If we are compiling ObjC++ and we see an __attribute__ we neeed to
37408 look ahead to see if an objc keyword follows the attributes. This
37409 is to detect the use of prefix attributes on ObjC @interface and
37410 @protocol. */
37411
37412static bool
37413cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib)
37414{
37415 cp_lexer_save_tokens (lexer: parser->lexer);
37416 tree addon = cp_parser_attributes_opt (parser);
37417 if (addon
37418 && OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
37419 {
37420 cp_lexer_commit_tokens (lexer: parser->lexer);
37421 if (*attrib)
37422 TREE_CHAIN (*attrib) = addon;
37423 else
37424 *attrib = addon;
37425 return true;
37426 }
37427 cp_lexer_rollback_tokens (lexer: parser->lexer);
37428 return false;
37429}
37430
37431/* This routine is a minimal replacement for
37432 c_parser_struct_declaration () used when parsing the list of
37433 types/names or ObjC++ properties. For example, when parsing the
37434 code
37435
37436 @property (readonly) int a, b, c;
37437
37438 this function is responsible for parsing "int a, int b, int c" and
37439 returning the declarations as CHAIN of DECLs.
37440
37441 TODO: Share this code with cp_parser_objc_class_ivars. It's very
37442 similar parsing. */
37443static tree
37444cp_parser_objc_struct_declaration (cp_parser *parser)
37445{
37446 tree decls = NULL_TREE;
37447 cp_decl_specifier_seq declspecs;
37448 int decl_class_or_enum_p;
37449 tree prefix_attributes;
37450
37451 cp_parser_decl_specifier_seq (parser,
37452 flags: CP_PARSER_FLAGS_NONE,
37453 decl_specs: &declspecs,
37454 declares_class_or_enum: &decl_class_or_enum_p);
37455
37456 if (declspecs.type == error_mark_node)
37457 return error_mark_node;
37458
37459 /* auto, register, static, extern, mutable. */
37460 if (declspecs.storage_class != sc_none)
37461 {
37462 cp_parser_error (parser, gmsgid: "invalid type for property");
37463 declspecs.storage_class = sc_none;
37464 }
37465
37466 /* thread_local. */
37467 if (decl_spec_seq_has_spec_p (decl_specs: &declspecs, ds: ds_thread))
37468 {
37469 cp_parser_error (parser, gmsgid: "invalid type for property");
37470 declspecs.locations[ds_thread] = 0;
37471 }
37472
37473 /* typedef. */
37474 if (decl_spec_seq_has_spec_p (decl_specs: &declspecs, ds: ds_typedef))
37475 {
37476 cp_parser_error (parser, gmsgid: "invalid type for property");
37477 declspecs.locations[ds_typedef] = 0;
37478 }
37479
37480 prefix_attributes = declspecs.attributes;
37481 declspecs.attributes = NULL_TREE;
37482
37483 /* Keep going until we hit the `;' at the end of the declaration. */
37484 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
37485 {
37486 tree attributes, first_attribute, decl;
37487 cp_declarator *declarator;
37488 cp_token *token;
37489
37490 /* Parse the declarator. */
37491 declarator = cp_parser_declarator (parser, dcl_kind: CP_PARSER_DECLARATOR_NAMED,
37492 flags: CP_PARSER_FLAGS_NONE,
37493 NULL, NULL, member_p: false, friend_p: false, static_p: false);
37494
37495 /* Look for attributes that apply to the ivar. */
37496 attributes = cp_parser_attributes_opt (parser);
37497 /* Remember which attributes are prefix attributes and
37498 which are not. */
37499 first_attribute = attributes;
37500 /* Combine the attributes. */
37501 attributes = attr_chainon (attrs: prefix_attributes, attr: attributes);
37502
37503 decl = grokfield (declarator, &declspecs,
37504 NULL_TREE, /*init_const_expr_p=*/false,
37505 NULL_TREE, attributes);
37506
37507 if (decl == error_mark_node || decl == NULL_TREE)
37508 return error_mark_node;
37509
37510 /* Reset PREFIX_ATTRIBUTES. */
37511 if (attributes != error_mark_node)
37512 {
37513 while (attributes && TREE_CHAIN (attributes) != first_attribute)
37514 attributes = TREE_CHAIN (attributes);
37515 if (attributes)
37516 TREE_CHAIN (attributes) = NULL_TREE;
37517 }
37518
37519 DECL_CHAIN (decl) = decls;
37520 decls = decl;
37521
37522 token = cp_lexer_peek_token (lexer: parser->lexer);
37523 if (token->type == CPP_COMMA)
37524 {
37525 cp_lexer_consume_token (lexer: parser->lexer); /* Eat ','. */
37526 continue;
37527 }
37528 else
37529 break;
37530 }
37531 return decls;
37532}
37533
37534/* Parse an Objective-C @property declaration. The syntax is:
37535
37536 objc-property-declaration:
37537 '@property' objc-property-attributes[opt] struct-declaration ;
37538
37539 objc-property-attributes:
37540 '(' objc-property-attribute-list ')'
37541
37542 objc-property-attribute-list:
37543 objc-property-attribute
37544 objc-property-attribute-list, objc-property-attribute
37545
37546 objc-property-attribute
37547 'getter' = identifier
37548 'setter' = identifier
37549 'readonly'
37550 'readwrite'
37551 'assign'
37552 'retain'
37553 'copy'
37554 'nonatomic'
37555
37556 For example:
37557 @property NSString *name;
37558 @property (readonly) id object;
37559 @property (retain, nonatomic, getter=getTheName) id name;
37560 @property int a, b, c;
37561
37562 PS: This function is identical to
37563 c_parser_objc_at_property_declaration for C. Keep them in sync. */
37564static void
37565cp_parser_objc_at_property_declaration (cp_parser *parser)
37566{
37567 /* Parse the optional attribute list.
37568
37569 A list of parsed, but not verified, attributes. */
37570 auto_delete_vec<property_attribute_info> prop_attr_list;
37571 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
37572
37573 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@property'. */
37574
37575 /* Parse the optional attribute list... */
37576 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
37577 {
37578 /* Eat the '('. */
37579 matching_parens parens;
37580 location_t attr_start = cp_lexer_peek_token (lexer: parser->lexer)->location;
37581 parens.consume_open (parser);
37582 bool syntax_error = false;
37583
37584 /* Allow empty @property attribute lists, but with a warning. */
37585 location_t attr_end = cp_lexer_peek_token (lexer: parser->lexer)->location;
37586 location_t attr_comb;
37587 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
37588 {
37589 attr_comb = make_location (caret: attr_end, start: attr_start, finish: attr_end);
37590 warning_at (attr_comb, OPT_Wattributes,
37591 "empty property attribute list");
37592 }
37593 else
37594 while (true)
37595 {
37596 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
37597 attr_start = token->location;
37598 attr_end = get_finish (loc: token->location);
37599 attr_comb = make_location (caret: attr_start, start: attr_start, finish: attr_end);
37600
37601 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
37602 {
37603 warning_at (attr_comb, OPT_Wattributes,
37604 "missing property attribute");
37605 if (token->type == CPP_CLOSE_PAREN)
37606 break;
37607 cp_lexer_consume_token (lexer: parser->lexer);
37608 continue;
37609 }
37610
37611 tree attr_name = NULL_TREE;
37612 if (identifier_p (t: token->u.value))
37613 attr_name = token->u.value;
37614
37615 enum rid keyword;
37616 if (token->type == CPP_NAME)
37617 keyword = C_RID_CODE (token->u.value);
37618 else if (token->type == CPP_KEYWORD
37619 && token->keyword == RID_CLASS)
37620 /* Account for accepting the 'class' keyword in this context. */
37621 keyword = RID_CLASS;
37622 else
37623 keyword = RID_MAX; /* By definition, an unknown property. */
37624 cp_lexer_consume_token (lexer: parser->lexer);
37625
37626 enum objc_property_attribute_kind prop_kind
37627 = objc_prop_attr_kind_for_rid (keyword);
37628 property_attribute_info *prop
37629 = new property_attribute_info (attr_name, attr_comb, prop_kind);
37630 prop_attr_list.safe_push (obj: prop);
37631
37632 tree meth_name;
37633 switch (prop->prop_kind)
37634 {
37635 default: break;
37636 case OBJC_PROPERTY_ATTR_UNKNOWN:
37637 if (attr_name)
37638 error_at (attr_start, "unknown property attribute %qE",
37639 attr_name);
37640 else
37641 error_at (attr_start, "unknown property attribute");
37642 prop->parse_error = syntax_error = true;
37643 break;
37644
37645 case OBJC_PROPERTY_ATTR_GETTER:
37646 case OBJC_PROPERTY_ATTR_SETTER:
37647 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_EQ))
37648 {
37649 attr_comb = make_location (caret: attr_end, start: attr_start, finish: attr_end);
37650 error_at (attr_comb, "expected %<=%> after Objective-C %qE",
37651 attr_name);
37652 prop->parse_error = syntax_error = true;
37653 break;
37654 }
37655
37656 token = cp_lexer_peek_token (lexer: parser->lexer);
37657 attr_end = token->location;
37658 cp_lexer_consume_token (lexer: parser->lexer); /* eat the = */
37659
37660 if (!cp_parser_objc_selector_p
37661 (type: cp_lexer_peek_token (lexer: parser->lexer)->type))
37662 {
37663 attr_comb = make_location (caret: attr_end, start: attr_start, finish: attr_end);
37664 error_at (attr_comb, "expected %qE selector name",
37665 attr_name);
37666 prop->parse_error = syntax_error = true;
37667 break;
37668 }
37669
37670 /* Get the end of the method name, and consume the name. */
37671 token = cp_lexer_peek_token (lexer: parser->lexer);
37672 attr_end = get_finish (loc: token->location);
37673 /* Because method names may contain C++ keywords, we have a
37674 routine to fetch them (this also consumes the token). */
37675 meth_name = cp_parser_objc_selector (parser);
37676
37677 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
37678 {
37679 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COLON))
37680 {
37681 attr_comb = make_location (caret: attr_end, start: attr_start,
37682 finish: attr_end);
37683 error_at (attr_comb, "setter method names must"
37684 " terminate with %<:%>");
37685 prop->parse_error = syntax_error = true;
37686 }
37687 else
37688 {
37689 attr_end = get_finish (loc: cp_lexer_peek_token
37690 (lexer: parser->lexer)->location);
37691 cp_lexer_consume_token (lexer: parser->lexer);
37692 }
37693 attr_comb = make_location (caret: attr_start, start: attr_start,
37694 finish: attr_end);
37695 }
37696 else
37697 attr_comb = make_location (caret: attr_start, start: attr_start,
37698 finish: attr_end);
37699 prop->ident = meth_name;
37700 /* Updated location including all that was successfully
37701 parsed. */
37702 prop->prop_loc = attr_comb;
37703 break;
37704 }
37705
37706 /* If we see a comma here, then keep going - even if we already
37707 saw a syntax error. For simple mistakes e.g. (asign, getter=x)
37708 this makes a more useful output and avoid spurious warnings
37709 about missing attributes that are, in fact, specified after the
37710 one with the syntax error. */
37711 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
37712 cp_lexer_consume_token (lexer: parser->lexer);
37713 else
37714 break;
37715 }
37716
37717 if (syntax_error || !parens.require_close (parser))
37718 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
37719 /*or_comma=*/false,
37720 /*consume_paren=*/true);
37721 }
37722
37723 /* 'properties' is the list of properties that we read. Usually a
37724 single one, but maybe more (eg, in "@property int a, b, c;" there
37725 are three).
37726 TODO: Update this parsing so that it accepts (erroneous) bitfields so
37727 that we can issue a meaningful and consistent (between C/C++) error
37728 message from objc_add_property_declaration (). */
37729 tree properties = cp_parser_objc_struct_declaration (parser);
37730
37731 if (properties == error_mark_node)
37732 cp_parser_skip_to_end_of_statement (parser);
37733 else if (properties == NULL_TREE)
37734 cp_parser_error (parser, gmsgid: "expected identifier");
37735 else
37736 {
37737 /* Comma-separated properties are chained together in reverse order;
37738 add them one by one. */
37739 properties = nreverse (properties);
37740 for (; properties; properties = TREE_CHAIN (properties))
37741 objc_add_property_declaration (loc, copy_node (properties),
37742 prop_attr_list);
37743 }
37744
37745 cp_parser_consume_semicolon_at_end_of_statement (parser);
37746}
37747
37748/* Parse an Objective-C++ @synthesize declaration. The syntax is:
37749
37750 objc-synthesize-declaration:
37751 @synthesize objc-synthesize-identifier-list ;
37752
37753 objc-synthesize-identifier-list:
37754 objc-synthesize-identifier
37755 objc-synthesize-identifier-list, objc-synthesize-identifier
37756
37757 objc-synthesize-identifier
37758 identifier
37759 identifier = identifier
37760
37761 For example:
37762 @synthesize MyProperty;
37763 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
37764
37765 PS: This function is identical to c_parser_objc_at_synthesize_declaration
37766 for C. Keep them in sync.
37767*/
37768static void
37769cp_parser_objc_at_synthesize_declaration (cp_parser *parser)
37770{
37771 tree list = NULL_TREE;
37772 location_t loc;
37773 loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
37774
37775 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@synthesize'. */
37776 while (true)
37777 {
37778 tree property, ivar;
37779 property = cp_parser_identifier (parser);
37780 if (property == error_mark_node)
37781 {
37782 cp_parser_consume_semicolon_at_end_of_statement (parser);
37783 return;
37784 }
37785 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
37786 {
37787 cp_lexer_consume_token (lexer: parser->lexer);
37788 ivar = cp_parser_identifier (parser);
37789 if (ivar == error_mark_node)
37790 {
37791 cp_parser_consume_semicolon_at_end_of_statement (parser);
37792 return;
37793 }
37794 }
37795 else
37796 ivar = NULL_TREE;
37797 list = chainon (list, build_tree_list (ivar, property));
37798 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
37799 cp_lexer_consume_token (lexer: parser->lexer);
37800 else
37801 break;
37802 }
37803 cp_parser_consume_semicolon_at_end_of_statement (parser);
37804 objc_add_synthesize_declaration (loc, list);
37805}
37806
37807/* Parse an Objective-C++ @dynamic declaration. The syntax is:
37808
37809 objc-dynamic-declaration:
37810 @dynamic identifier-list ;
37811
37812 For example:
37813 @dynamic MyProperty;
37814 @dynamic MyProperty, AnotherProperty;
37815
37816 PS: This function is identical to c_parser_objc_at_dynamic_declaration
37817 for C. Keep them in sync.
37818*/
37819static void
37820cp_parser_objc_at_dynamic_declaration (cp_parser *parser)
37821{
37822 tree list = NULL_TREE;
37823 location_t loc;
37824 loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
37825
37826 cp_lexer_consume_token (lexer: parser->lexer); /* Eat '@dynamic'. */
37827 while (true)
37828 {
37829 tree property;
37830 property = cp_parser_identifier (parser);
37831 if (property == error_mark_node)
37832 {
37833 cp_parser_consume_semicolon_at_end_of_statement (parser);
37834 return;
37835 }
37836 list = chainon (list, build_tree_list (NULL, property));
37837 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
37838 cp_lexer_consume_token (lexer: parser->lexer);
37839 else
37840 break;
37841 }
37842 cp_parser_consume_semicolon_at_end_of_statement (parser);
37843 objc_add_dynamic_declaration (loc, list);
37844}
37845
37846
37847/* OpenMP 2.5 / 3.0 / 3.1 / 4.0 / 4.5 / 5.0 parsing routines. */
37848
37849/* Returns name of the next clause.
37850 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
37851 the token is not consumed. Otherwise appropriate pragma_omp_clause is
37852 returned and the token is consumed. */
37853
37854static pragma_omp_clause
37855cp_parser_omp_clause_name (cp_parser *parser)
37856{
37857 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
37858
37859 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_AUTO))
37860 result = PRAGMA_OACC_CLAUSE_AUTO;
37861 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_IF))
37862 result = PRAGMA_OMP_CLAUSE_IF;
37863 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_DEFAULT))
37864 result = PRAGMA_OMP_CLAUSE_DEFAULT;
37865 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_DELETE))
37866 result = PRAGMA_OACC_CLAUSE_DELETE;
37867 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_PRIVATE))
37868 result = PRAGMA_OMP_CLAUSE_PRIVATE;
37869 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_FOR))
37870 result = PRAGMA_OMP_CLAUSE_FOR;
37871 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
37872 {
37873 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
37874 const char *p = IDENTIFIER_POINTER (id);
37875
37876 switch (p[0])
37877 {
37878 case 'a':
37879 if (!strcmp (s1: "affinity", s2: p))
37880 result = PRAGMA_OMP_CLAUSE_AFFINITY;
37881 else if (!strcmp (s1: "aligned", s2: p))
37882 result = PRAGMA_OMP_CLAUSE_ALIGNED;
37883 else if (!strcmp (s1: "allocate", s2: p))
37884 result = PRAGMA_OMP_CLAUSE_ALLOCATE;
37885 else if (!strcmp (s1: "async", s2: p))
37886 result = PRAGMA_OACC_CLAUSE_ASYNC;
37887 else if (!strcmp (s1: "attach", s2: p))
37888 result = PRAGMA_OACC_CLAUSE_ATTACH;
37889 break;
37890 case 'b':
37891 if (!strcmp (s1: "bind", s2: p))
37892 result = PRAGMA_OMP_CLAUSE_BIND;
37893 break;
37894 case 'c':
37895 if (!strcmp (s1: "collapse", s2: p))
37896 result = PRAGMA_OMP_CLAUSE_COLLAPSE;
37897 else if (!strcmp (s1: "copy", s2: p))
37898 result = PRAGMA_OACC_CLAUSE_COPY;
37899 else if (!strcmp (s1: "copyin", s2: p))
37900 result = PRAGMA_OMP_CLAUSE_COPYIN;
37901 else if (!strcmp (s1: "copyout", s2: p))
37902 result = PRAGMA_OACC_CLAUSE_COPYOUT;
37903 else if (!strcmp (s1: "copyprivate", s2: p))
37904 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
37905 else if (!strcmp (s1: "create", s2: p))
37906 result = PRAGMA_OACC_CLAUSE_CREATE;
37907 break;
37908 case 'd':
37909 if (!strcmp (s1: "defaultmap", s2: p))
37910 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
37911 else if (!strcmp (s1: "depend", s2: p))
37912 result = PRAGMA_OMP_CLAUSE_DEPEND;
37913 else if (!strcmp (s1: "detach", s2: p))
37914 result = PRAGMA_OACC_CLAUSE_DETACH;
37915 else if (!strcmp (s1: "device", s2: p))
37916 result = PRAGMA_OMP_CLAUSE_DEVICE;
37917 else if (!strcmp (s1: "deviceptr", s2: p))
37918 result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
37919 else if (!strcmp (s1: "device_resident", s2: p))
37920 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
37921 else if (!strcmp (s1: "device_type", s2: p))
37922 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
37923 else if (!strcmp (s1: "dist_schedule", s2: p))
37924 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
37925 else if (!strcmp (s1: "doacross", s2: p))
37926 result = PRAGMA_OMP_CLAUSE_DOACROSS;
37927 break;
37928 case 'e':
37929 if (!strcmp (s1: "enter", s2: p))
37930 result = PRAGMA_OMP_CLAUSE_ENTER;
37931 break;
37932 case 'f':
37933 if (!strcmp (s1: "filter", s2: p))
37934 result = PRAGMA_OMP_CLAUSE_FILTER;
37935 else if (!strcmp (s1: "final", s2: p))
37936 result = PRAGMA_OMP_CLAUSE_FINAL;
37937 else if (!strcmp (s1: "finalize", s2: p))
37938 result = PRAGMA_OACC_CLAUSE_FINALIZE;
37939 else if (!strcmp (s1: "firstprivate", s2: p))
37940 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
37941 else if (!strcmp (s1: "from", s2: p))
37942 result = PRAGMA_OMP_CLAUSE_FROM;
37943 break;
37944 case 'g':
37945 if (!strcmp (s1: "gang", s2: p))
37946 result = PRAGMA_OACC_CLAUSE_GANG;
37947 else if (!strcmp (s1: "grainsize", s2: p))
37948 result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
37949 break;
37950 case 'h':
37951 if (!strcmp (s1: "has_device_addr", s2: p))
37952 result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
37953 else if (!strcmp (s1: "hint", s2: p))
37954 result = PRAGMA_OMP_CLAUSE_HINT;
37955 else if (!strcmp (s1: "host", s2: p))
37956 result = PRAGMA_OACC_CLAUSE_HOST;
37957 break;
37958 case 'i':
37959 if (!strcmp (s1: "if_present", s2: p))
37960 result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
37961 else if (!strcmp (s1: "in_reduction", s2: p))
37962 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
37963 else if (!strcmp (s1: "inbranch", s2: p))
37964 result = PRAGMA_OMP_CLAUSE_INBRANCH;
37965 else if (!strcmp (s1: "independent", s2: p))
37966 result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
37967 else if (!strcmp (s1: "indirect", s2: p))
37968 result = PRAGMA_OMP_CLAUSE_INDIRECT;
37969 else if (!strcmp (s1: "is_device_ptr", s2: p))
37970 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
37971 break;
37972 case 'l':
37973 if (!strcmp (s1: "lastprivate", s2: p))
37974 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
37975 else if (!strcmp (s1: "linear", s2: p))
37976 result = PRAGMA_OMP_CLAUSE_LINEAR;
37977 else if (!strcmp (s1: "link", s2: p))
37978 result = PRAGMA_OMP_CLAUSE_LINK;
37979 break;
37980 case 'm':
37981 if (!strcmp (s1: "map", s2: p))
37982 result = PRAGMA_OMP_CLAUSE_MAP;
37983 else if (!strcmp (s1: "mergeable", s2: p))
37984 result = PRAGMA_OMP_CLAUSE_MERGEABLE;
37985 break;
37986 case 'n':
37987 if (!strcmp (s1: "no_create", s2: p))
37988 result = PRAGMA_OACC_CLAUSE_NO_CREATE;
37989 else if (!strcmp (s1: "nogroup", s2: p))
37990 result = PRAGMA_OMP_CLAUSE_NOGROUP;
37991 else if (!strcmp (s1: "nohost", s2: p))
37992 result = PRAGMA_OACC_CLAUSE_NOHOST;
37993 else if (!strcmp (s1: "nontemporal", s2: p))
37994 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
37995 else if (!strcmp (s1: "notinbranch", s2: p))
37996 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
37997 else if (!strcmp (s1: "nowait", s2: p))
37998 result = PRAGMA_OMP_CLAUSE_NOWAIT;
37999 else if (!strcmp (s1: "num_gangs", s2: p))
38000 result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
38001 else if (!strcmp (s1: "num_tasks", s2: p))
38002 result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
38003 else if (!strcmp (s1: "num_teams", s2: p))
38004 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
38005 else if (!strcmp (s1: "num_threads", s2: p))
38006 result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
38007 else if (!strcmp (s1: "num_workers", s2: p))
38008 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
38009 break;
38010 case 'o':
38011 if (!strcmp (s1: "ordered", s2: p))
38012 result = PRAGMA_OMP_CLAUSE_ORDERED;
38013 else if (!strcmp (s1: "order", s2: p))
38014 result = PRAGMA_OMP_CLAUSE_ORDER;
38015 break;
38016 case 'p':
38017 if (!strcmp (s1: "parallel", s2: p))
38018 result = PRAGMA_OMP_CLAUSE_PARALLEL;
38019 else if (!strcmp (s1: "present", s2: p))
38020 result = PRAGMA_OACC_CLAUSE_PRESENT;
38021 else if (!strcmp (s1: "present_or_copy", s2: p)
38022 || !strcmp (s1: "pcopy", s2: p))
38023 result = PRAGMA_OACC_CLAUSE_COPY;
38024 else if (!strcmp (s1: "present_or_copyin", s2: p)
38025 || !strcmp (s1: "pcopyin", s2: p))
38026 result = PRAGMA_OACC_CLAUSE_COPYIN;
38027 else if (!strcmp (s1: "present_or_copyout", s2: p)
38028 || !strcmp (s1: "pcopyout", s2: p))
38029 result = PRAGMA_OACC_CLAUSE_COPYOUT;
38030 else if (!strcmp (s1: "present_or_create", s2: p)
38031 || !strcmp (s1: "pcreate", s2: p))
38032 result = PRAGMA_OACC_CLAUSE_CREATE;
38033 else if (!strcmp (s1: "priority", s2: p))
38034 result = PRAGMA_OMP_CLAUSE_PRIORITY;
38035 else if (!strcmp (s1: "proc_bind", s2: p))
38036 result = PRAGMA_OMP_CLAUSE_PROC_BIND;
38037 break;
38038 case 'r':
38039 if (!strcmp (s1: "reduction", s2: p))
38040 result = PRAGMA_OMP_CLAUSE_REDUCTION;
38041 break;
38042 case 's':
38043 if (!strcmp (s1: "safelen", s2: p))
38044 result = PRAGMA_OMP_CLAUSE_SAFELEN;
38045 else if (!strcmp (s1: "schedule", s2: p))
38046 result = PRAGMA_OMP_CLAUSE_SCHEDULE;
38047 else if (!strcmp (s1: "sections", s2: p))
38048 result = PRAGMA_OMP_CLAUSE_SECTIONS;
38049 else if (!strcmp (s1: "self", s2: p))
38050 result = PRAGMA_OACC_CLAUSE_SELF;
38051 else if (!strcmp (s1: "seq", s2: p))
38052 result = PRAGMA_OACC_CLAUSE_SEQ;
38053 else if (!strcmp (s1: "shared", s2: p))
38054 result = PRAGMA_OMP_CLAUSE_SHARED;
38055 else if (!strcmp (s1: "simd", s2: p))
38056 result = PRAGMA_OMP_CLAUSE_SIMD;
38057 else if (!strcmp (s1: "simdlen", s2: p))
38058 result = PRAGMA_OMP_CLAUSE_SIMDLEN;
38059 break;
38060 case 't':
38061 if (!strcmp (s1: "task_reduction", s2: p))
38062 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
38063 else if (!strcmp (s1: "taskgroup", s2: p))
38064 result = PRAGMA_OMP_CLAUSE_TASKGROUP;
38065 else if (!strcmp (s1: "thread_limit", s2: p))
38066 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
38067 else if (!strcmp (s1: "threads", s2: p))
38068 result = PRAGMA_OMP_CLAUSE_THREADS;
38069 else if (!strcmp (s1: "tile", s2: p))
38070 result = PRAGMA_OACC_CLAUSE_TILE;
38071 else if (!strcmp (s1: "to", s2: p))
38072 result = PRAGMA_OMP_CLAUSE_TO;
38073 break;
38074 case 'u':
38075 if (!strcmp (s1: "uniform", s2: p))
38076 result = PRAGMA_OMP_CLAUSE_UNIFORM;
38077 else if (!strcmp (s1: "untied", s2: p))
38078 result = PRAGMA_OMP_CLAUSE_UNTIED;
38079 else if (!strcmp (s1: "use_device", s2: p))
38080 result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
38081 else if (!strcmp (s1: "use_device_addr", s2: p))
38082 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
38083 else if (!strcmp (s1: "use_device_ptr", s2: p))
38084 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
38085 break;
38086 case 'v':
38087 if (!strcmp (s1: "vector", s2: p))
38088 result = PRAGMA_OACC_CLAUSE_VECTOR;
38089 else if (!strcmp (s1: "vector_length", s2: p))
38090 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
38091 break;
38092 case 'w':
38093 if (!strcmp (s1: "wait", s2: p))
38094 result = PRAGMA_OACC_CLAUSE_WAIT;
38095 else if (!strcmp (s1: "worker", s2: p))
38096 result = PRAGMA_OACC_CLAUSE_WORKER;
38097 break;
38098 }
38099 }
38100
38101 if (result != PRAGMA_OMP_CLAUSE_NONE)
38102 cp_lexer_consume_token (lexer: parser->lexer);
38103
38104 return result;
38105}
38106
38107/* Validate that a clause of the given type does not already exist. */
38108
38109static void
38110check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
38111 const char *name, location_t location)
38112{
38113 if (omp_find_clause (clauses, kind: code))
38114 error_at (location, "too many %qs clauses", name);
38115}
38116
38117/* OpenMP 2.5:
38118 variable-list:
38119 identifier
38120 variable-list , identifier
38121
38122 In addition, we match a closing parenthesis (or, if COLON is non-NULL,
38123 colon). An opening parenthesis will have been consumed by the caller.
38124
38125 If KIND is nonzero, create the appropriate node and install the decl
38126 in OMP_CLAUSE_DECL and add the node to the head of the list.
38127
38128 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
38129 return the list created.
38130
38131 COLON can be NULL if only closing parenthesis should end the list,
38132 or pointer to bool which will receive false if the list is terminated
38133 by closing parenthesis or true if the list is terminated by colon.
38134
38135 The optional ALLOW_DEREF argument is true if list items can use the deref
38136 (->) operator. */
38137
38138struct omp_dim
38139{
38140 tree low_bound, length;
38141 location_t loc;
38142 bool no_colon;
38143 omp_dim (tree lb, tree len, location_t lo, bool nc)
38144 : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
38145};
38146
38147static tree
38148cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
38149 tree list, bool *colon,
38150 bool map_lvalue = false)
38151{
38152 auto_vec<omp_dim> dims;
38153 bool array_section_p;
38154 cp_token *token;
38155 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
38156 if (colon)
38157 {
38158 parser->colon_corrects_to_scope_p = false;
38159 *colon = false;
38160 }
38161 while (1)
38162 {
38163 tree name, decl;
38164
38165 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
38166 cp_parser_parse_tentatively (parser);
38167 /* This condition doesn't include OMP_CLAUSE_DEPEND or
38168 OMP_CLAUSE_AFFINITY since lvalue ("locator list") parsing for those is
38169 handled further down the function. */
38170 else if (map_lvalue
38171 && (kind == OMP_CLAUSE_MAP
38172 || kind == OMP_CLAUSE_TO
38173 || kind == OMP_CLAUSE_FROM))
38174 {
38175 auto s = make_temp_override (var&: parser->omp_array_section_p, overrider: true);
38176 token = cp_lexer_peek_token (lexer: parser->lexer);
38177 location_t loc = token->location;
38178 decl = cp_parser_assignment_expression (parser);
38179
38180 /* This code rewrites a parsed expression containing various tree
38181 codes used to represent array accesses into a more uniform nest of
38182 OMP_ARRAY_SECTION nodes before it is processed by
38183 semantics.cc:handle_omp_array_sections_1. It might be more
38184 efficient to move this logic to that function instead, analysing
38185 the parsed expression directly rather than this preprocessed
38186 form. */
38187 dims.truncate (size: 0);
38188 if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
38189 {
38190 while (TREE_CODE (decl) == OMP_ARRAY_SECTION)
38191 {
38192 tree low_bound = TREE_OPERAND (decl, 1);
38193 tree length = TREE_OPERAND (decl, 2);
38194 dims.safe_push (obj: omp_dim (low_bound, length, loc, false));
38195 decl = TREE_OPERAND (decl, 0);
38196 }
38197
38198 while (TREE_CODE (decl) == ARRAY_REF
38199 || TREE_CODE (decl) == INDIRECT_REF
38200 || TREE_CODE (decl) == COMPOUND_EXPR)
38201 {
38202 if (REFERENCE_REF_P (decl))
38203 break;
38204
38205 if (TREE_CODE (decl) == COMPOUND_EXPR)
38206 {
38207 decl = TREE_OPERAND (decl, 1);
38208 STRIP_NOPS (decl);
38209 }
38210 else if (TREE_CODE (decl) == INDIRECT_REF)
38211 {
38212 dims.safe_push (obj: omp_dim (integer_zero_node,
38213 integer_one_node, loc, true));
38214 decl = TREE_OPERAND (decl, 0);
38215 }
38216 else /* ARRAY_REF. */
38217 {
38218 tree index = TREE_OPERAND (decl, 1);
38219 dims.safe_push (obj: omp_dim (index, integer_one_node, loc,
38220 true));
38221 decl = TREE_OPERAND (decl, 0);
38222 }
38223 }
38224
38225 /* Bare references have their own special handling, so remove
38226 the explicit dereference added by convert_from_reference. */
38227 if (REFERENCE_REF_P (decl))
38228 decl = TREE_OPERAND (decl, 0);
38229
38230 for (int i = dims.length () - 1; i >= 0; i--)
38231 decl = grok_omp_array_section (loc, decl, dims[i].low_bound,
38232 dims[i].length);
38233 }
38234 else if (TREE_CODE (decl) == INDIRECT_REF)
38235 {
38236 bool ref_p = REFERENCE_REF_P (decl);
38237
38238 /* If we have "*foo" and
38239 - it's an indirection of a reference, "unconvert" it, i.e.
38240 strip the indirection (to just "foo").
38241 - it's an indirection of a pointer, turn it into
38242 "foo[0:1]". */
38243 decl = TREE_OPERAND (decl, 0);
38244 STRIP_NOPS (decl);
38245
38246 if (!ref_p)
38247 decl = grok_omp_array_section (loc, decl, integer_zero_node,
38248 integer_one_node);
38249 }
38250 else if (TREE_CODE (decl) == ARRAY_REF)
38251 {
38252 tree idx = TREE_OPERAND (decl, 1);
38253
38254 decl = TREE_OPERAND (decl, 0);
38255 STRIP_NOPS (decl);
38256
38257 decl = grok_omp_array_section (loc, decl, idx, integer_one_node);
38258 }
38259 else if (TREE_CODE (decl) == NON_LVALUE_EXPR
38260 || CONVERT_EXPR_P (decl))
38261 decl = TREE_OPERAND (decl, 0);
38262
38263 goto build_clause;
38264 }
38265 token = cp_lexer_peek_token (lexer: parser->lexer);
38266 if (kind != 0
38267 && cp_parser_is_keyword (token, keyword: RID_THIS))
38268 {
38269 decl = finish_this_expr ();
38270 if (TREE_CODE (decl) == NON_LVALUE_EXPR
38271 || CONVERT_EXPR_P (decl))
38272 decl = TREE_OPERAND (decl, 0);
38273 cp_lexer_consume_token (lexer: parser->lexer);
38274 }
38275 else if (cp_parser_is_keyword (token, keyword: RID_FUNCTION_NAME)
38276 || cp_parser_is_keyword (token, keyword: RID_PRETTY_FUNCTION_NAME)
38277 || cp_parser_is_keyword (token, keyword: RID_C99_FUNCTION_NAME))
38278 {
38279 cp_id_kind idk;
38280 decl = cp_parser_primary_expression (parser, address_p: false, cast_p: false, template_arg_p: false,
38281 idk: &idk);
38282 }
38283 else if (kind == OMP_CLAUSE_DEPEND
38284 && cp_parser_is_keyword (token, keyword: RID_OMP_ALL_MEMORY)
38285 && (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COMMA)
38286 || cp_lexer_nth_token_is (lexer: parser->lexer, n: 2,
38287 type: CPP_CLOSE_PAREN)))
38288 {
38289 decl = ridpointers[RID_OMP_ALL_MEMORY];
38290 cp_lexer_consume_token (lexer: parser->lexer);
38291 }
38292 else
38293 {
38294 name = cp_parser_id_expression (parser, /*template_p=*/template_keyword_p: false,
38295 /*check_dependency_p=*/true,
38296 /*template_p=*/NULL,
38297 /*declarator_p=*/false,
38298 /*optional_p=*/false);
38299 if (name == error_mark_node)
38300 {
38301 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
38302 && cp_parser_simulate_error (parser))
38303 goto depend_lvalue;
38304 goto skip_comma;
38305 }
38306
38307 if (identifier_p (t: name))
38308 decl = cp_parser_lookup_name_simple (parser, name, location: token->location);
38309 else
38310 decl = name;
38311 if (decl == error_mark_node)
38312 {
38313 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
38314 && cp_parser_simulate_error (parser))
38315 goto depend_lvalue;
38316 cp_parser_name_lookup_error (parser, name, decl, desired: NLE_NULL,
38317 location: token->location);
38318 }
38319 }
38320 if (outer_automatic_var_p (decl))
38321 decl = process_outer_var_ref (decl, tf_warning_or_error);
38322 if (decl == error_mark_node)
38323 ;
38324 else if (kind != 0)
38325 {
38326 switch (kind)
38327 {
38328 case OMP_CLAUSE__CACHE_:
38329 /* The OpenACC cache directive explicitly only allows "array
38330 elements or subarrays". */
38331 if (cp_lexer_peek_token (lexer: parser->lexer)->type != CPP_OPEN_SQUARE)
38332 {
38333 error_at (token->location, "expected %<[%>");
38334 decl = error_mark_node;
38335 break;
38336 }
38337 /* FALLTHROUGH. */
38338 case OMP_CLAUSE_MAP:
38339 case OMP_CLAUSE_FROM:
38340 case OMP_CLAUSE_TO:
38341 start_component_ref:
38342 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DOT)
38343 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DEREF))
38344 {
38345 cpp_ttype ttype
38346 = cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DOT)
38347 ? CPP_DOT : CPP_DEREF;
38348 location_t loc
38349 = cp_lexer_peek_token (lexer: parser->lexer)->location;
38350 cp_id_kind idk = CP_ID_KIND_NONE;
38351 cp_lexer_consume_token (lexer: parser->lexer);
38352 decl = convert_from_reference (decl);
38353 decl = (cp_parser_postfix_dot_deref_expression
38354 (parser, token_type: ttype, postfix_expression: cp_expr (decl, token->location),
38355 for_offsetof: false, idk: &idk, location: loc));
38356 }
38357 /* FALLTHROUGH. */
38358 case OMP_CLAUSE_AFFINITY:
38359 case OMP_CLAUSE_DEPEND:
38360 case OMP_CLAUSE_REDUCTION:
38361 case OMP_CLAUSE_IN_REDUCTION:
38362 case OMP_CLAUSE_TASK_REDUCTION:
38363 case OMP_CLAUSE_HAS_DEVICE_ADDR:
38364 array_section_p = false;
38365 dims.truncate (size: 0);
38366 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
38367 {
38368 location_t loc = UNKNOWN_LOCATION;
38369 tree low_bound = NULL_TREE, length = NULL_TREE;
38370 bool no_colon = false;
38371
38372 parser->colon_corrects_to_scope_p = false;
38373 cp_lexer_consume_token (lexer: parser->lexer);
38374 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
38375 {
38376 loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
38377 low_bound = cp_parser_expression (parser);
38378 /* Later handling is not prepared to see through these. */
38379 gcc_checking_assert (!location_wrapper_p (low_bound));
38380 }
38381 if (!colon)
38382 parser->colon_corrects_to_scope_p
38383 = saved_colon_corrects_to_scope_p;
38384 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_SQUARE))
38385 {
38386 length = integer_one_node;
38387 no_colon = true;
38388 }
38389 else
38390 {
38391 /* Look for `:'. */
38392 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
38393 {
38394 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
38395 && cp_parser_simulate_error (parser))
38396 goto depend_lvalue;
38397 goto skip_comma;
38398 }
38399 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
38400 cp_parser_commit_to_tentative_parse (parser);
38401 else
38402 array_section_p = true;
38403 if (!cp_lexer_next_token_is (lexer: parser->lexer,
38404 type: CPP_CLOSE_SQUARE))
38405 {
38406 length = cp_parser_expression (parser);
38407 /* Later handling is not prepared to see through these. */
38408 gcc_checking_assert (!location_wrapper_p (length));
38409 }
38410 }
38411 /* Look for the closing `]'. */
38412 if (!cp_parser_require (parser, type: CPP_CLOSE_SQUARE,
38413 token_desc: RT_CLOSE_SQUARE))
38414 {
38415 if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
38416 && cp_parser_simulate_error (parser))
38417 goto depend_lvalue;
38418 goto skip_comma;
38419 }
38420
38421 dims.safe_push (obj: omp_dim (low_bound, length, loc, no_colon));
38422 }
38423
38424 if ((kind == OMP_CLAUSE_MAP
38425 || kind == OMP_CLAUSE_FROM
38426 || kind == OMP_CLAUSE_TO)
38427 && !array_section_p
38428 && (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DOT)
38429 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_DEREF)))
38430 {
38431 for (unsigned i = 0; i < dims.length (); i++)
38432 {
38433 gcc_assert (dims[i].length == integer_one_node);
38434 decl = build_array_ref (dims[i].loc,
38435 decl, dims[i].low_bound);
38436 }
38437 goto start_component_ref;
38438 }
38439 else
38440 for (unsigned i = 0; i < dims.length (); i++)
38441 decl = build_omp_array_section (input_location, decl,
38442 dims[i].low_bound,
38443 dims[i].length);
38444 break;
38445 default:
38446 break;
38447 }
38448
38449 if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
38450 {
38451 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA)
38452 && cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN)
38453 && cp_parser_simulate_error (parser))
38454 {
38455 depend_lvalue:
38456 cp_parser_abort_tentative_parse (parser);
38457 decl = cp_parser_assignment_expression (parser, NULL,
38458 cast_p: false, decltype_p: false);
38459 }
38460 else
38461 cp_parser_parse_definitely (parser);
38462 }
38463
38464 build_clause:
38465 tree u = build_omp_clause (token->location, kind);
38466 OMP_CLAUSE_DECL (u) = decl;
38467 OMP_CLAUSE_CHAIN (u) = list;
38468 list = u;
38469 }
38470 else
38471 list = tree_cons (decl, NULL_TREE, list);
38472
38473 get_comma:
38474 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
38475 break;
38476 cp_lexer_consume_token (lexer: parser->lexer);
38477 }
38478
38479 if (colon)
38480 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
38481
38482 if (colon != NULL && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
38483 {
38484 *colon = true;
38485 cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON);
38486 return list;
38487 }
38488
38489 if (!cp_parser_require (parser, type: CPP_CLOSE_PAREN, token_desc: RT_CLOSE_PAREN))
38490 {
38491 int ending;
38492
38493 /* Try to resync to an unnested comma. Copied from
38494 cp_parser_parenthesized_expression_list. */
38495 skip_comma:
38496 if (colon)
38497 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
38498 ending = cp_parser_skip_to_closing_parenthesis (parser,
38499 /*recovering=*/true,
38500 /*or_comma=*/true,
38501 /*consume_paren=*/true);
38502 if (ending < 0)
38503 goto get_comma;
38504 }
38505
38506 return list;
38507}
38508
38509/* Similarly, but expect leading and trailing parenthesis. This is a very
38510 common case for omp clauses. */
38511
38512static tree
38513cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list,
38514 bool map_lvalue = false)
38515{
38516 if (parser->lexer->in_omp_decl_attribute)
38517 {
38518 if (kind)
38519 {
38520 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
38521 tree u = build_omp_clause (loc, kind);
38522 OMP_CLAUSE_DECL (u) = parser->lexer->in_omp_decl_attribute;
38523 OMP_CLAUSE_CHAIN (u) = list;
38524 return u;
38525 }
38526 else
38527 return tree_cons (parser->lexer->in_omp_decl_attribute, NULL_TREE,
38528 list);
38529 }
38530
38531 if (cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
38532 return cp_parser_omp_var_list_no_open (parser, kind, list, NULL,
38533 map_lvalue);
38534 return list;
38535}
38536
38537/* OpenACC 2.0:
38538 copy ( variable-list )
38539 copyin ( variable-list )
38540 copyout ( variable-list )
38541 create ( variable-list )
38542 delete ( variable-list )
38543 present ( variable-list )
38544
38545 OpenACC 2.6:
38546 no_create ( variable-list )
38547 attach ( variable-list )
38548 detach ( variable-list )
38549
38550 OpenACC 2.7:
38551 copyin (readonly : variable-list )
38552 */
38553
38554static tree
38555cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
38556 tree list)
38557{
38558 enum gomp_map_kind kind;
38559 switch (c_kind)
38560 {
38561 case PRAGMA_OACC_CLAUSE_ATTACH:
38562 kind = GOMP_MAP_ATTACH;
38563 break;
38564 case PRAGMA_OACC_CLAUSE_COPY:
38565 kind = GOMP_MAP_TOFROM;
38566 break;
38567 case PRAGMA_OACC_CLAUSE_COPYIN:
38568 kind = GOMP_MAP_TO;
38569 break;
38570 case PRAGMA_OACC_CLAUSE_COPYOUT:
38571 kind = GOMP_MAP_FROM;
38572 break;
38573 case PRAGMA_OACC_CLAUSE_CREATE:
38574 kind = GOMP_MAP_ALLOC;
38575 break;
38576 case PRAGMA_OACC_CLAUSE_DELETE:
38577 kind = GOMP_MAP_RELEASE;
38578 break;
38579 case PRAGMA_OACC_CLAUSE_DETACH:
38580 kind = GOMP_MAP_DETACH;
38581 break;
38582 case PRAGMA_OACC_CLAUSE_DEVICE:
38583 kind = GOMP_MAP_FORCE_TO;
38584 break;
38585 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
38586 kind = GOMP_MAP_DEVICE_RESIDENT;
38587 break;
38588 case PRAGMA_OACC_CLAUSE_LINK:
38589 kind = GOMP_MAP_LINK;
38590 break;
38591 case PRAGMA_OACC_CLAUSE_NO_CREATE:
38592 kind = GOMP_MAP_IF_PRESENT;
38593 break;
38594 case PRAGMA_OACC_CLAUSE_PRESENT:
38595 kind = GOMP_MAP_FORCE_PRESENT;
38596 break;
38597 case PRAGMA_OACC_CLAUSE_SELF:
38598 /* "The 'host' clause is a synonym for the 'self' clause." */
38599 case PRAGMA_OACC_CLAUSE_HOST:
38600 kind = GOMP_MAP_FORCE_FROM;
38601 break;
38602 default:
38603 gcc_unreachable ();
38604 }
38605
38606 tree nl = list;
38607 bool readonly = false;
38608 if (cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
38609 {
38610 /* Turn on readonly modifier parsing for copyin clause. */
38611 if (c_kind == PRAGMA_OACC_CLAUSE_COPYIN)
38612 {
38613 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
38614 if (token->type == CPP_NAME
38615 && !strcmp (IDENTIFIER_POINTER (token->u.value), s2: "readonly")
38616 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_COLON)
38617 {
38618 cp_lexer_consume_token (lexer: parser->lexer);
38619 cp_lexer_consume_token (lexer: parser->lexer);
38620 readonly = true;
38621 }
38622 }
38623 nl = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_MAP, list, NULL,
38624 map_lvalue: false);
38625 }
38626
38627 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
38628 {
38629 OMP_CLAUSE_SET_MAP_KIND (c, kind);
38630 if (readonly)
38631 OMP_CLAUSE_MAP_READONLY (c) = 1;
38632 }
38633
38634 return nl;
38635}
38636
38637/* OpenACC 2.0:
38638 deviceptr ( variable-list ) */
38639
38640static tree
38641cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list)
38642{
38643 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
38644 tree vars, t;
38645
38646 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
38647 cp_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
38648 variable-list must only allow for pointer variables. */
38649 vars = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_ERROR, NULL);
38650 for (t = vars; t; t = TREE_CHAIN (t))
38651 {
38652 tree v = TREE_PURPOSE (t);
38653 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
38654 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
38655 OMP_CLAUSE_DECL (u) = v;
38656 OMP_CLAUSE_CHAIN (u) = list;
38657 list = u;
38658 }
38659
38660 return list;
38661}
38662
38663/* OpenACC 2.5:
38664 auto
38665 finalize
38666 independent
38667 nohost
38668 seq */
38669
38670static tree
38671cp_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
38672 tree list)
38673{
38674 check_no_duplicate_clause (clauses: list, code, name: omp_clause_code_name[code], location: loc);
38675
38676 tree c = build_omp_clause (loc, code);
38677 OMP_CLAUSE_CHAIN (c) = list;
38678
38679 return c;
38680}
38681
38682 /* OpenACC:
38683 num_gangs ( expression )
38684 num_workers ( expression )
38685 vector_length ( expression ) */
38686
38687static tree
38688cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
38689 const char *str, tree list)
38690{
38691 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
38692
38693 matching_parens parens;
38694 if (!parens.require_open (parser))
38695 return list;
38696
38697 tree t = cp_parser_assignment_expression (parser, NULL, cast_p: false, decltype_p: false);
38698
38699 if (t == error_mark_node
38700 || !parens.require_close (parser))
38701 {
38702 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
38703 /*or_comma=*/false,
38704 /*consume_paren=*/true);
38705 return list;
38706 }
38707
38708 check_no_duplicate_clause (clauses: list, code, name: str, location: loc);
38709
38710 tree c = build_omp_clause (loc, code);
38711 OMP_CLAUSE_OPERAND (c, 0) = t;
38712 OMP_CLAUSE_CHAIN (c) = list;
38713 return c;
38714}
38715
38716/* OpenACC:
38717
38718 gang [( gang-arg-list )]
38719 worker [( [num:] int-expr )]
38720 vector [( [length:] int-expr )]
38721
38722 where gang-arg is one of:
38723
38724 [num:] int-expr
38725 static: size-expr
38726
38727 and size-expr may be:
38728
38729 *
38730 int-expr
38731*/
38732
38733static tree
38734cp_parser_oacc_shape_clause (cp_parser *parser, location_t loc,
38735 omp_clause_code kind,
38736 const char *str, tree list)
38737{
38738 const char *id = "num";
38739 cp_lexer *lexer = parser->lexer;
38740 tree ops[2] = { NULL_TREE, NULL_TREE }, c;
38741
38742 if (kind == OMP_CLAUSE_VECTOR)
38743 id = "length";
38744
38745 if (cp_lexer_next_token_is (lexer, type: CPP_OPEN_PAREN))
38746 {
38747 matching_parens parens;
38748 parens.consume_open (parser);
38749
38750 do
38751 {
38752 cp_token *next = cp_lexer_peek_token (lexer);
38753 int idx = 0;
38754
38755 /* Gang static argument. */
38756 if (kind == OMP_CLAUSE_GANG
38757 && cp_lexer_next_token_is_keyword (lexer, keyword: RID_STATIC))
38758 {
38759 cp_lexer_consume_token (lexer);
38760
38761 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
38762 goto cleanup_error;
38763
38764 idx = 1;
38765 if (ops[idx] != NULL)
38766 {
38767 cp_parser_error (parser, gmsgid: "too many %<static%> arguments");
38768 goto cleanup_error;
38769 }
38770
38771 /* Check for the '*' argument. */
38772 if (cp_lexer_next_token_is (lexer, type: CPP_MULT)
38773 && (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COMMA)
38774 || cp_lexer_nth_token_is (lexer: parser->lexer, n: 2,
38775 type: CPP_CLOSE_PAREN)))
38776 {
38777 cp_lexer_consume_token (lexer);
38778 ops[idx] = integer_minus_one_node;
38779
38780 if (cp_lexer_next_token_is (lexer, type: CPP_COMMA))
38781 {
38782 cp_lexer_consume_token (lexer);
38783 continue;
38784 }
38785 else break;
38786 }
38787 }
38788 /* Worker num: argument and vector length: arguments. */
38789 else if (cp_lexer_next_token_is (lexer, type: CPP_NAME)
38790 && id_equal (id: next->u.value, str: id)
38791 && cp_lexer_nth_token_is (lexer, n: 2, type: CPP_COLON))
38792 {
38793 cp_lexer_consume_token (lexer); /* id */
38794 cp_lexer_consume_token (lexer); /* ':' */
38795 }
38796
38797 /* Now collect the actual argument. */
38798 if (ops[idx] != NULL_TREE)
38799 {
38800 cp_parser_error (parser, gmsgid: "unexpected argument");
38801 goto cleanup_error;
38802 }
38803
38804 tree expr = cp_parser_assignment_expression (parser, NULL, cast_p: false,
38805 decltype_p: false);
38806 if (expr == error_mark_node)
38807 goto cleanup_error;
38808
38809 mark_exp_read (expr);
38810 ops[idx] = expr;
38811
38812 if (kind == OMP_CLAUSE_GANG
38813 && cp_lexer_next_token_is (lexer, type: CPP_COMMA))
38814 {
38815 cp_lexer_consume_token (lexer);
38816 continue;
38817 }
38818 break;
38819 }
38820 while (1);
38821
38822 if (!parens.require_close (parser))
38823 goto cleanup_error;
38824 }
38825
38826 check_no_duplicate_clause (clauses: list, code: kind, name: str, location: loc);
38827
38828 c = build_omp_clause (loc, kind);
38829
38830 if (ops[1])
38831 OMP_CLAUSE_OPERAND (c, 1) = ops[1];
38832
38833 OMP_CLAUSE_OPERAND (c, 0) = ops[0];
38834 OMP_CLAUSE_CHAIN (c) = list;
38835
38836 return c;
38837
38838 cleanup_error:
38839 cp_parser_skip_to_closing_parenthesis (parser, recovering: false, or_comma: false, consume_paren: true);
38840 return list;
38841}
38842
38843/* OpenACC 2.0:
38844 tile ( size-expr-list ) */
38845
38846static tree
38847cp_parser_oacc_clause_tile (cp_parser *parser, location_t clause_loc, tree list)
38848{
38849 tree c, expr = error_mark_node;
38850 tree tile = NULL_TREE;
38851
38852 /* Collapse and tile are mutually exclusive. (The spec doesn't say
38853 so, but the spec authors never considered such a case and have
38854 differing opinions on what it might mean, including 'not
38855 allowed'.) */
38856 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_TILE, name: "tile", location: clause_loc);
38857 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_COLLAPSE, name: "collapse",
38858 location: clause_loc);
38859
38860 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
38861 return list;
38862
38863 do
38864 {
38865 if (tile && !cp_parser_require (parser, type: CPP_COMMA, token_desc: RT_COMMA))
38866 return list;
38867
38868 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MULT)
38869 && (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COMMA)
38870 || cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_CLOSE_PAREN)))
38871 {
38872 cp_lexer_consume_token (lexer: parser->lexer);
38873 expr = integer_zero_node;
38874 }
38875 else
38876 expr = cp_parser_constant_expression (parser);
38877
38878 tile = tree_cons (NULL_TREE, expr, tile);
38879 }
38880 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN));
38881
38882 /* Consume the trailing ')'. */
38883 cp_lexer_consume_token (lexer: parser->lexer);
38884
38885 c = build_omp_clause (clause_loc, OMP_CLAUSE_TILE);
38886 tile = nreverse (tile);
38887 OMP_CLAUSE_TILE_LIST (c) = tile;
38888 OMP_CLAUSE_CHAIN (c) = list;
38889 return c;
38890}
38891
38892/* OpenACC 2.0
38893 Parse wait clause or directive parameters. */
38894
38895static tree
38896cp_parser_oacc_wait_list (cp_parser *parser, location_t clause_loc, tree list)
38897{
38898 vec<tree, va_gc> *args;
38899 tree t, args_tree;
38900
38901 args = cp_parser_parenthesized_expression_list (parser, is_attribute_list: non_attr,
38902 /*cast_p=*/false,
38903 /*allow_expansion_p=*/true,
38904 /*non_constant_p=*/NULL);
38905
38906 if (args == NULL || args->length () == 0)
38907 {
38908 if (args != NULL)
38909 {
38910 cp_parser_error (parser, gmsgid: "expected integer expression list");
38911 release_tree_vector (args);
38912 }
38913 return list;
38914 }
38915
38916 args_tree = build_tree_list_vec (args);
38917
38918 release_tree_vector (args);
38919
38920 for (t = args_tree; t; t = TREE_CHAIN (t))
38921 {
38922 tree targ = TREE_VALUE (t);
38923
38924 if (targ != error_mark_node)
38925 {
38926 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
38927 error ("%<wait%> expression must be integral");
38928 else
38929 {
38930 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
38931
38932 targ = mark_rvalue_use (targ);
38933 OMP_CLAUSE_DECL (c) = targ;
38934 OMP_CLAUSE_CHAIN (c) = list;
38935 list = c;
38936 }
38937 }
38938 }
38939
38940 return list;
38941}
38942
38943/* OpenACC:
38944 wait [( int-expr-list )] */
38945
38946static tree
38947cp_parser_oacc_clause_wait (cp_parser *parser, tree list)
38948{
38949 location_t location = cp_lexer_peek_token (lexer: parser->lexer)->location;
38950
38951 if (cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_OPEN_PAREN)
38952 list = cp_parser_oacc_wait_list (parser, clause_loc: location, list);
38953 else
38954 {
38955 tree c = build_omp_clause (location, OMP_CLAUSE_WAIT);
38956
38957 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
38958 OMP_CLAUSE_CHAIN (c) = list;
38959 list = c;
38960 }
38961
38962 return list;
38963}
38964
38965/* OpenMP 3.0:
38966 collapse ( constant-expression ) */
38967
38968static tree
38969cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location)
38970{
38971 tree c, num;
38972 location_t loc;
38973 HOST_WIDE_INT n;
38974
38975 loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
38976 matching_parens parens;
38977 if (!parens.require_open (parser))
38978 return list;
38979
38980 num = cp_parser_constant_expression (parser);
38981
38982 if (!parens.require_close (parser))
38983 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
38984 /*or_comma=*/false,
38985 /*consume_paren=*/true);
38986
38987 if (num == error_mark_node)
38988 return list;
38989 num = fold_non_dependent_expr (num);
38990 if (!tree_fits_shwi_p (num)
38991 || !INTEGRAL_TYPE_P (TREE_TYPE (num))
38992 || (n = tree_to_shwi (num)) <= 0
38993 || (int) n != n)
38994 {
38995 error_at (loc, "collapse argument needs positive constant integer expression");
38996 return list;
38997 }
38998
38999 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_COLLAPSE, name: "collapse", location);
39000 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_TILE, name: "tile", location);
39001 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
39002 OMP_CLAUSE_CHAIN (c) = list;
39003 OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
39004
39005 return c;
39006}
39007
39008/* OpenMP 2.5:
39009 default ( none | shared )
39010
39011 OpenMP 5.1:
39012 default ( private | firstprivate )
39013
39014 OpenACC:
39015 default ( none | present ) */
39016
39017static tree
39018cp_parser_omp_clause_default (cp_parser *parser, tree list,
39019 location_t location, bool is_oacc)
39020{
39021 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
39022 tree c;
39023
39024 matching_parens parens;
39025 if (!parens.require_open (parser))
39026 return list;
39027 if (!is_oacc && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_PRIVATE))
39028 {
39029 kind = OMP_CLAUSE_DEFAULT_PRIVATE;
39030 cp_lexer_consume_token (lexer: parser->lexer);
39031 }
39032 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
39033 {
39034 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39035 const char *p = IDENTIFIER_POINTER (id);
39036
39037 switch (p[0])
39038 {
39039 case 'n':
39040 if (strcmp (s1: "none", s2: p) != 0)
39041 goto invalid_kind;
39042 kind = OMP_CLAUSE_DEFAULT_NONE;
39043 break;
39044
39045 case 'p':
39046 if (strcmp (s1: "present", s2: p) != 0 || !is_oacc)
39047 goto invalid_kind;
39048 kind = OMP_CLAUSE_DEFAULT_PRESENT;
39049 break;
39050
39051 case 'f':
39052 if (strcmp (s1: "firstprivate", s2: p) != 0 || is_oacc)
39053 goto invalid_kind;
39054 kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
39055 break;
39056
39057 case 's':
39058 if (strcmp (s1: "shared", s2: p) != 0 || is_oacc)
39059 goto invalid_kind;
39060 kind = OMP_CLAUSE_DEFAULT_SHARED;
39061 break;
39062
39063 default:
39064 goto invalid_kind;
39065 }
39066
39067 cp_lexer_consume_token (lexer: parser->lexer);
39068 }
39069 else
39070 {
39071 invalid_kind:
39072 if (is_oacc)
39073 cp_parser_error (parser, gmsgid: "expected %<none%> or %<present%>");
39074 else
39075 cp_parser_error (parser, gmsgid: "expected %<none%>, %<shared%>, "
39076 "%<private%> or %<firstprivate%>");
39077 }
39078
39079 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED
39080 || !parens.require_close (parser))
39081 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39082 /*or_comma=*/false,
39083 /*consume_paren=*/true);
39084
39085 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
39086 return list;
39087
39088 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_DEFAULT, name: "default", location);
39089 c = build_omp_clause (location, OMP_CLAUSE_DEFAULT);
39090 OMP_CLAUSE_CHAIN (c) = list;
39091 OMP_CLAUSE_DEFAULT_KIND (c) = kind;
39092
39093 return c;
39094}
39095
39096/* OpenMP 3.1:
39097 final ( expression ) */
39098
39099static tree
39100cp_parser_omp_clause_final (cp_parser *parser, tree list, location_t location)
39101{
39102 tree t, c;
39103
39104 matching_parens parens;
39105 if (!parens.require_open (parser))
39106 return list;
39107
39108 t = cp_parser_assignment_expression (parser);
39109
39110 if (t == error_mark_node
39111 || !parens.require_close (parser))
39112 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39113 /*or_comma=*/false,
39114 /*consume_paren=*/true);
39115
39116 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_FINAL, name: "final", location);
39117
39118 c = build_omp_clause (location, OMP_CLAUSE_FINAL);
39119 OMP_CLAUSE_FINAL_EXPR (c) = t;
39120 OMP_CLAUSE_CHAIN (c) = list;
39121
39122 return c;
39123}
39124
39125/* OpenMP 5.1:
39126 indirect [( expression )]
39127*/
39128
39129static tree
39130cp_parser_omp_clause_indirect (cp_parser *parser, tree list,
39131 location_t location)
39132{
39133 tree t;
39134
39135 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
39136 {
39137 matching_parens parens;
39138 if (!parens.require_open (parser))
39139 return list;
39140
39141 bool non_constant_p;
39142 t = cp_parser_constant_expression (parser, allow_non_constant_p: true, non_constant_p: &non_constant_p);
39143
39144 if (t != error_mark_node && non_constant_p)
39145 error_at (location, "expected constant logical expression");
39146
39147 if (t == error_mark_node
39148 || !parens.require_close (parser))
39149 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39150 /*or_comma=*/false,
39151 /*consume_paren=*/true);
39152 }
39153 else
39154 t = integer_one_node;
39155
39156 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_INDIRECT, name: "indirect", location);
39157
39158 tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
39159 OMP_CLAUSE_INDIRECT_EXPR (c) = t;
39160 OMP_CLAUSE_CHAIN (c) = list;
39161
39162 return c;
39163}
39164
39165/* OpenMP 2.5:
39166 if ( expression )
39167
39168 OpenMP 4.5:
39169 if ( directive-name-modifier : expression )
39170
39171 directive-name-modifier:
39172 parallel | task | taskloop | target data | target | target update
39173 | target enter data | target exit data
39174
39175 OpenMP 5.0:
39176 directive-name-modifier:
39177 ... | simd | cancel */
39178
39179static tree
39180cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
39181 bool is_omp)
39182{
39183 tree t, c;
39184 enum tree_code if_modifier = ERROR_MARK;
39185
39186 matching_parens parens;
39187 if (!parens.require_open (parser))
39188 return list;
39189
39190 if (is_omp && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
39191 {
39192 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39193 const char *p = IDENTIFIER_POINTER (id);
39194 int n = 2;
39195
39196 if (strcmp (s1: "cancel", s2: p) == 0)
39197 if_modifier = VOID_CST;
39198 else if (strcmp (s1: "parallel", s2: p) == 0)
39199 if_modifier = OMP_PARALLEL;
39200 else if (strcmp (s1: "simd", s2: p) == 0)
39201 if_modifier = OMP_SIMD;
39202 else if (strcmp (s1: "task", s2: p) == 0)
39203 if_modifier = OMP_TASK;
39204 else if (strcmp (s1: "taskloop", s2: p) == 0)
39205 if_modifier = OMP_TASKLOOP;
39206 else if (strcmp (s1: "target", s2: p) == 0)
39207 {
39208 if_modifier = OMP_TARGET;
39209 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
39210 {
39211 id = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->u.value;
39212 p = IDENTIFIER_POINTER (id);
39213 if (strcmp (s1: "data", s2: p) == 0)
39214 if_modifier = OMP_TARGET_DATA;
39215 else if (strcmp (s1: "update", s2: p) == 0)
39216 if_modifier = OMP_TARGET_UPDATE;
39217 else if (strcmp (s1: "enter", s2: p) == 0)
39218 if_modifier = OMP_TARGET_ENTER_DATA;
39219 else if (strcmp (s1: "exit", s2: p) == 0)
39220 if_modifier = OMP_TARGET_EXIT_DATA;
39221 if (if_modifier != OMP_TARGET)
39222 n = 3;
39223 else
39224 {
39225 location_t loc
39226 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->location;
39227 error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
39228 "or %<exit%>");
39229 if_modifier = ERROR_MARK;
39230 }
39231 if (if_modifier == OMP_TARGET_ENTER_DATA
39232 || if_modifier == OMP_TARGET_EXIT_DATA)
39233 {
39234 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_NAME))
39235 {
39236 id = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->u.value;
39237 p = IDENTIFIER_POINTER (id);
39238 if (strcmp (s1: "data", s2: p) == 0)
39239 n = 4;
39240 }
39241 if (n != 4)
39242 {
39243 location_t loc
39244 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->location;
39245 error_at (loc, "expected %<data%>");
39246 if_modifier = ERROR_MARK;
39247 }
39248 }
39249 }
39250 }
39251 if (if_modifier != ERROR_MARK)
39252 {
39253 if (cp_lexer_nth_token_is (lexer: parser->lexer, n, type: CPP_COLON))
39254 {
39255 while (n-- > 0)
39256 cp_lexer_consume_token (lexer: parser->lexer);
39257 }
39258 else
39259 {
39260 if (n > 2)
39261 {
39262 location_t loc
39263 = cp_lexer_peek_nth_token (lexer: parser->lexer, n)->location;
39264 error_at (loc, "expected %<:%>");
39265 }
39266 if_modifier = ERROR_MARK;
39267 }
39268 }
39269 }
39270
39271 t = cp_parser_assignment_expression (parser);
39272
39273 if (t == error_mark_node
39274 || !parens.require_close (parser))
39275 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39276 /*or_comma=*/false,
39277 /*consume_paren=*/true);
39278
39279 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
39280 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
39281 {
39282 if (if_modifier != ERROR_MARK
39283 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
39284 {
39285 const char *p = NULL;
39286 switch (if_modifier)
39287 {
39288 case VOID_CST: p = "cancel"; break;
39289 case OMP_PARALLEL: p = "parallel"; break;
39290 case OMP_SIMD: p = "simd"; break;
39291 case OMP_TASK: p = "task"; break;
39292 case OMP_TASKLOOP: p = "taskloop"; break;
39293 case OMP_TARGET_DATA: p = "target data"; break;
39294 case OMP_TARGET: p = "target"; break;
39295 case OMP_TARGET_UPDATE: p = "target update"; break;
39296 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
39297 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
39298 default: gcc_unreachable ();
39299 }
39300 error_at (location, "too many %<if%> clauses with %qs modifier",
39301 p);
39302 return list;
39303 }
39304 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
39305 {
39306 if (!is_omp)
39307 error_at (location, "too many %<if%> clauses");
39308 else
39309 error_at (location, "too many %<if%> clauses without modifier");
39310 return list;
39311 }
39312 else if (if_modifier == ERROR_MARK
39313 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
39314 {
39315 error_at (location, "if any %<if%> clause has modifier, then all "
39316 "%<if%> clauses have to use modifier");
39317 return list;
39318 }
39319 }
39320
39321 c = build_omp_clause (location, OMP_CLAUSE_IF);
39322 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
39323 OMP_CLAUSE_IF_EXPR (c) = t;
39324 OMP_CLAUSE_CHAIN (c) = list;
39325
39326 return c;
39327}
39328
39329/* OpenMP 3.1:
39330 mergeable */
39331
39332static tree
39333cp_parser_omp_clause_mergeable (cp_parser * /*parser*/,
39334 tree list, location_t location)
39335{
39336 tree c;
39337
39338 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_MERGEABLE, name: "mergeable",
39339 location);
39340
39341 c = build_omp_clause (location, OMP_CLAUSE_MERGEABLE);
39342 OMP_CLAUSE_CHAIN (c) = list;
39343 return c;
39344}
39345
39346/* OpenMP 2.5:
39347 nowait */
39348
39349static tree
39350cp_parser_omp_clause_nowait (cp_parser * /*parser*/,
39351 tree list, location_t location)
39352{
39353 tree c;
39354
39355 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_NOWAIT, name: "nowait", location);
39356
39357 c = build_omp_clause (location, OMP_CLAUSE_NOWAIT);
39358 OMP_CLAUSE_CHAIN (c) = list;
39359 return c;
39360}
39361
39362/* OpenMP 2.5:
39363 num_threads ( expression ) */
39364
39365static tree
39366cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
39367 location_t location)
39368{
39369 tree t, c;
39370
39371 matching_parens parens;
39372 if (!parens.require_open (parser))
39373 return list;
39374
39375 t = cp_parser_assignment_expression (parser);
39376
39377 if (t == error_mark_node
39378 || !parens.require_close (parser))
39379 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39380 /*or_comma=*/false,
39381 /*consume_paren=*/true);
39382
39383 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_NUM_THREADS,
39384 name: "num_threads", location);
39385
39386 c = build_omp_clause (location, OMP_CLAUSE_NUM_THREADS);
39387 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
39388 OMP_CLAUSE_CHAIN (c) = list;
39389
39390 return c;
39391}
39392
39393/* OpenMP 4.5:
39394 num_tasks ( expression )
39395
39396 OpenMP 5.1:
39397 num_tasks ( strict : expression ) */
39398
39399static tree
39400cp_parser_omp_clause_num_tasks (cp_parser *parser, tree list,
39401 location_t location)
39402{
39403 tree t, c;
39404
39405 matching_parens parens;
39406 if (!parens.require_open (parser))
39407 return list;
39408
39409 bool strict = false;
39410 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
39411 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COLON))
39412 {
39413 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39414 if (!strcmp (IDENTIFIER_POINTER (id), s2: "strict"))
39415 {
39416 strict = true;
39417 cp_lexer_consume_token (lexer: parser->lexer);
39418 cp_lexer_consume_token (lexer: parser->lexer);
39419 }
39420 }
39421
39422 t = cp_parser_assignment_expression (parser);
39423
39424 if (t == error_mark_node
39425 || !parens.require_close (parser))
39426 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39427 /*or_comma=*/false,
39428 /*consume_paren=*/true);
39429
39430 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_NUM_TASKS,
39431 name: "num_tasks", location);
39432
39433 c = build_omp_clause (location, OMP_CLAUSE_NUM_TASKS);
39434 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
39435 OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
39436 OMP_CLAUSE_CHAIN (c) = list;
39437
39438 return c;
39439}
39440
39441/* OpenMP 4.5:
39442 grainsize ( expression )
39443
39444 OpenMP 5.1:
39445 grainsize ( strict : expression ) */
39446
39447static tree
39448cp_parser_omp_clause_grainsize (cp_parser *parser, tree list,
39449 location_t location)
39450{
39451 tree t, c;
39452
39453 matching_parens parens;
39454 if (!parens.require_open (parser))
39455 return list;
39456
39457 bool strict = false;
39458 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
39459 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COLON))
39460 {
39461 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39462 if (!strcmp (IDENTIFIER_POINTER (id), s2: "strict"))
39463 {
39464 strict = true;
39465 cp_lexer_consume_token (lexer: parser->lexer);
39466 cp_lexer_consume_token (lexer: parser->lexer);
39467 }
39468 }
39469
39470 t = cp_parser_assignment_expression (parser);
39471
39472 if (t == error_mark_node
39473 || !parens.require_close (parser))
39474 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39475 /*or_comma=*/false,
39476 /*consume_paren=*/true);
39477
39478 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_GRAINSIZE,
39479 name: "grainsize", location);
39480
39481 c = build_omp_clause (location, OMP_CLAUSE_GRAINSIZE);
39482 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
39483 OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
39484 OMP_CLAUSE_CHAIN (c) = list;
39485
39486 return c;
39487}
39488
39489/* OpenMP 4.5:
39490 priority ( expression ) */
39491
39492static tree
39493cp_parser_omp_clause_priority (cp_parser *parser, tree list,
39494 location_t location)
39495{
39496 tree t, c;
39497
39498 matching_parens parens;
39499 if (!parens.require_open (parser))
39500 return list;
39501
39502 t = cp_parser_assignment_expression (parser);
39503
39504 if (t == error_mark_node
39505 || !parens.require_close (parser))
39506 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39507 /*or_comma=*/false,
39508 /*consume_paren=*/true);
39509
39510 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_PRIORITY,
39511 name: "priority", location);
39512
39513 c = build_omp_clause (location, OMP_CLAUSE_PRIORITY);
39514 OMP_CLAUSE_PRIORITY_EXPR (c) = t;
39515 OMP_CLAUSE_CHAIN (c) = list;
39516
39517 return c;
39518}
39519
39520/* OpenMP 4.5:
39521 hint ( expression ) */
39522
39523static tree
39524cp_parser_omp_clause_hint (cp_parser *parser, tree list, location_t location)
39525{
39526 tree t, c;
39527
39528 matching_parens parens;
39529 if (!parens.require_open (parser))
39530 return list;
39531
39532 t = cp_parser_assignment_expression (parser);
39533
39534 if (t != error_mark_node)
39535 {
39536 t = fold_non_dependent_expr (t);
39537 if (!value_dependent_expression_p (t)
39538 && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
39539 || !tree_fits_shwi_p (t)
39540 || tree_int_cst_sgn (t) == -1))
39541 error_at (location, "expected constant integer expression with "
39542 "valid sync-hint value");
39543 }
39544 if (t == error_mark_node
39545 || !parens.require_close (parser))
39546 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39547 /*or_comma=*/false,
39548 /*consume_paren=*/true);
39549 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_HINT, name: "hint", location);
39550
39551 c = build_omp_clause (location, OMP_CLAUSE_HINT);
39552 OMP_CLAUSE_HINT_EXPR (c) = t;
39553 OMP_CLAUSE_CHAIN (c) = list;
39554
39555 return c;
39556}
39557
39558/* OpenMP 5.1:
39559 filter ( integer-expression ) */
39560
39561static tree
39562cp_parser_omp_clause_filter (cp_parser *parser, tree list, location_t location)
39563{
39564 tree t, c;
39565
39566 matching_parens parens;
39567 if (!parens.require_open (parser))
39568 return list;
39569
39570 t = cp_parser_assignment_expression (parser);
39571
39572 if (t == error_mark_node
39573 || !parens.require_close (parser))
39574 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39575 /*or_comma=*/false,
39576 /*consume_paren=*/true);
39577 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_FILTER, name: "filter", location);
39578
39579 c = build_omp_clause (location, OMP_CLAUSE_FILTER);
39580 OMP_CLAUSE_FILTER_EXPR (c) = t;
39581 OMP_CLAUSE_CHAIN (c) = list;
39582
39583 return c;
39584}
39585
39586/* OpenMP 4.5:
39587 defaultmap ( tofrom : scalar )
39588
39589 OpenMP 5.0:
39590 defaultmap ( implicit-behavior [ : variable-category ] ) */
39591
39592static tree
39593cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
39594 location_t location)
39595{
39596 tree c, id;
39597 const char *p;
39598 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
39599 enum omp_clause_defaultmap_kind category
39600 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
39601
39602 matching_parens parens;
39603 if (!parens.require_open (parser))
39604 return list;
39605
39606 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_DEFAULT))
39607 p = "default";
39608 else if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
39609 {
39610 invalid_behavior:
39611 cp_parser_error (parser, gmsgid: "expected %<alloc%>, %<to%>, %<from%>, "
39612 "%<tofrom%>, %<firstprivate%>, %<none%> "
39613 "or %<default%>");
39614 goto out_err;
39615 }
39616 else
39617 {
39618 id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39619 p = IDENTIFIER_POINTER (id);
39620 }
39621
39622 switch (p[0])
39623 {
39624 case 'a':
39625 if (strcmp (s1: "alloc", s2: p) == 0)
39626 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
39627 else
39628 goto invalid_behavior;
39629 break;
39630
39631 case 'd':
39632 if (strcmp (s1: "default", s2: p) == 0)
39633 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
39634 else
39635 goto invalid_behavior;
39636 break;
39637
39638 case 'f':
39639 if (strcmp (s1: "firstprivate", s2: p) == 0)
39640 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
39641 else if (strcmp (s1: "from", s2: p) == 0)
39642 behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
39643 else
39644 goto invalid_behavior;
39645 break;
39646
39647 case 'n':
39648 if (strcmp (s1: "none", s2: p) == 0)
39649 behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
39650 else
39651 goto invalid_behavior;
39652 break;
39653
39654 case 'p':
39655 if (strcmp (s1: "present", s2: p) == 0)
39656 behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
39657 else
39658 goto invalid_behavior;
39659 break;
39660
39661 case 't':
39662 if (strcmp (s1: "tofrom", s2: p) == 0)
39663 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
39664 else if (strcmp (s1: "to", s2: p) == 0)
39665 behavior = OMP_CLAUSE_DEFAULTMAP_TO;
39666 else
39667 goto invalid_behavior;
39668 break;
39669
39670 default:
39671 goto invalid_behavior;
39672 }
39673 cp_lexer_consume_token (lexer: parser->lexer);
39674
39675 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
39676 {
39677 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
39678 goto out_err;
39679
39680 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
39681 {
39682 invalid_category:
39683 cp_parser_error (parser, gmsgid: "expected %<scalar%>, %<aggregate%>, "
39684 "%<all%>");
39685 goto out_err;
39686 }
39687 id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39688 p = IDENTIFIER_POINTER (id);
39689
39690 switch (p[0])
39691 {
39692 case 'a':
39693 if (strcmp (s1: "aggregate", s2: p) == 0)
39694 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
39695 else if (strcmp (s1: "all", s2: p) == 0)
39696 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
39697 else
39698 goto invalid_category;
39699 break;
39700
39701 case 'p':
39702 if (strcmp (s1: "pointer", s2: p) == 0)
39703 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
39704 else
39705 goto invalid_category;
39706 break;
39707
39708 case 's':
39709 if (strcmp (s1: "scalar", s2: p) == 0)
39710 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
39711 else
39712 goto invalid_category;
39713 break;
39714
39715 default:
39716 goto invalid_category;
39717 }
39718
39719 cp_lexer_consume_token (lexer: parser->lexer);
39720 }
39721 if (!parens.require_close (parser))
39722 goto out_err;
39723
39724 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
39725 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
39726 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
39727 || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
39728 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
39729 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
39730 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
39731 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
39732 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
39733 {
39734 enum omp_clause_defaultmap_kind cat = category;
39735 location_t loc = OMP_CLAUSE_LOCATION (c);
39736 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
39737 || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
39738 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
39739 != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
39740 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
39741 p = NULL;
39742 switch (cat)
39743 {
39744 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
39745 p = NULL;
39746 break;
39747 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
39748 p = "all";
39749 break;
39750 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
39751 p = "aggregate";
39752 break;
39753 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
39754 p = "pointer";
39755 break;
39756 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
39757 p = "scalar";
39758 break;
39759 default:
39760 gcc_unreachable ();
39761 }
39762 if (p)
39763 error_at (loc, "too many %<defaultmap%> clauses with %qs category",
39764 p);
39765 else
39766 error_at (loc, "too many %<defaultmap%> clauses with unspecified "
39767 "category");
39768 break;
39769 }
39770
39771 c = build_omp_clause (location, OMP_CLAUSE_DEFAULTMAP);
39772 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
39773 OMP_CLAUSE_CHAIN (c) = list;
39774 return c;
39775
39776 out_err:
39777 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39778 /*or_comma=*/false,
39779 /*consume_paren=*/true);
39780 return list;
39781}
39782
39783/* OpenMP 5.0:
39784 order ( concurrent )
39785
39786 OpenMP 5.1:
39787 order ( order-modifier : concurrent )
39788
39789 order-modifier:
39790 reproducible
39791 unconstrained */
39792
39793static tree
39794cp_parser_omp_clause_order (cp_parser *parser, tree list, location_t location)
39795{
39796 tree c, id;
39797 const char *p;
39798 bool unconstrained = false;
39799 bool reproducible = false;
39800
39801 matching_parens parens;
39802 if (!parens.require_open (parser))
39803 return list;
39804
39805 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
39806 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COLON))
39807 {
39808 id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39809 p = IDENTIFIER_POINTER (id);
39810 if (strcmp (s1: p, s2: "unconstrained") == 0)
39811 unconstrained = true;
39812 else if (strcmp (s1: p, s2: "reproducible") == 0)
39813 reproducible = true;
39814 else
39815 {
39816 cp_parser_error (parser, gmsgid: "expected %<reproducible%> or "
39817 "%<unconstrained%>");
39818 goto out_err;
39819 }
39820 cp_lexer_consume_token (lexer: parser->lexer);
39821 cp_lexer_consume_token (lexer: parser->lexer);
39822 }
39823 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
39824 {
39825 cp_parser_error (parser, gmsgid: "expected %<concurrent%>");
39826 goto out_err;
39827 }
39828 else
39829 {
39830 id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39831 p = IDENTIFIER_POINTER (id);
39832 }
39833 if (strcmp (s1: p, s2: "concurrent") != 0)
39834 {
39835 cp_parser_error (parser, gmsgid: "expected %<concurrent%>");
39836 goto out_err;
39837 }
39838 cp_lexer_consume_token (lexer: parser->lexer);
39839 if (!parens.require_close (parser))
39840 goto out_err;
39841
39842 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_ORDER, name: "order", location);
39843 c = build_omp_clause (location, OMP_CLAUSE_ORDER);
39844 OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
39845 OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
39846 OMP_CLAUSE_CHAIN (c) = list;
39847 return c;
39848
39849 out_err:
39850 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39851 /*or_comma=*/false,
39852 /*consume_paren=*/true);
39853 return list;
39854}
39855
39856/* OpenMP 5.0:
39857 bind ( teams | parallel | thread ) */
39858
39859static tree
39860cp_parser_omp_clause_bind (cp_parser *parser, tree list,
39861 location_t location)
39862{
39863 tree c;
39864 const char *p;
39865 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
39866
39867 matching_parens parens;
39868 if (!parens.require_open (parser))
39869 return list;
39870
39871 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
39872 {
39873 invalid:
39874 cp_parser_error (parser,
39875 gmsgid: "expected %<teams%>, %<parallel%> or %<thread%>");
39876 goto out_err;
39877 }
39878 else
39879 {
39880 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
39881 p = IDENTIFIER_POINTER (id);
39882 }
39883 if (strcmp (s1: p, s2: "teams") == 0)
39884 kind = OMP_CLAUSE_BIND_TEAMS;
39885 else if (strcmp (s1: p, s2: "parallel") == 0)
39886 kind = OMP_CLAUSE_BIND_PARALLEL;
39887 else if (strcmp (s1: p, s2: "thread") != 0)
39888 goto invalid;
39889 cp_lexer_consume_token (lexer: parser->lexer);
39890 if (!parens.require_close (parser))
39891 goto out_err;
39892
39893 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind", location); */
39894 c = build_omp_clause (location, OMP_CLAUSE_BIND);
39895 OMP_CLAUSE_BIND_KIND (c) = kind;
39896 OMP_CLAUSE_CHAIN (c) = list;
39897 return c;
39898
39899 out_err:
39900 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39901 /*or_comma=*/false,
39902 /*consume_paren=*/true);
39903 return list;
39904}
39905
39906/* OpenMP 2.5:
39907 ordered
39908
39909 OpenMP 4.5:
39910 ordered ( constant-expression ) */
39911
39912static tree
39913cp_parser_omp_clause_ordered (cp_parser *parser,
39914 tree list, location_t location)
39915{
39916 tree c, num = NULL_TREE;
39917 HOST_WIDE_INT n;
39918
39919 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_ORDERED,
39920 name: "ordered", location);
39921
39922 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
39923 {
39924 matching_parens parens;
39925 parens.consume_open (parser);
39926
39927 num = cp_parser_constant_expression (parser);
39928
39929 if (!parens.require_close (parser))
39930 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
39931 /*or_comma=*/false,
39932 /*consume_paren=*/true);
39933
39934 if (num == error_mark_node)
39935 return list;
39936 num = fold_non_dependent_expr (num);
39937 if (!tree_fits_shwi_p (num)
39938 || !INTEGRAL_TYPE_P (TREE_TYPE (num))
39939 || (n = tree_to_shwi (num)) <= 0
39940 || (int) n != n)
39941 {
39942 error_at (location,
39943 "ordered argument needs positive constant integer "
39944 "expression");
39945 return list;
39946 }
39947 }
39948
39949 c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
39950 OMP_CLAUSE_ORDERED_EXPR (c) = num;
39951 OMP_CLAUSE_CHAIN (c) = list;
39952 return c;
39953}
39954
39955/* OpenMP 2.5:
39956 reduction ( reduction-operator : variable-list )
39957
39958 reduction-operator:
39959 One of: + * - & ^ | && ||
39960
39961 OpenMP 3.1:
39962
39963 reduction-operator:
39964 One of: + * - & ^ | && || min max
39965
39966 OpenMP 4.0:
39967
39968 reduction-operator:
39969 One of: + * - & ^ | && ||
39970 id-expression
39971
39972 OpenMP 5.0:
39973 reduction ( reduction-modifier, reduction-operator : variable-list )
39974 in_reduction ( reduction-operator : variable-list )
39975 task_reduction ( reduction-operator : variable-list ) */
39976
39977static tree
39978cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
39979 bool is_omp, tree list)
39980{
39981 enum tree_code code = ERROR_MARK;
39982 tree nlist, c, id = NULL_TREE;
39983 bool task = false;
39984 bool inscan = false;
39985
39986 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
39987 return list;
39988
39989 if (kind == OMP_CLAUSE_REDUCTION && is_omp)
39990 {
39991 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_DEFAULT)
39992 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COMMA))
39993 {
39994 cp_lexer_consume_token (lexer: parser->lexer);
39995 cp_lexer_consume_token (lexer: parser->lexer);
39996 }
39997 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
39998 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COMMA))
39999 {
40000 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40001 const char *p = IDENTIFIER_POINTER (id);
40002 if (strcmp (s1: p, s2: "task") == 0)
40003 task = true;
40004 else if (strcmp (s1: p, s2: "inscan") == 0)
40005 inscan = true;
40006 if (task || inscan)
40007 {
40008 cp_lexer_consume_token (lexer: parser->lexer);
40009 cp_lexer_consume_token (lexer: parser->lexer);
40010 }
40011 }
40012 }
40013
40014 switch (cp_lexer_peek_token (lexer: parser->lexer)->type)
40015 {
40016 case CPP_PLUS: code = PLUS_EXPR; break;
40017 case CPP_MULT: code = MULT_EXPR; break;
40018 case CPP_MINUS: code = MINUS_EXPR; break;
40019 case CPP_AND: code = BIT_AND_EXPR; break;
40020 case CPP_XOR: code = BIT_XOR_EXPR; break;
40021 case CPP_OR: code = BIT_IOR_EXPR; break;
40022 case CPP_AND_AND: code = TRUTH_ANDIF_EXPR; break;
40023 case CPP_OR_OR: code = TRUTH_ORIF_EXPR; break;
40024 default: break;
40025 }
40026
40027 if (code != ERROR_MARK)
40028 cp_lexer_consume_token (lexer: parser->lexer);
40029 else
40030 {
40031 bool saved_colon_corrects_to_scope_p;
40032 saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
40033 parser->colon_corrects_to_scope_p = false;
40034 id = cp_parser_id_expression (parser, /*template_p=*/template_keyword_p: false,
40035 /*check_dependency_p=*/true,
40036 /*template_p=*/NULL,
40037 /*declarator_p=*/false,
40038 /*optional_p=*/false);
40039 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
40040 if (identifier_p (t: id))
40041 {
40042 const char *p = IDENTIFIER_POINTER (id);
40043
40044 if (strcmp (s1: p, s2: "min") == 0)
40045 code = MIN_EXPR;
40046 else if (strcmp (s1: p, s2: "max") == 0)
40047 code = MAX_EXPR;
40048 else if (id == ovl_op_identifier (isass: false, code: PLUS_EXPR))
40049 code = PLUS_EXPR;
40050 else if (id == ovl_op_identifier (isass: false, code: MULT_EXPR))
40051 code = MULT_EXPR;
40052 else if (id == ovl_op_identifier (isass: false, code: MINUS_EXPR))
40053 code = MINUS_EXPR;
40054 else if (id == ovl_op_identifier (isass: false, code: BIT_AND_EXPR))
40055 code = BIT_AND_EXPR;
40056 else if (id == ovl_op_identifier (isass: false, code: BIT_IOR_EXPR))
40057 code = BIT_IOR_EXPR;
40058 else if (id == ovl_op_identifier (isass: false, code: BIT_XOR_EXPR))
40059 code = BIT_XOR_EXPR;
40060 else if (id == ovl_op_identifier (isass: false, code: TRUTH_ANDIF_EXPR))
40061 code = TRUTH_ANDIF_EXPR;
40062 else if (id == ovl_op_identifier (isass: false, code: TRUTH_ORIF_EXPR))
40063 code = TRUTH_ORIF_EXPR;
40064 id = omp_reduction_id (code, id, NULL_TREE);
40065 tree scope = parser->scope;
40066 if (scope)
40067 id = build_qualified_name (NULL_TREE, scope, id, false);
40068 parser->scope = NULL_TREE;
40069 parser->qualifying_scope = NULL_TREE;
40070 parser->object_scope = NULL_TREE;
40071 }
40072 else
40073 {
40074 error ("invalid reduction-identifier");
40075 resync_fail:
40076 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40077 /*or_comma=*/false,
40078 /*consume_paren=*/true);
40079 return list;
40080 }
40081 }
40082
40083 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
40084 goto resync_fail;
40085
40086 nlist = cp_parser_omp_var_list_no_open (parser, kind, list,
40087 NULL);
40088 for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
40089 {
40090 OMP_CLAUSE_REDUCTION_CODE (c) = code;
40091 if (task)
40092 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
40093 else if (inscan)
40094 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
40095 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = id;
40096 }
40097
40098 return nlist;
40099}
40100
40101/* OpenMP 2.5:
40102 schedule ( schedule-kind )
40103 schedule ( schedule-kind , expression )
40104
40105 schedule-kind:
40106 static | dynamic | guided | runtime | auto
40107
40108 OpenMP 4.5:
40109 schedule ( schedule-modifier : schedule-kind )
40110 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
40111
40112 schedule-modifier:
40113 simd
40114 monotonic
40115 nonmonotonic */
40116
40117static tree
40118cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
40119{
40120 tree c, t;
40121 int modifiers = 0, nmodifiers = 0;
40122
40123 matching_parens parens;
40124 if (!parens.require_open (parser))
40125 return list;
40126
40127 c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);
40128
40129 location_t comma = UNKNOWN_LOCATION;
40130 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
40131 {
40132 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40133 const char *p = IDENTIFIER_POINTER (id);
40134 if (strcmp (s1: "simd", s2: p) == 0)
40135 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
40136 else if (strcmp (s1: "monotonic", s2: p) == 0)
40137 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
40138 else if (strcmp (s1: "nonmonotonic", s2: p) == 0)
40139 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
40140 else
40141 break;
40142 comma = UNKNOWN_LOCATION;
40143 cp_lexer_consume_token (lexer: parser->lexer);
40144 if (nmodifiers++ == 0
40145 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
40146 {
40147 comma = cp_lexer_peek_token (lexer: parser->lexer)->location;
40148 cp_lexer_consume_token (lexer: parser->lexer);
40149 }
40150 else
40151 {
40152 cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON);
40153 break;
40154 }
40155 }
40156 if (comma != UNKNOWN_LOCATION)
40157 error_at (comma, "expected %<:%>");
40158
40159 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
40160 {
40161 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40162 const char *p = IDENTIFIER_POINTER (id);
40163
40164 switch (p[0])
40165 {
40166 case 'd':
40167 if (strcmp (s1: "dynamic", s2: p) != 0)
40168 goto invalid_kind;
40169 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
40170 break;
40171
40172 case 'g':
40173 if (strcmp (s1: "guided", s2: p) != 0)
40174 goto invalid_kind;
40175 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
40176 break;
40177
40178 case 'r':
40179 if (strcmp (s1: "runtime", s2: p) != 0)
40180 goto invalid_kind;
40181 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
40182 break;
40183
40184 default:
40185 goto invalid_kind;
40186 }
40187 }
40188 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_STATIC))
40189 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
40190 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_AUTO))
40191 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
40192 else
40193 goto invalid_kind;
40194 cp_lexer_consume_token (lexer: parser->lexer);
40195
40196 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
40197 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
40198 == (OMP_CLAUSE_SCHEDULE_MONOTONIC
40199 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
40200 {
40201 error_at (location, "both %<monotonic%> and %<nonmonotonic%> modifiers "
40202 "specified");
40203 modifiers = 0;
40204 }
40205
40206 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
40207 {
40208 cp_token *token;
40209 cp_lexer_consume_token (lexer: parser->lexer);
40210
40211 token = cp_lexer_peek_token (lexer: parser->lexer);
40212 t = cp_parser_assignment_expression (parser);
40213
40214 if (t == error_mark_node)
40215 goto resync_fail;
40216 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
40217 error_at (token->location, "schedule %<runtime%> does not take "
40218 "a %<chunk_size%> parameter");
40219 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
40220 error_at (token->location, "schedule %<auto%> does not take "
40221 "a %<chunk_size%> parameter");
40222 else
40223 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
40224
40225 if (!parens.require_close (parser))
40226 goto resync_fail;
40227 }
40228 else if (!cp_parser_require (parser, type: CPP_CLOSE_PAREN, token_desc: RT_COMMA_CLOSE_PAREN))
40229 goto resync_fail;
40230
40231 OMP_CLAUSE_SCHEDULE_KIND (c)
40232 = (enum omp_clause_schedule_kind)
40233 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
40234
40235 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_SCHEDULE, name: "schedule", location);
40236 OMP_CLAUSE_CHAIN (c) = list;
40237 return c;
40238
40239 invalid_kind:
40240 cp_parser_error (parser, gmsgid: "invalid schedule kind");
40241 resync_fail:
40242 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40243 /*or_comma=*/false,
40244 /*consume_paren=*/true);
40245 return list;
40246}
40247
40248/* OpenMP 3.0:
40249 untied */
40250
40251static tree
40252cp_parser_omp_clause_untied (cp_parser * /*parser*/,
40253 tree list, location_t location)
40254{
40255 tree c;
40256
40257 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_UNTIED, name: "untied", location);
40258
40259 c = build_omp_clause (location, OMP_CLAUSE_UNTIED);
40260 OMP_CLAUSE_CHAIN (c) = list;
40261 return c;
40262}
40263
40264/* OpenMP 4.0:
40265 inbranch
40266 notinbranch */
40267
40268static tree
40269cp_parser_omp_clause_branch (cp_parser * /*parser*/, enum omp_clause_code code,
40270 tree list, location_t location)
40271{
40272 check_no_duplicate_clause (clauses: list, code, name: omp_clause_code_name[code], location);
40273 tree c = build_omp_clause (location, code);
40274 OMP_CLAUSE_CHAIN (c) = list;
40275 return c;
40276}
40277
40278/* OpenMP 4.0:
40279 parallel
40280 for
40281 sections
40282 taskgroup */
40283
40284static tree
40285cp_parser_omp_clause_cancelkind (cp_parser * /*parser*/,
40286 enum omp_clause_code code,
40287 tree list, location_t location)
40288{
40289 tree c = build_omp_clause (location, code);
40290 OMP_CLAUSE_CHAIN (c) = list;
40291 return c;
40292}
40293
40294/* OpenMP 4.5:
40295 nogroup */
40296
40297static tree
40298cp_parser_omp_clause_nogroup (cp_parser * /*parser*/,
40299 tree list, location_t location)
40300{
40301 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_NOGROUP, name: "nogroup", location);
40302 tree c = build_omp_clause (location, OMP_CLAUSE_NOGROUP);
40303 OMP_CLAUSE_CHAIN (c) = list;
40304 return c;
40305}
40306
40307/* OpenMP 4.5:
40308 simd
40309 threads */
40310
40311static tree
40312cp_parser_omp_clause_orderedkind (cp_parser * /*parser*/,
40313 enum omp_clause_code code,
40314 tree list, location_t location)
40315{
40316 check_no_duplicate_clause (clauses: list, code, name: omp_clause_code_name[code], location);
40317 tree c = build_omp_clause (location, code);
40318 OMP_CLAUSE_CHAIN (c) = list;
40319 return c;
40320}
40321
40322/* OpenMP 4.0:
40323 num_teams ( expression )
40324
40325 OpenMP 5.1:
40326 num_teams ( expression : expression ) */
40327
40328static tree
40329cp_parser_omp_clause_num_teams (cp_parser *parser, tree list,
40330 location_t location)
40331{
40332 tree upper, lower = NULL_TREE, c;
40333
40334 matching_parens parens;
40335 if (!parens.require_open (parser))
40336 return list;
40337
40338 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
40339 parser->colon_corrects_to_scope_p = false;
40340 upper = cp_parser_assignment_expression (parser);
40341 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
40342
40343 if (upper != error_mark_node
40344 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
40345 {
40346 lower = upper;
40347 cp_lexer_consume_token (lexer: parser->lexer);
40348 upper = cp_parser_assignment_expression (parser);
40349 }
40350
40351 if (upper == error_mark_node
40352 || !parens.require_close (parser))
40353 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40354 /*or_comma=*/false,
40355 /*consume_paren=*/true);
40356
40357 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_NUM_TEAMS,
40358 name: "num_teams", location);
40359
40360 c = build_omp_clause (location, OMP_CLAUSE_NUM_TEAMS);
40361 OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
40362 OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
40363 OMP_CLAUSE_CHAIN (c) = list;
40364
40365 return c;
40366}
40367
40368/* OpenMP 4.0:
40369 thread_limit ( expression ) */
40370
40371static tree
40372cp_parser_omp_clause_thread_limit (cp_parser *parser, tree list,
40373 location_t location)
40374{
40375 tree t, c;
40376
40377 matching_parens parens;
40378 if (!parens.require_open (parser))
40379 return list;
40380
40381 t = cp_parser_assignment_expression (parser);
40382
40383 if (t == error_mark_node
40384 || !parens.require_close (parser))
40385 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40386 /*or_comma=*/false,
40387 /*consume_paren=*/true);
40388
40389 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_THREAD_LIMIT,
40390 name: "thread_limit", location);
40391
40392 c = build_omp_clause (location, OMP_CLAUSE_THREAD_LIMIT);
40393 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
40394 OMP_CLAUSE_CHAIN (c) = list;
40395
40396 return c;
40397}
40398
40399/* OpenMP 4.0:
40400 aligned ( variable-list )
40401 aligned ( variable-list : constant-expression ) */
40402
40403static tree
40404cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
40405{
40406 tree nlist, c, alignment = NULL_TREE;
40407 bool colon;
40408
40409 matching_parens parens;
40410 if (!parens.require_open (parser))
40411 return list;
40412
40413 nlist = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_ALIGNED, list,
40414 colon: &colon);
40415
40416 if (colon)
40417 {
40418 alignment = cp_parser_constant_expression (parser);
40419
40420 if (!parens.require_close (parser))
40421 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40422 /*or_comma=*/false,
40423 /*consume_paren=*/true);
40424
40425 if (alignment == error_mark_node)
40426 alignment = NULL_TREE;
40427 }
40428
40429 for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
40430 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
40431
40432 return nlist;
40433}
40434
40435/* OpenMP 5.0:
40436 allocate ( variable-list )
40437 allocate ( expression : variable-list )
40438
40439 OpenMP 5.1:
40440 allocate ( allocator-modifier : variable-list )
40441 allocate ( allocator-modifier , allocator-modifier : variable-list )
40442
40443 allocator-modifier:
40444 allocator ( expression )
40445 align ( expression ) */
40446
40447static tree
40448cp_parser_omp_clause_allocate (cp_parser *parser, tree list)
40449{
40450 tree nlist, c, allocator = NULL_TREE, align = NULL_TREE;
40451 bool colon, has_modifiers = false;
40452
40453 matching_parens parens;
40454 if (!parens.require_open (parser))
40455 return list;
40456
40457 cp_parser_parse_tentatively (parser);
40458 bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
40459 parser->colon_corrects_to_scope_p = false;
40460 for (int mod = 0; mod < 2; mod++)
40461 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
40462 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_PAREN))
40463 {
40464 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40465 const char *p = IDENTIFIER_POINTER (id);
40466 if (strcmp (s1: p, s2: "allocator") != 0 && strcmp (s1: p, s2: "align") != 0)
40467 break;
40468 cp_lexer_consume_token (lexer: parser->lexer);
40469 matching_parens parens2;
40470 if (!parens2.require_open (parser))
40471 break;
40472 if (strcmp (s1: p, s2: "allocator") == 0)
40473 {
40474 if (allocator != NULL_TREE)
40475 break;
40476 allocator = cp_parser_assignment_expression (parser);
40477 }
40478 else
40479 {
40480 if (align != NULL_TREE)
40481 break;
40482 align = cp_parser_assignment_expression (parser);
40483 }
40484 if (!parens2.require_close (parser))
40485 break;
40486 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
40487 {
40488 has_modifiers = true;
40489 break;
40490 }
40491 if (mod != 0 || cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA))
40492 break;
40493 cp_lexer_consume_token (lexer: parser->lexer);
40494 }
40495 else
40496 break;
40497 if (!has_modifiers)
40498 {
40499 cp_parser_abort_tentative_parse (parser);
40500 align = NULL_TREE;
40501 allocator = NULL_TREE;
40502 cp_parser_parse_tentatively (parser);
40503 allocator = cp_parser_assignment_expression (parser);
40504 }
40505 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
40506 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
40507 {
40508 cp_parser_parse_definitely (parser);
40509 cp_lexer_consume_token (lexer: parser->lexer);
40510 if (allocator == error_mark_node)
40511 allocator = NULL_TREE;
40512 if (align == error_mark_node)
40513 align = NULL_TREE;
40514 }
40515 else
40516 {
40517 cp_parser_abort_tentative_parse (parser);
40518 allocator = NULL_TREE;
40519 align = NULL_TREE;
40520 }
40521
40522 nlist = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_ALLOCATE, list,
40523 colon: &colon);
40524
40525 if (allocator || align)
40526 for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
40527 {
40528 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
40529 OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
40530 }
40531
40532 return nlist;
40533}
40534
40535/* OpenMP 2.5:
40536 lastprivate ( variable-list )
40537
40538 OpenMP 5.0:
40539 lastprivate ( [ lastprivate-modifier : ] variable-list ) */
40540
40541static tree
40542cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list)
40543{
40544 bool conditional = false;
40545
40546 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
40547 return list;
40548
40549 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
40550 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COLON))
40551 {
40552 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40553 const char *p = IDENTIFIER_POINTER (id);
40554
40555 if (strcmp (s1: "conditional", s2: p) == 0)
40556 {
40557 conditional = true;
40558 cp_lexer_consume_token (lexer: parser->lexer);
40559 cp_lexer_consume_token (lexer: parser->lexer);
40560 }
40561 }
40562
40563 tree nlist = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_LASTPRIVATE,
40564 list, NULL);
40565
40566 if (conditional)
40567 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
40568 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
40569 return nlist;
40570}
40571
40572/* OpenMP 4.0:
40573 linear ( variable-list )
40574 linear ( variable-list : expression )
40575
40576 OpenMP 4.5:
40577 linear ( modifier ( variable-list ) )
40578 linear ( modifier ( variable-list ) : expression )
40579
40580 modifier:
40581 val
40582 ref
40583 uval
40584
40585 OpenMP 5.2:
40586 linear ( variable-list : modifiers-list )
40587
40588 modifiers:
40589 val
40590 ref
40591 uval
40592 step ( expression ) */
40593
40594static tree
40595cp_parser_omp_clause_linear (cp_parser *parser, tree list,
40596 bool declare_simd)
40597{
40598 tree nlist, c, step = integer_one_node;
40599 bool colon;
40600 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
40601 bool old_linear_modifier = false;
40602
40603 matching_parens parens;
40604 if (!parens.require_open (parser))
40605 return list;
40606
40607 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
40608 {
40609 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40610 const char *p = IDENTIFIER_POINTER (id);
40611
40612 if (strcmp (s1: "ref", s2: p) == 0)
40613 kind = OMP_CLAUSE_LINEAR_REF;
40614 else if (strcmp (s1: "val", s2: p) == 0)
40615 kind = OMP_CLAUSE_LINEAR_VAL;
40616 else if (strcmp (s1: "uval", s2: p) == 0)
40617 kind = OMP_CLAUSE_LINEAR_UVAL;
40618 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_PAREN))
40619 {
40620 cp_lexer_consume_token (lexer: parser->lexer);
40621 old_linear_modifier = true;
40622 }
40623 else
40624 kind = OMP_CLAUSE_LINEAR_DEFAULT;
40625 }
40626
40627 if (kind == OMP_CLAUSE_LINEAR_DEFAULT)
40628 nlist = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_LINEAR, list,
40629 colon: &colon);
40630 else
40631 {
40632 nlist = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_LINEAR, list);
40633 colon = cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON);
40634 if (colon)
40635 cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON);
40636 else if (!parens.require_close (parser))
40637 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40638 /*or_comma=*/false,
40639 /*consume_paren=*/true);
40640 }
40641
40642 if (colon)
40643 {
40644 bool has_modifiers = false;
40645 if (kind == OMP_CLAUSE_LINEAR_DEFAULT
40646 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
40647 {
40648 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40649 const char *p = IDENTIFIER_POINTER (id);
40650 size_t pos = 0;
40651 if (strcmp (s1: "ref", s2: p) == 0
40652 || strcmp (s1: "val", s2: p) == 0
40653 || strcmp (s1: "uval", s2: p) == 0)
40654 pos = 2;
40655 else if (strcmp (s1: "step", s2: p) == 0
40656 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_PAREN))
40657 {
40658 pos = cp_parser_skip_balanced_tokens (parser, n: 2);
40659 if (pos == 2)
40660 pos = 0;
40661 }
40662 if (pos != 0
40663 && (cp_lexer_nth_token_is (lexer: parser->lexer, n: pos, type: CPP_COMMA)
40664 || cp_lexer_nth_token_is (lexer: parser->lexer, n: pos,
40665 type: CPP_CLOSE_PAREN)))
40666 has_modifiers = true;
40667 }
40668
40669 step = NULL_TREE;
40670 if (has_modifiers)
40671 {
40672 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
40673 {
40674 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40675 const char *p = IDENTIFIER_POINTER (id);
40676 enum omp_clause_linear_kind nkind = OMP_CLAUSE_LINEAR_DEFAULT;
40677 if (strcmp (s1: "ref", s2: p) == 0)
40678 nkind = OMP_CLAUSE_LINEAR_REF;
40679 else if (strcmp (s1: "val", s2: p) == 0)
40680 nkind = OMP_CLAUSE_LINEAR_VAL;
40681 else if (strcmp (s1: "uval", s2: p) == 0)
40682 nkind = OMP_CLAUSE_LINEAR_UVAL;
40683 if (nkind != OMP_CLAUSE_LINEAR_DEFAULT)
40684 {
40685 if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
40686 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
40687 "multiple linear modifiers");
40688 kind = nkind;
40689 cp_lexer_consume_token (lexer: parser->lexer);
40690 }
40691 else if (strcmp (s1: "step", s2: p) == 0)
40692 {
40693 location_t step_loc
40694 = cp_lexer_peek_token (lexer: parser->lexer)->location;
40695 cp_lexer_consume_token (lexer: parser->lexer);
40696 matching_parens parens2;
40697 if (parens2.require_open (parser))
40698 {
40699 if (step)
40700 error_at (step_loc, "multiple %<step%> modifiers");
40701 if (declare_simd
40702 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
40703 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2,
40704 type: CPP_CLOSE_PAREN))
40705 {
40706 cp_token *token
40707 = cp_lexer_peek_token (lexer: parser->lexer);
40708 location_t tok_loc = token->location;
40709 cp_parser_parse_tentatively (parser);
40710 step = cp_parser_id_expression (parser, template_keyword_p: false, check_dependency_p: true,
40711 NULL, declarator_p: false, optional_p: false);
40712 if (step != error_mark_node)
40713 step = cp_parser_lookup_name_simple (parser, name: step,
40714 location: tok_loc);
40715 if (step == error_mark_node)
40716 {
40717 step = NULL_TREE;
40718 cp_parser_abort_tentative_parse (parser);
40719 }
40720 else if (!cp_parser_parse_definitely (parser))
40721 step = NULL_TREE;
40722 }
40723 if (!step)
40724 step = cp_parser_assignment_expression (parser);
40725 if (!parens2.require_close (parser))
40726 cp_parser_skip_to_closing_parenthesis (parser, recovering: true,
40727 or_comma: false, consume_paren: true);
40728 }
40729 else
40730 break;
40731 }
40732 else
40733 break;
40734 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
40735 {
40736 cp_lexer_consume_token (lexer: parser->lexer);
40737 continue;
40738 }
40739 break;
40740 }
40741 if (!step)
40742 step = integer_one_node;
40743 }
40744 else if (declare_simd
40745 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
40746 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_CLOSE_PAREN))
40747 {
40748 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
40749 cp_parser_parse_tentatively (parser);
40750 step = cp_parser_id_expression (parser, /*template_p=*/template_keyword_p: false,
40751 /*check_dependency_p=*/true,
40752 /*template_p=*/NULL,
40753 /*declarator_p=*/false,
40754 /*optional_p=*/false);
40755 if (step != error_mark_node)
40756 step = cp_parser_lookup_name_simple (parser, name: step, location: token->location);
40757 if (step == error_mark_node)
40758 {
40759 step = NULL_TREE;
40760 cp_parser_abort_tentative_parse (parser);
40761 }
40762 else if (!cp_parser_parse_definitely (parser))
40763 step = NULL_TREE;
40764 }
40765 if (!step)
40766 step = cp_parser_assignment_expression (parser);
40767
40768 if (!parens.require_close (parser))
40769 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40770 /*or_comma=*/false,
40771 /*consume_paren=*/true);
40772
40773 if (step == error_mark_node)
40774 return list;
40775 }
40776
40777 for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
40778 {
40779 OMP_CLAUSE_LINEAR_STEP (c) = step;
40780 OMP_CLAUSE_LINEAR_KIND (c) = kind;
40781 OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
40782 }
40783
40784 return nlist;
40785}
40786
40787/* OpenMP 4.0:
40788 safelen ( constant-expression ) */
40789
40790static tree
40791cp_parser_omp_clause_safelen (cp_parser *parser, tree list,
40792 location_t location)
40793{
40794 tree t, c;
40795
40796 matching_parens parens;
40797 if (!parens.require_open (parser))
40798 return list;
40799
40800 t = cp_parser_constant_expression (parser);
40801
40802 if (t == error_mark_node
40803 || !parens.require_close (parser))
40804 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40805 /*or_comma=*/false,
40806 /*consume_paren=*/true);
40807
40808 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_SAFELEN, name: "safelen", location);
40809
40810 c = build_omp_clause (location, OMP_CLAUSE_SAFELEN);
40811 OMP_CLAUSE_SAFELEN_EXPR (c) = t;
40812 OMP_CLAUSE_CHAIN (c) = list;
40813
40814 return c;
40815}
40816
40817/* OpenMP 4.0:
40818 simdlen ( constant-expression ) */
40819
40820static tree
40821cp_parser_omp_clause_simdlen (cp_parser *parser, tree list,
40822 location_t location)
40823{
40824 tree t, c;
40825
40826 matching_parens parens;
40827 if (!parens.require_open (parser))
40828 return list;
40829
40830 t = cp_parser_constant_expression (parser);
40831
40832 if (t == error_mark_node
40833 || !parens.require_close (parser))
40834 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40835 /*or_comma=*/false,
40836 /*consume_paren=*/true);
40837
40838 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_SIMDLEN, name: "simdlen", location);
40839
40840 c = build_omp_clause (location, OMP_CLAUSE_SIMDLEN);
40841 OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
40842 OMP_CLAUSE_CHAIN (c) = list;
40843
40844 return c;
40845}
40846
40847/* OpenMP 4.5:
40848 vec:
40849 identifier [+/- integer]
40850 vec , identifier [+/- integer]
40851*/
40852
40853static tree
40854cp_parser_omp_clause_doacross_sink (cp_parser *parser, location_t clause_loc,
40855 tree list, bool depend_p)
40856{
40857 tree vec = NULL;
40858
40859 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NAME))
40860 {
40861 cp_parser_error (parser, gmsgid: "expected identifier");
40862 return list;
40863 }
40864
40865 if (!depend_p)
40866 {
40867 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40868 if (strcmp (IDENTIFIER_POINTER (id), s2: "omp_cur_iteration") == 0
40869 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_MINUS)
40870 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 3, type: CPP_NUMBER)
40871 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 4, type: CPP_CLOSE_PAREN))
40872 {
40873 tree val = cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->u.value;
40874 if (integer_onep (val))
40875 {
40876 cp_lexer_consume_token (lexer: parser->lexer);
40877 cp_lexer_consume_token (lexer: parser->lexer);
40878 cp_lexer_consume_token (lexer: parser->lexer);
40879 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
40880 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
40881 OMP_CLAUSE_CHAIN (u) = list;
40882 return u;
40883 }
40884 }
40885 }
40886
40887 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
40888 {
40889 location_t id_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
40890 tree t, identifier = cp_parser_identifier (parser);
40891 tree addend = NULL;
40892
40893 if (identifier == error_mark_node)
40894 t = error_mark_node;
40895 else
40896 {
40897 t = cp_parser_lookup_name_simple
40898 (parser, name: identifier,
40899 location: cp_lexer_peek_token (lexer: parser->lexer)->location);
40900 if (t == error_mark_node)
40901 cp_parser_name_lookup_error (parser, name: identifier, decl: t, desired: NLE_NULL,
40902 location: id_loc);
40903 }
40904
40905 bool neg = false;
40906 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_MINUS))
40907 neg = true;
40908 else if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_PLUS))
40909 {
40910 addend = integer_zero_node;
40911 goto add_to_vector;
40912 }
40913 cp_lexer_consume_token (lexer: parser->lexer);
40914
40915 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NUMBER))
40916 {
40917 cp_parser_error (parser, gmsgid: "expected integer");
40918 return list;
40919 }
40920
40921 addend = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
40922 if (TREE_CODE (addend) != INTEGER_CST)
40923 {
40924 cp_parser_error (parser, gmsgid: "expected integer");
40925 return list;
40926 }
40927 cp_lexer_consume_token (lexer: parser->lexer);
40928
40929 add_to_vector:
40930 if (t != error_mark_node)
40931 {
40932 vec = tree_cons (addend, t, vec);
40933 if (neg)
40934 OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
40935 }
40936
40937 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_COMMA)
40938 || !cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
40939 break;
40940
40941 cp_lexer_consume_token (lexer: parser->lexer);
40942 }
40943
40944 if (vec)
40945 {
40946 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
40947 OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
40948 OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
40949 OMP_CLAUSE_DECL (u) = nreverse (vec);
40950 OMP_CLAUSE_CHAIN (u) = list;
40951 return u;
40952 }
40953 return list;
40954}
40955
40956/* OpenMP 5.0:
40957 detach ( event-handle ) */
40958
40959static tree
40960cp_parser_omp_clause_detach (cp_parser *parser, tree list)
40961{
40962 matching_parens parens;
40963
40964 if (!parens.require_open (parser))
40965 return list;
40966
40967 cp_token *token;
40968 tree name, decl;
40969
40970 token = cp_lexer_peek_token (lexer: parser->lexer);
40971 name = cp_parser_id_expression (parser, /*template_p=*/template_keyword_p: false,
40972 /*check_dependency_p=*/true,
40973 /*template_p=*/NULL,
40974 /*declarator_p=*/false,
40975 /*optional_p=*/false);
40976 if (name == error_mark_node)
40977 decl = error_mark_node;
40978 else
40979 {
40980 if (identifier_p (t: name))
40981 decl = cp_parser_lookup_name_simple (parser, name, location: token->location);
40982 else
40983 decl = name;
40984 if (decl == error_mark_node)
40985 cp_parser_name_lookup_error (parser, name, decl, desired: NLE_NULL,
40986 location: token->location);
40987 }
40988
40989 if (decl == error_mark_node
40990 || !parens.require_close (parser))
40991 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
40992 /*or_comma=*/false,
40993 /*consume_paren=*/true);
40994
40995 tree u = build_omp_clause (token->location, OMP_CLAUSE_DETACH);
40996 OMP_CLAUSE_DECL (u) = decl;
40997 OMP_CLAUSE_CHAIN (u) = list;
40998
40999 return u;
41000}
41001
41002/* OpenMP 5.0:
41003 iterators ( iterators-definition )
41004
41005 iterators-definition:
41006 iterator-specifier
41007 iterator-specifier , iterators-definition
41008
41009 iterator-specifier:
41010 identifier = range-specification
41011 iterator-type identifier = range-specification
41012
41013 range-specification:
41014 begin : end
41015 begin : end : step */
41016
41017static tree
41018cp_parser_omp_iterators (cp_parser *parser)
41019{
41020 tree ret = NULL_TREE, *last = &ret;
41021 cp_lexer_consume_token (lexer: parser->lexer);
41022
41023 matching_parens parens;
41024 if (!parens.require_open (parser))
41025 return error_mark_node;
41026
41027 bool saved_colon_corrects_to_scope_p
41028 = parser->colon_corrects_to_scope_p;
41029 bool saved_colon_doesnt_start_class_def_p
41030 = parser->colon_doesnt_start_class_def_p;
41031
41032 do
41033 {
41034 tree iter_type;
41035 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
41036 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_EQ))
41037 iter_type = integer_type_node;
41038 else
41039 {
41040 const char *saved_message
41041 = parser->type_definition_forbidden_message;
41042 parser->type_definition_forbidden_message
41043 = G_("types may not be defined in iterator type");
41044
41045 iter_type = cp_parser_type_id (parser);
41046
41047 parser->type_definition_forbidden_message = saved_message;
41048 }
41049
41050 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
41051 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NAME))
41052 {
41053 cp_parser_error (parser, gmsgid: "expected identifier");
41054 break;
41055 }
41056
41057 tree id = cp_parser_identifier (parser);
41058 if (id == error_mark_node)
41059 break;
41060
41061 if (!cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ))
41062 break;
41063
41064 parser->colon_corrects_to_scope_p = false;
41065 parser->colon_doesnt_start_class_def_p = true;
41066 tree begin = cp_parser_assignment_expression (parser);
41067
41068 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
41069 break;
41070
41071 tree end = cp_parser_assignment_expression (parser);
41072
41073 tree step = integer_one_node;
41074 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
41075 {
41076 cp_lexer_consume_token (lexer: parser->lexer);
41077 step = cp_parser_assignment_expression (parser);
41078 }
41079
41080 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
41081 DECL_ARTIFICIAL (iter_var) = 1;
41082 DECL_CONTEXT (iter_var) = current_function_decl;
41083 pushdecl (iter_var);
41084
41085 *last = make_tree_vec (6);
41086 TREE_VEC_ELT (*last, 0) = iter_var;
41087 TREE_VEC_ELT (*last, 1) = begin;
41088 TREE_VEC_ELT (*last, 2) = end;
41089 TREE_VEC_ELT (*last, 3) = step;
41090 last = &TREE_CHAIN (*last);
41091
41092 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
41093 {
41094 cp_lexer_consume_token (lexer: parser->lexer);
41095 continue;
41096 }
41097 break;
41098 }
41099 while (1);
41100
41101 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
41102 parser->colon_doesnt_start_class_def_p
41103 = saved_colon_doesnt_start_class_def_p;
41104
41105 if (!parens.require_close (parser))
41106 cp_parser_skip_to_closing_parenthesis (parser,
41107 /*recovering=*/true,
41108 /*or_comma=*/false,
41109 /*consume_paren=*/true);
41110
41111 return ret ? ret : error_mark_node;
41112}
41113
41114/* OpenMP 5.0:
41115 affinity ( [aff-modifier :] variable-list )
41116 aff-modifier:
41117 iterator ( iterators-definition ) */
41118
41119static tree
41120cp_parser_omp_clause_affinity (cp_parser *parser, tree list)
41121{
41122 tree nlist, c, iterators = NULL_TREE;
41123
41124 matching_parens parens;
41125 if (!parens.require_open (parser))
41126 return list;
41127
41128 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
41129 {
41130 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
41131 const char *p = IDENTIFIER_POINTER (id);
41132 bool parse_iter = ((strcmp (s1: "iterator", s2: p) == 0)
41133 && (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2,
41134 type: CPP_OPEN_PAREN)));
41135 if (parse_iter)
41136 {
41137 size_t n = cp_parser_skip_balanced_tokens (parser, n: 2);
41138 parse_iter = cp_lexer_nth_token_is (lexer: parser->lexer, n, type: CPP_COLON);
41139 }
41140 if (parse_iter)
41141 {
41142 begin_scope (sk_omp, NULL);
41143 iterators = cp_parser_omp_iterators (parser);
41144 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
41145 {
41146 if (iterators)
41147 poplevel (0, 1, 0);
41148 cp_parser_skip_to_closing_parenthesis (parser,
41149 /*recovering=*/true,
41150 /*or_comma=*/false,
41151 /*consume_paren=*/true);
41152 return list;
41153 }
41154 }
41155 }
41156 nlist = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_AFFINITY,
41157 list, NULL);
41158 if (iterators)
41159 {
41160 tree block = poplevel (1, 1, 0);
41161 if (iterators != error_mark_node)
41162 {
41163 TREE_VEC_ELT (iterators, 5) = block;
41164 for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
41165 OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
41166 OMP_CLAUSE_DECL (c));
41167 }
41168 }
41169 return nlist;
41170}
41171
41172/* OpenMP 4.0:
41173 depend ( depend-kind : variable-list )
41174
41175 depend-kind:
41176 in | out | inout
41177
41178 OpenMP 4.5:
41179 depend ( source )
41180
41181 depend ( sink : vec )
41182
41183 OpenMP 5.0:
41184 depend ( depend-modifier , depend-kind: variable-list )
41185
41186 depend-kind:
41187 in | out | inout | mutexinoutset | depobj
41188
41189 depend-modifier:
41190 iterator ( iterators-definition ) */
41191
41192static tree
41193cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
41194{
41195 tree nlist, c, iterators = NULL_TREE;
41196 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
41197 enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
41198
41199 matching_parens parens;
41200 if (!parens.require_open (parser))
41201 return list;
41202
41203 do
41204 {
41205 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NAME))
41206 goto invalid_kind;
41207
41208 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
41209 const char *p = IDENTIFIER_POINTER (id);
41210
41211 if (strcmp (s1: "iterator", s2: p) == 0 && iterators == NULL_TREE)
41212 {
41213 begin_scope (sk_omp, NULL);
41214 iterators = cp_parser_omp_iterators (parser);
41215 cp_parser_require (parser, type: CPP_COMMA, token_desc: RT_COMMA);
41216 continue;
41217 }
41218 if (strcmp (s1: "in", s2: p) == 0)
41219 kind = OMP_CLAUSE_DEPEND_IN;
41220 else if (strcmp (s1: "inout", s2: p) == 0)
41221 kind = OMP_CLAUSE_DEPEND_INOUT;
41222 else if (strcmp (s1: "inoutset", s2: p) == 0)
41223 kind = OMP_CLAUSE_DEPEND_INOUTSET;
41224 else if (strcmp (s1: "mutexinoutset", s2: p) == 0)
41225 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
41226 else if (strcmp (s1: "out", s2: p) == 0)
41227 kind = OMP_CLAUSE_DEPEND_OUT;
41228 else if (strcmp (s1: "depobj", s2: p) == 0)
41229 kind = OMP_CLAUSE_DEPEND_DEPOBJ;
41230 else if (strcmp (s1: "sink", s2: p) == 0)
41231 dkind = OMP_CLAUSE_DOACROSS_SINK;
41232 else if (strcmp (s1: "source", s2: p) == 0)
41233 dkind = OMP_CLAUSE_DOACROSS_SOURCE;
41234 else
41235 goto invalid_kind;
41236 break;
41237 }
41238 while (1);
41239
41240 cp_lexer_consume_token (lexer: parser->lexer);
41241
41242 if (iterators
41243 && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
41244 || dkind == OMP_CLAUSE_DOACROSS_SINK))
41245 {
41246 poplevel (0, 1, 0);
41247 error_at (loc, "%<iterator%> modifier incompatible with %qs",
41248 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
41249 iterators = NULL_TREE;
41250 }
41251
41252 if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
41253 {
41254 c = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
41255 OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
41256 OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
41257 OMP_CLAUSE_DECL (c) = NULL_TREE;
41258 OMP_CLAUSE_CHAIN (c) = list;
41259 if (!parens.require_close (parser))
41260 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41261 /*or_comma=*/false,
41262 /*consume_paren=*/true);
41263 return c;
41264 }
41265
41266 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
41267 goto resync_fail;
41268
41269 if (dkind == OMP_CLAUSE_DOACROSS_SINK)
41270 {
41271 nlist = cp_parser_omp_clause_doacross_sink (parser, clause_loc: loc, list, depend_p: true);
41272 if (!parens.require_close (parser))
41273 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41274 /*or_comma=*/false,
41275 /*consume_paren=*/true);
41276 }
41277 else
41278 {
41279 nlist = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_DEPEND,
41280 list, NULL);
41281
41282 if (iterators)
41283 {
41284 tree block = poplevel (1, 1, 0);
41285 if (iterators == error_mark_node)
41286 iterators = NULL_TREE;
41287 else
41288 TREE_VEC_ELT (iterators, 5) = block;
41289 }
41290
41291 for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
41292 {
41293 OMP_CLAUSE_DEPEND_KIND (c) = kind;
41294 if (iterators)
41295 OMP_CLAUSE_DECL (c)
41296 = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
41297 }
41298 }
41299 return nlist;
41300
41301 invalid_kind:
41302 cp_parser_error (parser, gmsgid: "invalid depend kind");
41303 resync_fail:
41304 if (iterators)
41305 poplevel (0, 1, 0);
41306 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41307 /*or_comma=*/false,
41308 /*consume_paren=*/true);
41309 return list;
41310}
41311
41312/* OpenMP 5.2:
41313 doacross ( source : )
41314 doacross ( source : omp_cur_iteration )
41315
41316 doacross ( sink : vec )
41317 doacross ( sink : omp_cur_iteration - logical_iteration ) */
41318
41319static tree
41320cp_parser_omp_clause_doacross (cp_parser *parser, tree list, location_t loc)
41321{
41322 tree nlist;
41323 enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
41324
41325 matching_parens parens;
41326 if (!parens.require_open (parser))
41327 return list;
41328
41329 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NAME))
41330 {
41331 invalid_kind:
41332 cp_parser_error (parser, gmsgid: "invalid doacross kind");
41333 resync_fail:
41334 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41335 /*or_comma=*/false,
41336 /*consume_paren=*/true);
41337 return list;
41338 }
41339
41340 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
41341 const char *p = IDENTIFIER_POINTER (id);
41342
41343 if (strcmp (s1: "sink", s2: p) == 0)
41344 kind = OMP_CLAUSE_DOACROSS_SINK;
41345 else if (strcmp (s1: "source", s2: p) == 0)
41346 kind = OMP_CLAUSE_DOACROSS_SOURCE;
41347 else
41348 goto invalid_kind;
41349
41350 cp_lexer_consume_token (lexer: parser->lexer);
41351
41352 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
41353 goto resync_fail;
41354
41355 if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
41356 {
41357 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
41358 {
41359 id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
41360 p = IDENTIFIER_POINTER (id);
41361 if (strcmp (s1: p, s2: "omp_cur_iteration") == 0)
41362 cp_lexer_consume_token (lexer: parser->lexer);
41363 }
41364 nlist = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
41365 OMP_CLAUSE_DOACROSS_KIND (nlist) = OMP_CLAUSE_DOACROSS_SOURCE;
41366 OMP_CLAUSE_DECL (nlist) = NULL_TREE;
41367 OMP_CLAUSE_CHAIN (nlist) = list;
41368 }
41369 else
41370 nlist = cp_parser_omp_clause_doacross_sink (parser, clause_loc: loc, list, depend_p: false);
41371
41372 if (!parens.require_close (parser))
41373 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41374 /*or_comma=*/false,
41375 /*consume_paren=*/true);
41376 return nlist;
41377}
41378
41379/* OpenMP 4.0:
41380 from ( variable-list )
41381 to ( variable-list )
41382
41383 OpenMP 5.1:
41384 from ( [present :] variable-list )
41385 to ( [present :] variable-list ) */
41386
41387static tree
41388cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
41389 tree list)
41390{
41391 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
41392 return list;
41393
41394 bool present = false;
41395 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
41396
41397 if (token->type == CPP_NAME
41398 && strcmp (IDENTIFIER_POINTER (token->u.value), s2: "present") == 0
41399 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COLON))
41400 {
41401 present = true;
41402 cp_lexer_consume_token (lexer: parser->lexer);
41403 cp_lexer_consume_token (lexer: parser->lexer);
41404 }
41405
41406 tree nl = cp_parser_omp_var_list_no_open (parser, kind, list, NULL, map_lvalue: true);
41407 if (present)
41408 for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
41409 OMP_CLAUSE_MOTION_PRESENT (c) = 1;
41410
41411 return nl;
41412}
41413
41414/* OpenMP 4.0:
41415 map ( map-kind : variable-list )
41416 map ( variable-list )
41417
41418 map-kind:
41419 alloc | to | from | tofrom
41420
41421 OpenMP 4.5:
41422 map-kind:
41423 alloc | to | from | tofrom | release | delete
41424
41425 map ( always [,] map-kind: variable-list )
41426
41427 OpenMP 5.0:
41428 map ( [map-type-modifier[,] ...] map-kind: variable-list )
41429
41430 map-type-modifier:
41431 always | close */
41432
41433static tree
41434cp_parser_omp_clause_map (cp_parser *parser, tree list)
41435{
41436 tree nlist, c;
41437 enum gomp_map_kind kind = GOMP_MAP_TOFROM;
41438
41439 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
41440 return list;
41441
41442 int pos = 1;
41443 int map_kind_pos = 0;
41444 while (cp_lexer_peek_nth_token (lexer: parser->lexer, n: pos)->type == CPP_NAME
41445 || cp_lexer_peek_nth_token (lexer: parser->lexer, n: pos)->keyword == RID_DELETE)
41446 {
41447 if (cp_lexer_peek_nth_token (lexer: parser->lexer, n: pos + 1)->type == CPP_COLON)
41448 {
41449 map_kind_pos = pos;
41450 break;
41451 }
41452
41453 if (cp_lexer_peek_nth_token (lexer: parser->lexer, n: pos + 1)->type == CPP_COMMA)
41454 pos++;
41455 pos++;
41456 }
41457
41458 bool always_modifier = false;
41459 bool close_modifier = false;
41460 bool present_modifier = false;
41461 for (int pos = 1; pos < map_kind_pos; ++pos)
41462 {
41463 cp_token *tok = cp_lexer_peek_token (lexer: parser->lexer);
41464 if (tok->type == CPP_COMMA)
41465 {
41466 cp_lexer_consume_token (lexer: parser->lexer);
41467 continue;
41468 }
41469
41470 const char *p = IDENTIFIER_POINTER (tok->u.value);
41471 if (strcmp (s1: "always", s2: p) == 0)
41472 {
41473 if (always_modifier)
41474 {
41475 cp_parser_error (parser, gmsgid: "too many %<always%> modifiers");
41476 cp_parser_skip_to_closing_parenthesis (parser,
41477 /*recovering=*/true,
41478 /*or_comma=*/false,
41479 /*consume_paren=*/true);
41480 return list;
41481 }
41482 always_modifier = true;
41483 }
41484 else if (strcmp (s1: "close", s2: p) == 0)
41485 {
41486 if (close_modifier)
41487 {
41488 cp_parser_error (parser, gmsgid: "too many %<close%> modifiers");
41489 cp_parser_skip_to_closing_parenthesis (parser,
41490 /*recovering=*/true,
41491 /*or_comma=*/false,
41492 /*consume_paren=*/true);
41493 return list;
41494 }
41495 close_modifier = true;
41496 }
41497 else if (strcmp (s1: "present", s2: p) == 0)
41498 {
41499 if (present_modifier)
41500 {
41501 cp_parser_error (parser, gmsgid: "too many %<present%> modifiers");
41502 cp_parser_skip_to_closing_parenthesis (parser,
41503 /*recovering=*/true,
41504 /*or_comma=*/false,
41505 /*consume_paren=*/true);
41506 return list;
41507 }
41508 present_modifier = true;
41509 }
41510 else
41511 {
41512 cp_parser_error (parser, gmsgid: "%<map%> clause with map-type modifier other"
41513 " than %<always%>, %<close%> or %<present%>");
41514 cp_parser_skip_to_closing_parenthesis (parser,
41515 /*recovering=*/true,
41516 /*or_comma=*/false,
41517 /*consume_paren=*/true);
41518 return list;
41519 }
41520
41521 cp_lexer_consume_token (lexer: parser->lexer);
41522 }
41523
41524 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
41525 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_COLON)
41526 {
41527 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
41528 const char *p = IDENTIFIER_POINTER (id);
41529 int always_present_modifier = always_modifier && present_modifier;
41530
41531 if (strcmp (s1: "alloc", s2: p) == 0)
41532 kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
41533 else if (strcmp (s1: "to", s2: p) == 0)
41534 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
41535 : present_modifier ? GOMP_MAP_PRESENT_TO
41536 : always_modifier ? GOMP_MAP_ALWAYS_TO
41537 : GOMP_MAP_TO);
41538 else if (strcmp (s1: "from", s2: p) == 0)
41539 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
41540 : present_modifier ? GOMP_MAP_PRESENT_FROM
41541 : always_modifier ? GOMP_MAP_ALWAYS_FROM
41542 : GOMP_MAP_FROM);
41543 else if (strcmp (s1: "tofrom", s2: p) == 0)
41544 kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
41545 : present_modifier ? GOMP_MAP_PRESENT_TOFROM
41546 : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
41547 : GOMP_MAP_TOFROM);
41548 else if (strcmp (s1: "release", s2: p) == 0)
41549 kind = GOMP_MAP_RELEASE;
41550 else
41551 {
41552 cp_parser_error (parser, gmsgid: "invalid map kind");
41553 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41554 /*or_comma=*/false,
41555 /*consume_paren=*/true);
41556 return list;
41557 }
41558 cp_lexer_consume_token (lexer: parser->lexer);
41559 cp_lexer_consume_token (lexer: parser->lexer);
41560 }
41561 else if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_DELETE)
41562 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_COLON)
41563 {
41564 kind = GOMP_MAP_DELETE;
41565 cp_lexer_consume_token (lexer: parser->lexer);
41566 cp_lexer_consume_token (lexer: parser->lexer);
41567 }
41568
41569 /* We introduce a scope here so that errors parsing e.g. "always", "close"
41570 tokens do not propagate to later directives that might use them
41571 legally. */
41572 begin_scope (sk_omp, NULL);
41573 nlist = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE_MAP, list,
41574 NULL, map_lvalue: true);
41575 finish_scope ();
41576
41577 for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
41578 OMP_CLAUSE_SET_MAP_KIND (c, kind);
41579
41580 return nlist;
41581}
41582
41583/* OpenMP 4.0:
41584 device ( expression )
41585
41586 OpenMP 5.0:
41587 device ( [device-modifier :] integer-expression )
41588
41589 device-modifier:
41590 ancestor | device_num */
41591
41592static tree
41593cp_parser_omp_clause_device (cp_parser *parser, tree list,
41594 location_t location)
41595{
41596 tree t, c;
41597 bool ancestor = false;
41598
41599 matching_parens parens;
41600 if (!parens.require_open (parser))
41601 return list;
41602
41603 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
41604 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_COLON))
41605 {
41606 cp_token *tok = cp_lexer_peek_token (lexer: parser->lexer);
41607 const char *p = IDENTIFIER_POINTER (tok->u.value);
41608 if (strcmp (s1: "ancestor", s2: p) == 0)
41609 {
41610 ancestor = true;
41611
41612 /* A requires directive with the reverse_offload clause must be
41613 specified. */
41614 if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
41615 {
41616 error_at (tok->location, "%<ancestor%> device modifier not "
41617 "preceded by %<requires%> directive "
41618 "with %<reverse_offload%> clause");
41619 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false, consume_paren: true);
41620 return list;
41621 }
41622 }
41623 else if (strcmp (s1: "device_num", s2: p) == 0)
41624 ;
41625 else
41626 {
41627 error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
41628 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false, consume_paren: true);
41629 return list;
41630 }
41631 cp_lexer_consume_token (lexer: parser->lexer);
41632 cp_lexer_consume_token (lexer: parser->lexer);
41633 }
41634
41635 t = cp_parser_assignment_expression (parser);
41636
41637 if (t == error_mark_node
41638 || !parens.require_close (parser))
41639 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41640 /*or_comma=*/false,
41641 /*consume_paren=*/true);
41642
41643 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_DEVICE,
41644 name: "device", location);
41645
41646 c = build_omp_clause (location, OMP_CLAUSE_DEVICE);
41647 OMP_CLAUSE_DEVICE_ID (c) = t;
41648 OMP_CLAUSE_CHAIN (c) = list;
41649 OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
41650
41651 return c;
41652}
41653
41654/* OpenMP 4.0:
41655 dist_schedule ( static )
41656 dist_schedule ( static , expression ) */
41657
41658static tree
41659cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
41660 location_t location)
41661{
41662 tree c, t;
41663
41664 matching_parens parens;
41665 if (!parens.require_open (parser))
41666 return list;
41667
41668 c = build_omp_clause (location, OMP_CLAUSE_DIST_SCHEDULE);
41669
41670 if (!cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_STATIC))
41671 goto invalid_kind;
41672 cp_lexer_consume_token (lexer: parser->lexer);
41673
41674 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
41675 {
41676 cp_lexer_consume_token (lexer: parser->lexer);
41677
41678 t = cp_parser_assignment_expression (parser);
41679
41680 if (t == error_mark_node)
41681 goto resync_fail;
41682 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
41683
41684 if (!parens.require_close (parser))
41685 goto resync_fail;
41686 }
41687 else if (!cp_parser_require (parser, type: CPP_CLOSE_PAREN, token_desc: RT_COMMA_CLOSE_PAREN))
41688 goto resync_fail;
41689
41690 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
41691 "dist_schedule", location); */
41692 if (omp_find_clause (clauses: list, kind: OMP_CLAUSE_DIST_SCHEDULE))
41693 warning_at (location, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
41694 OMP_CLAUSE_CHAIN (c) = list;
41695 return c;
41696
41697 invalid_kind:
41698 cp_parser_error (parser, gmsgid: "invalid dist_schedule kind");
41699 resync_fail:
41700 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41701 /*or_comma=*/false,
41702 /*consume_paren=*/true);
41703 return list;
41704}
41705
41706/* OpenMP 4.0:
41707 proc_bind ( proc-bind-kind )
41708
41709 proc-bind-kind:
41710 primary | master | close | spread
41711 where OpenMP 5.1 added 'primary' and deprecated the alias 'master'. */
41712
41713static tree
41714cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
41715 location_t location)
41716{
41717 tree c;
41718 enum omp_clause_proc_bind_kind kind;
41719
41720 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
41721 return list;
41722
41723 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
41724 {
41725 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
41726 const char *p = IDENTIFIER_POINTER (id);
41727
41728 if (strcmp (s1: "primary", s2: p) == 0)
41729 kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
41730 else if (strcmp (s1: "master", s2: p) == 0)
41731 kind = OMP_CLAUSE_PROC_BIND_MASTER;
41732 else if (strcmp (s1: "close", s2: p) == 0)
41733 kind = OMP_CLAUSE_PROC_BIND_CLOSE;
41734 else if (strcmp (s1: "spread", s2: p) == 0)
41735 kind = OMP_CLAUSE_PROC_BIND_SPREAD;
41736 else
41737 goto invalid_kind;
41738 }
41739 else
41740 goto invalid_kind;
41741
41742 cp_lexer_consume_token (lexer: parser->lexer);
41743 if (!cp_parser_require (parser, type: CPP_CLOSE_PAREN, token_desc: RT_COMMA_CLOSE_PAREN))
41744 goto resync_fail;
41745
41746 c = build_omp_clause (location, OMP_CLAUSE_PROC_BIND);
41747 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_PROC_BIND, name: "proc_bind",
41748 location);
41749 OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
41750 OMP_CLAUSE_CHAIN (c) = list;
41751 return c;
41752
41753 invalid_kind:
41754 cp_parser_error (parser, gmsgid: "invalid depend kind");
41755 resync_fail:
41756 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41757 /*or_comma=*/false,
41758 /*consume_paren=*/true);
41759 return list;
41760}
41761
41762/* OpenMP 5.0:
41763 device_type ( host | nohost | any ) */
41764
41765static tree
41766cp_parser_omp_clause_device_type (cp_parser *parser, tree list,
41767 location_t location)
41768{
41769 tree c;
41770 enum omp_clause_device_type_kind kind;
41771
41772 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
41773 return list;
41774
41775 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
41776 {
41777 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
41778 const char *p = IDENTIFIER_POINTER (id);
41779
41780 if (strcmp (s1: "host", s2: p) == 0)
41781 kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
41782 else if (strcmp (s1: "nohost", s2: p) == 0)
41783 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
41784 else if (strcmp (s1: "any", s2: p) == 0)
41785 kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
41786 else
41787 goto invalid_kind;
41788 }
41789 else
41790 goto invalid_kind;
41791
41792 cp_lexer_consume_token (lexer: parser->lexer);
41793 if (!cp_parser_require (parser, type: CPP_CLOSE_PAREN, token_desc: RT_COMMA_CLOSE_PAREN))
41794 goto resync_fail;
41795
41796 c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE);
41797 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_DEVICE_TYPE, name: "device_type",
41798 location);
41799 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
41800 OMP_CLAUSE_CHAIN (c) = list;
41801 return c;
41802
41803 invalid_kind:
41804 cp_parser_error (parser, gmsgid: "invalid depend kind");
41805 resync_fail:
41806 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41807 /*or_comma=*/false,
41808 /*consume_paren=*/true);
41809 return list;
41810}
41811
41812/* OpenACC:
41813 async [( int-expr )] */
41814
41815static tree
41816cp_parser_oacc_clause_async (cp_parser *parser, tree list)
41817{
41818 tree c, t;
41819 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
41820
41821 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
41822
41823 if (cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_OPEN_PAREN)
41824 {
41825 matching_parens parens;
41826 parens.consume_open (parser);
41827
41828 t = cp_parser_assignment_expression (parser);
41829 if (t == error_mark_node
41830 || !parens.require_close (parser))
41831 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41832 /*or_comma=*/false,
41833 /*consume_paren=*/true);
41834 }
41835
41836 check_no_duplicate_clause (clauses: list, code: OMP_CLAUSE_ASYNC, name: "async", location: loc);
41837
41838 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
41839 OMP_CLAUSE_ASYNC_EXPR (c) = t;
41840 OMP_CLAUSE_CHAIN (c) = list;
41841 list = c;
41842
41843 return list;
41844}
41845
41846/* OpenACC 2.7:
41847 self [( expression )] */
41848
41849static tree
41850cp_parser_oacc_compute_clause_self (cp_parser *parser, tree list)
41851{
41852 tree t;
41853 location_t location = cp_lexer_peek_token (lexer: parser->lexer)->location;
41854 if (cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_OPEN_PAREN)
41855 {
41856 matching_parens parens;
41857 parens.consume_open (parser);
41858 t = cp_parser_assignment_expression (parser);
41859 if (t == error_mark_node
41860 || !parens.require_close (parser))
41861 {
41862 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
41863 /*or_comma=*/false,
41864 /*consume_paren=*/true);
41865 return list;
41866 }
41867 }
41868 else
41869 t = truthvalue_true_node;
41870
41871 for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
41872 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
41873 {
41874 error_at (location, "too many %<self%> clauses");
41875 return list;
41876 }
41877
41878 tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
41879 OMP_CLAUSE_SELF_EXPR (c) = t;
41880 OMP_CLAUSE_CHAIN (c) = list;
41881 return c;
41882}
41883
41884/* Parse all OpenACC clauses. The set clauses allowed by the directive
41885 is a bitmask in MASK. Return the list of clauses found. */
41886
41887static tree
41888cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
41889 const char *where, cp_token *pragma_tok,
41890 bool finish_p = true, bool target_p = false)
41891{
41892 tree clauses = NULL;
41893 bool first = true;
41894
41895 /* Don't create location wrapper nodes within OpenACC clauses. */
41896 auto_suppress_location_wrappers sentinel;
41897
41898 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
41899 {
41900 location_t here;
41901 pragma_omp_clause c_kind;
41902 omp_clause_code code;
41903 const char *c_name;
41904 tree prev = clauses;
41905
41906 if (!first && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
41907 cp_lexer_consume_token (lexer: parser->lexer);
41908
41909 here = cp_lexer_peek_token (lexer: parser->lexer)->location;
41910 c_kind = cp_parser_omp_clause_name (parser);
41911
41912 switch (c_kind)
41913 {
41914 case PRAGMA_OACC_CLAUSE_ASYNC:
41915 clauses = cp_parser_oacc_clause_async (parser, list: clauses);
41916 c_name = "async";
41917 break;
41918 case PRAGMA_OACC_CLAUSE_AUTO:
41919 clauses = cp_parser_oacc_simple_clause (loc: here, code: OMP_CLAUSE_AUTO,
41920 list: clauses);
41921 c_name = "auto";
41922 break;
41923 case PRAGMA_OACC_CLAUSE_ATTACH:
41924 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41925 c_name = "attach";
41926 break;
41927 case PRAGMA_OACC_CLAUSE_COLLAPSE:
41928 clauses = cp_parser_omp_clause_collapse (parser, list: clauses, location: here);
41929 c_name = "collapse";
41930 break;
41931 case PRAGMA_OACC_CLAUSE_COPY:
41932 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41933 c_name = "copy";
41934 break;
41935 case PRAGMA_OACC_CLAUSE_COPYIN:
41936 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41937 c_name = "copyin";
41938 break;
41939 case PRAGMA_OACC_CLAUSE_COPYOUT:
41940 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41941 c_name = "copyout";
41942 break;
41943 case PRAGMA_OACC_CLAUSE_CREATE:
41944 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41945 c_name = "create";
41946 break;
41947 case PRAGMA_OACC_CLAUSE_DELETE:
41948 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41949 c_name = "delete";
41950 break;
41951 case PRAGMA_OMP_CLAUSE_DEFAULT:
41952 clauses = cp_parser_omp_clause_default (parser, list: clauses, location: here, is_oacc: true);
41953 c_name = "default";
41954 break;
41955 case PRAGMA_OACC_CLAUSE_DETACH:
41956 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41957 c_name = "detach";
41958 break;
41959 case PRAGMA_OACC_CLAUSE_DEVICE:
41960 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41961 c_name = "device";
41962 break;
41963 case PRAGMA_OACC_CLAUSE_DEVICEPTR:
41964 clauses = cp_parser_oacc_data_clause_deviceptr (parser, list: clauses);
41965 c_name = "deviceptr";
41966 break;
41967 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
41968 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41969 c_name = "device_resident";
41970 break;
41971 case PRAGMA_OACC_CLAUSE_FINALIZE:
41972 clauses = cp_parser_oacc_simple_clause (loc: here, code: OMP_CLAUSE_FINALIZE,
41973 list: clauses);
41974 c_name = "finalize";
41975 break;
41976 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
41977 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_FIRSTPRIVATE,
41978 list: clauses);
41979 c_name = "firstprivate";
41980 break;
41981 case PRAGMA_OACC_CLAUSE_GANG:
41982 c_name = "gang";
41983 clauses = cp_parser_oacc_shape_clause (parser, loc: here, kind: OMP_CLAUSE_GANG,
41984 str: c_name, list: clauses);
41985 break;
41986 case PRAGMA_OACC_CLAUSE_HOST:
41987 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
41988 c_name = "host";
41989 break;
41990 case PRAGMA_OACC_CLAUSE_IF:
41991 clauses = cp_parser_omp_clause_if (parser, list: clauses, location: here, is_omp: false);
41992 c_name = "if";
41993 break;
41994 case PRAGMA_OACC_CLAUSE_IF_PRESENT:
41995 clauses = cp_parser_oacc_simple_clause (loc: here, code: OMP_CLAUSE_IF_PRESENT,
41996 list: clauses);
41997 c_name = "if_present";
41998 break;
41999 case PRAGMA_OACC_CLAUSE_INDEPENDENT:
42000 clauses = cp_parser_oacc_simple_clause (loc: here, code: OMP_CLAUSE_INDEPENDENT,
42001 list: clauses);
42002 c_name = "independent";
42003 break;
42004 case PRAGMA_OACC_CLAUSE_LINK:
42005 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
42006 c_name = "link";
42007 break;
42008 case PRAGMA_OACC_CLAUSE_NO_CREATE:
42009 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
42010 c_name = "no_create";
42011 break;
42012 case PRAGMA_OACC_CLAUSE_NOHOST:
42013 clauses = cp_parser_oacc_simple_clause (loc: here, code: OMP_CLAUSE_NOHOST,
42014 list: clauses);
42015 c_name = "nohost";
42016 break;
42017 case PRAGMA_OACC_CLAUSE_NUM_GANGS:
42018 code = OMP_CLAUSE_NUM_GANGS;
42019 c_name = "num_gangs";
42020 clauses = cp_parser_oacc_single_int_clause (parser, code, str: c_name,
42021 list: clauses);
42022 break;
42023 case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
42024 c_name = "num_workers";
42025 code = OMP_CLAUSE_NUM_WORKERS;
42026 clauses = cp_parser_oacc_single_int_clause (parser, code, str: c_name,
42027 list: clauses);
42028 break;
42029 case PRAGMA_OACC_CLAUSE_PRESENT:
42030 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
42031 c_name = "present";
42032 break;
42033 case PRAGMA_OACC_CLAUSE_PRIVATE:
42034 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_PRIVATE,
42035 list: clauses);
42036 c_name = "private";
42037 break;
42038 case PRAGMA_OACC_CLAUSE_REDUCTION:
42039 clauses
42040 = cp_parser_omp_clause_reduction (parser, kind: OMP_CLAUSE_REDUCTION,
42041 is_omp: false, list: clauses);
42042 c_name = "reduction";
42043 break;
42044 case PRAGMA_OACC_CLAUSE_SELF:
42045 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
42046 /* OpenACC compute construct */
42047 clauses = cp_parser_oacc_compute_clause_self (parser, list: clauses);
42048 else
42049 /* OpenACC 'update' directive */
42050 clauses = cp_parser_oacc_data_clause (parser, c_kind, list: clauses);
42051 c_name = "self";
42052 break;
42053 case PRAGMA_OACC_CLAUSE_SEQ:
42054 clauses = cp_parser_oacc_simple_clause (loc: here, code: OMP_CLAUSE_SEQ,
42055 list: clauses);
42056 c_name = "seq";
42057 break;
42058 case PRAGMA_OACC_CLAUSE_TILE:
42059 clauses = cp_parser_oacc_clause_tile (parser, clause_loc: here, list: clauses);
42060 c_name = "tile";
42061 break;
42062 case PRAGMA_OACC_CLAUSE_USE_DEVICE:
42063 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_USE_DEVICE_PTR,
42064 list: clauses);
42065 c_name = "use_device";
42066 break;
42067 case PRAGMA_OACC_CLAUSE_VECTOR:
42068 c_name = "vector";
42069 clauses = cp_parser_oacc_shape_clause (parser, loc: here,
42070 kind: OMP_CLAUSE_VECTOR,
42071 str: c_name, list: clauses);
42072 break;
42073 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
42074 c_name = "vector_length";
42075 code = OMP_CLAUSE_VECTOR_LENGTH;
42076 clauses = cp_parser_oacc_single_int_clause (parser, code, str: c_name,
42077 list: clauses);
42078 break;
42079 case PRAGMA_OACC_CLAUSE_WAIT:
42080 clauses = cp_parser_oacc_clause_wait (parser, list: clauses);
42081 c_name = "wait";
42082 break;
42083 case PRAGMA_OACC_CLAUSE_WORKER:
42084 c_name = "worker";
42085 clauses = cp_parser_oacc_shape_clause (parser, loc: here,
42086 kind: OMP_CLAUSE_WORKER,
42087 str: c_name, list: clauses);
42088 break;
42089 default:
42090 cp_parser_error (parser, gmsgid: "expected an OpenACC clause");
42091 goto saw_error;
42092 }
42093
42094 first = false;
42095
42096 if (((mask >> c_kind) & 1) == 0)
42097 {
42098 /* Remove the invalid clause(s) from the list to avoid
42099 confusing the rest of the compiler. */
42100 clauses = prev;
42101 error_at (here, "%qs is not valid for %qs", c_name, where);
42102 }
42103 }
42104
42105 saw_error:
42106 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
42107
42108 if (finish_p)
42109 return finish_omp_clauses (clauses, target_p ? C_ORT_ACC_TARGET
42110 : C_ORT_ACC);
42111
42112 return clauses;
42113}
42114
42115/* Parse all OpenMP clauses. The set clauses allowed by the directive
42116 is a bitmask in MASK. Return the list of clauses found.
42117 FINISH_P set if finish_omp_clauses should be called.
42118 NESTED non-zero if clauses should be terminated by closing paren instead
42119 of end of pragma. If it is 2, additionally commas are required in between
42120 the clauses. */
42121
42122static tree
42123cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
42124 const char *where, cp_token *pragma_tok,
42125 bool finish_p = true, int nested = 0)
42126{
42127 tree clauses = NULL;
42128 bool first = true;
42129 cp_token *token = NULL;
42130
42131 /* Don't create location wrapper nodes within OpenMP clauses. */
42132 auto_suppress_location_wrappers sentinel;
42133
42134 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
42135 {
42136 pragma_omp_clause c_kind;
42137 const char *c_name;
42138 tree prev = clauses;
42139
42140 if (nested && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
42141 break;
42142
42143 if (!first || nested != 2)
42144 {
42145 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
42146 cp_lexer_consume_token (lexer: parser->lexer);
42147 else if (nested == 2)
42148 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
42149 "clauses in %<simd%> trait should be separated "
42150 "by %<,%>");
42151 }
42152
42153 token = cp_lexer_peek_token (lexer: parser->lexer);
42154 c_kind = cp_parser_omp_clause_name (parser);
42155
42156 switch (c_kind)
42157 {
42158 case PRAGMA_OMP_CLAUSE_BIND:
42159 clauses = cp_parser_omp_clause_bind (parser, list: clauses,
42160 location: token->location);
42161 c_name = "bind";
42162 break;
42163 case PRAGMA_OMP_CLAUSE_COLLAPSE:
42164 clauses = cp_parser_omp_clause_collapse (parser, list: clauses,
42165 location: token->location);
42166 c_name = "collapse";
42167 break;
42168 case PRAGMA_OMP_CLAUSE_COPYIN:
42169 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_COPYIN, list: clauses);
42170 c_name = "copyin";
42171 break;
42172 case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
42173 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_COPYPRIVATE,
42174 list: clauses);
42175 c_name = "copyprivate";
42176 break;
42177 case PRAGMA_OMP_CLAUSE_DEFAULT:
42178 clauses = cp_parser_omp_clause_default (parser, list: clauses,
42179 location: token->location, is_oacc: false);
42180 c_name = "default";
42181 break;
42182 case PRAGMA_OMP_CLAUSE_FILTER:
42183 clauses = cp_parser_omp_clause_filter (parser, list: clauses,
42184 location: token->location);
42185 c_name = "filter";
42186 break;
42187 case PRAGMA_OMP_CLAUSE_FINAL:
42188 clauses = cp_parser_omp_clause_final (parser, list: clauses, location: token->location);
42189 c_name = "final";
42190 break;
42191 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
42192 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_FIRSTPRIVATE,
42193 list: clauses);
42194 c_name = "firstprivate";
42195 break;
42196 case PRAGMA_OMP_CLAUSE_GRAINSIZE:
42197 clauses = cp_parser_omp_clause_grainsize (parser, list: clauses,
42198 location: token->location);
42199 c_name = "grainsize";
42200 break;
42201 case PRAGMA_OMP_CLAUSE_HINT:
42202 clauses = cp_parser_omp_clause_hint (parser, list: clauses,
42203 location: token->location);
42204 c_name = "hint";
42205 break;
42206 case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
42207 clauses = cp_parser_omp_clause_defaultmap (parser, list: clauses,
42208 location: token->location);
42209 c_name = "defaultmap";
42210 break;
42211 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
42212 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_USE_DEVICE_PTR,
42213 list: clauses);
42214 c_name = "use_device_ptr";
42215 break;
42216 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
42217 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_USE_DEVICE_ADDR,
42218 list: clauses);
42219 c_name = "use_device_addr";
42220 break;
42221 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
42222 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_IS_DEVICE_PTR,
42223 list: clauses);
42224 c_name = "is_device_ptr";
42225 break;
42226 case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
42227 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_HAS_DEVICE_ADDR,
42228 list: clauses);
42229 c_name = "has_device_addr";
42230 break;
42231 case PRAGMA_OMP_CLAUSE_IF:
42232 clauses = cp_parser_omp_clause_if (parser, list: clauses, location: token->location,
42233 is_omp: true);
42234 c_name = "if";
42235 break;
42236 case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
42237 clauses
42238 = cp_parser_omp_clause_reduction (parser, kind: OMP_CLAUSE_IN_REDUCTION,
42239 is_omp: true, list: clauses);
42240 c_name = "in_reduction";
42241 break;
42242 case PRAGMA_OMP_CLAUSE_INDIRECT:
42243 clauses = cp_parser_omp_clause_indirect (parser, list: clauses,
42244 location: token->location);
42245 c_name = "indirect";
42246 break;
42247 case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
42248 clauses = cp_parser_omp_clause_lastprivate (parser, list: clauses);
42249 c_name = "lastprivate";
42250 break;
42251 case PRAGMA_OMP_CLAUSE_MERGEABLE:
42252 clauses = cp_parser_omp_clause_mergeable (parser, list: clauses,
42253 location: token->location);
42254 c_name = "mergeable";
42255 break;
42256 case PRAGMA_OMP_CLAUSE_NOWAIT:
42257 clauses = cp_parser_omp_clause_nowait (parser, list: clauses,
42258 location: token->location);
42259 c_name = "nowait";
42260 break;
42261 case PRAGMA_OMP_CLAUSE_NUM_TASKS:
42262 clauses = cp_parser_omp_clause_num_tasks (parser, list: clauses,
42263 location: token->location);
42264 c_name = "num_tasks";
42265 break;
42266 case PRAGMA_OMP_CLAUSE_NUM_THREADS:
42267 clauses = cp_parser_omp_clause_num_threads (parser, list: clauses,
42268 location: token->location);
42269 c_name = "num_threads";
42270 break;
42271 case PRAGMA_OMP_CLAUSE_ORDER:
42272 clauses = cp_parser_omp_clause_order (parser, list: clauses,
42273 location: token->location);
42274 c_name = "order";
42275 break;
42276 case PRAGMA_OMP_CLAUSE_ORDERED:
42277 clauses = cp_parser_omp_clause_ordered (parser, list: clauses,
42278 location: token->location);
42279 c_name = "ordered";
42280 break;
42281 case PRAGMA_OMP_CLAUSE_PRIORITY:
42282 clauses = cp_parser_omp_clause_priority (parser, list: clauses,
42283 location: token->location);
42284 c_name = "priority";
42285 break;
42286 case PRAGMA_OMP_CLAUSE_PRIVATE:
42287 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_PRIVATE,
42288 list: clauses);
42289 c_name = "private";
42290 break;
42291 case PRAGMA_OMP_CLAUSE_REDUCTION:
42292 clauses
42293 = cp_parser_omp_clause_reduction (parser, kind: OMP_CLAUSE_REDUCTION,
42294 is_omp: true, list: clauses);
42295 c_name = "reduction";
42296 break;
42297 case PRAGMA_OMP_CLAUSE_SCHEDULE:
42298 clauses = cp_parser_omp_clause_schedule (parser, list: clauses,
42299 location: token->location);
42300 c_name = "schedule";
42301 break;
42302 case PRAGMA_OMP_CLAUSE_SHARED:
42303 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_SHARED,
42304 list: clauses);
42305 c_name = "shared";
42306 break;
42307 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
42308 clauses
42309 = cp_parser_omp_clause_reduction (parser,
42310 kind: OMP_CLAUSE_TASK_REDUCTION,
42311 is_omp: true, list: clauses);
42312 c_name = "task_reduction";
42313 break;
42314 case PRAGMA_OMP_CLAUSE_UNTIED:
42315 clauses = cp_parser_omp_clause_untied (parser, list: clauses,
42316 location: token->location);
42317 c_name = "untied";
42318 break;
42319 case PRAGMA_OMP_CLAUSE_INBRANCH:
42320 clauses = cp_parser_omp_clause_branch (parser, code: OMP_CLAUSE_INBRANCH,
42321 list: clauses, location: token->location);
42322 c_name = "inbranch";
42323 break;
42324 case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
42325 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_NONTEMPORAL,
42326 list: clauses);
42327 c_name = "nontemporal";
42328 break;
42329 case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
42330 clauses = cp_parser_omp_clause_branch (parser,
42331 code: OMP_CLAUSE_NOTINBRANCH,
42332 list: clauses, location: token->location);
42333 c_name = "notinbranch";
42334 break;
42335 case PRAGMA_OMP_CLAUSE_PARALLEL:
42336 clauses = cp_parser_omp_clause_cancelkind (parser, code: OMP_CLAUSE_PARALLEL,
42337 list: clauses, location: token->location);
42338 c_name = "parallel";
42339 if (!first)
42340 {
42341 clause_not_first:
42342 error_at (token->location, "%qs must be the first clause of %qs",
42343 c_name, where);
42344 clauses = prev;
42345 }
42346 break;
42347 case PRAGMA_OMP_CLAUSE_FOR:
42348 clauses = cp_parser_omp_clause_cancelkind (parser, code: OMP_CLAUSE_FOR,
42349 list: clauses, location: token->location);
42350 c_name = "for";
42351 if (!first)
42352 goto clause_not_first;
42353 break;
42354 case PRAGMA_OMP_CLAUSE_SECTIONS:
42355 clauses = cp_parser_omp_clause_cancelkind (parser, code: OMP_CLAUSE_SECTIONS,
42356 list: clauses, location: token->location);
42357 c_name = "sections";
42358 if (!first)
42359 goto clause_not_first;
42360 break;
42361 case PRAGMA_OMP_CLAUSE_TASKGROUP:
42362 clauses = cp_parser_omp_clause_cancelkind (parser, code: OMP_CLAUSE_TASKGROUP,
42363 list: clauses, location: token->location);
42364 c_name = "taskgroup";
42365 if (!first)
42366 goto clause_not_first;
42367 break;
42368 case PRAGMA_OMP_CLAUSE_LINK:
42369 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_LINK, list: clauses);
42370 c_name = "link";
42371 break;
42372 case PRAGMA_OMP_CLAUSE_TO:
42373 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
42374 {
42375 tree nl = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_ENTER,
42376 list: clauses);
42377 for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
42378 OMP_CLAUSE_ENTER_TO (c) = 1;
42379 clauses = nl;
42380 }
42381 else
42382 clauses = cp_parser_omp_clause_from_to (parser, kind: OMP_CLAUSE_TO,
42383 list: clauses);
42384 c_name = "to";
42385 break;
42386 case PRAGMA_OMP_CLAUSE_FROM:
42387 clauses = cp_parser_omp_clause_from_to (parser, kind: OMP_CLAUSE_FROM,
42388 list: clauses);
42389 c_name = "from";
42390 break;
42391 case PRAGMA_OMP_CLAUSE_UNIFORM:
42392 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_UNIFORM,
42393 list: clauses);
42394 c_name = "uniform";
42395 break;
42396 case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
42397 clauses = cp_parser_omp_clause_num_teams (parser, list: clauses,
42398 location: token->location);
42399 c_name = "num_teams";
42400 break;
42401 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
42402 clauses = cp_parser_omp_clause_thread_limit (parser, list: clauses,
42403 location: token->location);
42404 c_name = "thread_limit";
42405 break;
42406 case PRAGMA_OMP_CLAUSE_ALIGNED:
42407 clauses = cp_parser_omp_clause_aligned (parser, list: clauses);
42408 c_name = "aligned";
42409 break;
42410 case PRAGMA_OMP_CLAUSE_ALLOCATE:
42411 clauses = cp_parser_omp_clause_allocate (parser, list: clauses);
42412 c_name = "allocate";
42413 break;
42414 case PRAGMA_OMP_CLAUSE_LINEAR:
42415 {
42416 bool declare_simd = false;
42417 if (((mask >> PRAGMA_OMP_CLAUSE_UNIFORM) & 1) != 0)
42418 declare_simd = true;
42419 clauses = cp_parser_omp_clause_linear (parser, list: clauses, declare_simd);
42420 }
42421 c_name = "linear";
42422 break;
42423 case PRAGMA_OMP_CLAUSE_AFFINITY:
42424 clauses = cp_parser_omp_clause_affinity (parser, list: clauses);
42425 c_name = "affinity";
42426 break;
42427 case PRAGMA_OMP_CLAUSE_DEPEND:
42428 clauses = cp_parser_omp_clause_depend (parser, list: clauses,
42429 loc: token->location);
42430 c_name = "depend";
42431 break;
42432 case PRAGMA_OMP_CLAUSE_DOACROSS:
42433 clauses = cp_parser_omp_clause_doacross (parser, list: clauses,
42434 loc: token->location);
42435 c_name = "doacross";
42436 break;
42437 case PRAGMA_OMP_CLAUSE_DETACH:
42438 clauses = cp_parser_omp_clause_detach (parser, list: clauses);
42439 c_name = "detach";
42440 break;
42441 case PRAGMA_OMP_CLAUSE_MAP:
42442 clauses = cp_parser_omp_clause_map (parser, list: clauses);
42443 c_name = "map";
42444 break;
42445 case PRAGMA_OMP_CLAUSE_DEVICE:
42446 clauses = cp_parser_omp_clause_device (parser, list: clauses,
42447 location: token->location);
42448 c_name = "device";
42449 break;
42450 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
42451 clauses = cp_parser_omp_clause_dist_schedule (parser, list: clauses,
42452 location: token->location);
42453 c_name = "dist_schedule";
42454 break;
42455 case PRAGMA_OMP_CLAUSE_PROC_BIND:
42456 clauses = cp_parser_omp_clause_proc_bind (parser, list: clauses,
42457 location: token->location);
42458 c_name = "proc_bind";
42459 break;
42460 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
42461 clauses = cp_parser_omp_clause_device_type (parser, list: clauses,
42462 location: token->location);
42463 c_name = "device_type";
42464 break;
42465 case PRAGMA_OMP_CLAUSE_SAFELEN:
42466 clauses = cp_parser_omp_clause_safelen (parser, list: clauses,
42467 location: token->location);
42468 c_name = "safelen";
42469 break;
42470 case PRAGMA_OMP_CLAUSE_SIMDLEN:
42471 clauses = cp_parser_omp_clause_simdlen (parser, list: clauses,
42472 location: token->location);
42473 c_name = "simdlen";
42474 break;
42475 case PRAGMA_OMP_CLAUSE_NOGROUP:
42476 clauses = cp_parser_omp_clause_nogroup (parser, list: clauses,
42477 location: token->location);
42478 c_name = "nogroup";
42479 break;
42480 case PRAGMA_OMP_CLAUSE_THREADS:
42481 clauses
42482 = cp_parser_omp_clause_orderedkind (parser, code: OMP_CLAUSE_THREADS,
42483 list: clauses, location: token->location);
42484 c_name = "threads";
42485 break;
42486 case PRAGMA_OMP_CLAUSE_SIMD:
42487 clauses
42488 = cp_parser_omp_clause_orderedkind (parser, code: OMP_CLAUSE_SIMD,
42489 list: clauses, location: token->location);
42490 c_name = "simd";
42491 break;
42492 case PRAGMA_OMP_CLAUSE_ENTER:
42493 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_ENTER,
42494 list: clauses);
42495 c_name = "enter";
42496 break;
42497 default:
42498 cp_parser_error (parser, gmsgid: "expected an OpenMP clause");
42499 goto saw_error;
42500 }
42501
42502 first = false;
42503
42504 if (((mask >> c_kind) & 1) == 0)
42505 {
42506 /* Remove the invalid clause(s) from the list to avoid
42507 confusing the rest of the compiler. */
42508 clauses = prev;
42509 error_at (token->location, "%qs is not valid for %qs", c_name, where);
42510 }
42511 }
42512 saw_error:
42513 if (!nested)
42514 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
42515 if (finish_p)
42516 {
42517 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
42518 return finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
42519 else
42520 return finish_omp_clauses (clauses, C_ORT_OMP);
42521 }
42522 return clauses;
42523}
42524
42525/* OpenMP 2.5:
42526 structured-block:
42527 statement
42528
42529 In practice, we're also interested in adding the statement to an
42530 outer node. So it is convenient if we work around the fact that
42531 cp_parser_statement calls add_stmt. */
42532
42533static unsigned
42534cp_parser_begin_omp_structured_block (cp_parser *parser)
42535{
42536 unsigned save = parser->in_statement;
42537
42538 /* Only move the values to IN_OMP_BLOCK if they weren't false.
42539 This preserves the "not within loop or switch" style error messages
42540 for nonsense cases like
42541 void foo() {
42542 #pragma omp single
42543 break;
42544 }
42545 */
42546 if (parser->in_statement)
42547 parser->in_statement = IN_OMP_BLOCK;
42548
42549 return save;
42550}
42551
42552static void
42553cp_parser_end_omp_structured_block (cp_parser *parser, unsigned save)
42554{
42555 parser->in_statement = save;
42556}
42557
42558static tree
42559cp_parser_omp_structured_block (cp_parser *parser, bool *if_p)
42560{
42561 tree stmt = begin_omp_structured_block ();
42562 unsigned int save = cp_parser_begin_omp_structured_block (parser);
42563
42564 parser->omp_attrs_forbidden_p = true;
42565 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p);
42566
42567 cp_parser_end_omp_structured_block (parser, save);
42568 return finish_omp_structured_block (stmt);
42569}
42570
42571/* OpenMP 5.x:
42572 # pragma omp allocate (list) clauses
42573
42574 OpenMP 5.0 clause:
42575 allocator (omp_allocator_handle_t expression)
42576
42577 OpenMP 5.1 additional clause:
42578 align (constant-expression)] */
42579
42580static void
42581cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
42582{
42583 tree allocator = NULL_TREE;
42584 tree alignment = NULL_TREE;
42585 location_t loc = pragma_tok->location;
42586 tree nl = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_ALLOCATE, NULL_TREE);
42587
42588 do
42589 {
42590 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
42591 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
42592 cp_lexer_consume_token (lexer: parser->lexer);
42593
42594 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
42595 break;
42596 matching_parens parens;
42597 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
42598 const char *p = IDENTIFIER_POINTER (id);
42599 location_t cloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
42600 cp_lexer_consume_token (lexer: parser->lexer);
42601 if (strcmp (s1: p, s2: "allocator") != 0 && strcmp (s1: p, s2: "align") != 0)
42602 {
42603 error_at (cloc, "expected %<allocator%> or %<align%>");
42604 break;
42605 }
42606 if (!parens.require_open (parser))
42607 break;
42608 tree expr = cp_parser_assignment_expression (parser);
42609 if (p[2] == 'i' && alignment)
42610 {
42611 error_at (cloc, "too many %qs clauses", "align");
42612 break;
42613 }
42614 else if (p[2] == 'i')
42615 {
42616 if (expr != error_mark_node)
42617 alignment = expr;
42618 /* FIXME: Remove when adding check to semantics.cc; cf FIXME below. */
42619 if (alignment
42620 && !type_dependent_expression_p (alignment)
42621 && !INTEGRAL_TYPE_P (TREE_TYPE (alignment)))
42622 {
42623 error_at (cloc, "%<align%> clause argument needs to be "
42624 "positive constant power of two integer "
42625 "expression");
42626 alignment = NULL_TREE;
42627 }
42628 else if (alignment)
42629 {
42630 alignment = mark_rvalue_use (alignment);
42631 if (!processing_template_decl)
42632 {
42633 alignment = maybe_constant_value (alignment);
42634 if (TREE_CODE (alignment) != INTEGER_CST
42635 || !tree_fits_uhwi_p (alignment)
42636 || !integer_pow2p (alignment))
42637 {
42638 error_at (cloc, "%<align%> clause argument needs to be "
42639 "positive constant power of two integer "
42640 "expression");
42641 alignment = NULL_TREE;
42642 }
42643 }
42644 }
42645 }
42646 else if (allocator)
42647 {
42648 error_at (cloc, "too many %qs clauses", "allocator");
42649 break;
42650 }
42651 else
42652 {
42653 if (expr != error_mark_node)
42654 allocator = expr;
42655 }
42656 parens.require_close (parser);
42657 } while (true);
42658 cp_parser_require_pragma_eol (parser, pragma_tok);
42659
42660 if (allocator || alignment)
42661 for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
42662 {
42663 OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
42664 OMP_CLAUSE_ALLOCATE_ALIGN (c) = alignment;
42665 }
42666
42667 /* FIXME: When implementing properly, delete the align/allocate expr error
42668 check above and add one in semantics.cc (to properly handle templates).
42669 Base this on the allocator/align modifiers check for the 'allocate' clause
42670 in semantics.cc's finish_omp_clauses. */
42671 sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
42672}
42673
42674/* OpenMP 2.5:
42675 # pragma omp atomic new-line
42676 expression-stmt
42677
42678 expression-stmt:
42679 x binop= expr | x++ | ++x | x-- | --x
42680 binop:
42681 +, *, -, /, &, ^, |, <<, >>
42682
42683 where x is an lvalue expression with scalar type.
42684
42685 OpenMP 3.1:
42686 # pragma omp atomic new-line
42687 update-stmt
42688
42689 # pragma omp atomic read new-line
42690 read-stmt
42691
42692 # pragma omp atomic write new-line
42693 write-stmt
42694
42695 # pragma omp atomic update new-line
42696 update-stmt
42697
42698 # pragma omp atomic capture new-line
42699 capture-stmt
42700
42701 # pragma omp atomic capture new-line
42702 capture-block
42703
42704 read-stmt:
42705 v = x
42706 write-stmt:
42707 x = expr
42708 update-stmt:
42709 expression-stmt | x = x binop expr
42710 capture-stmt:
42711 v = expression-stmt
42712 capture-block:
42713 { v = x; update-stmt; } | { update-stmt; v = x; }
42714
42715 OpenMP 4.0:
42716 update-stmt:
42717 expression-stmt | x = x binop expr | x = expr binop x
42718 capture-stmt:
42719 v = update-stmt
42720 capture-block:
42721 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
42722
42723 OpenMP 5.1:
42724 # pragma omp atomic compare new-line
42725 conditional-update-atomic
42726
42727 # pragma omp atomic compare capture new-line
42728 conditional-update-capture-atomic
42729
42730 conditional-update-atomic:
42731 cond-expr-stmt | cond-update-stmt
42732 cond-expr-stmt:
42733 x = expr ordop x ? expr : x;
42734 x = x ordop expr ? expr : x;
42735 x = x == e ? d : x;
42736 cond-update-stmt:
42737 if (expr ordop x) { x = expr; }
42738 if (x ordop expr) { x = expr; }
42739 if (x == e) { x = d; }
42740 ordop:
42741 <, >
42742 conditional-update-capture-atomic:
42743 v = cond-expr-stmt
42744 { v = x; cond-expr-stmt }
42745 { cond-expr-stmt v = x; }
42746 { v = x; cond-update-stmt }
42747 { cond-update-stmt v = x; }
42748 if (x == e) { x = d; } else { v = x; }
42749 { r = x == e; if (r) { x = d; } }
42750 { r = x == e; if (r) { x = d; } else { v = x; } }
42751
42752 where x, r and v are lvalue expressions with scalar type,
42753 expr, e and d are expressions with scalar type and e might be
42754 the same as v. */
42755
42756static void
42757cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok, bool openacc)
42758{
42759 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, lhs1 = NULL_TREE;
42760 tree rhs1 = NULL_TREE, orig_lhs, r = NULL_TREE;
42761 location_t loc = pragma_tok->location;
42762 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
42763 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
42764 bool structured_block = false;
42765 tree clauses = NULL_TREE;
42766 bool capture = false;
42767 bool compare = false;
42768 bool weak = false;
42769 enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
42770 bool no_semicolon = false;
42771 bool extra_scope = false;
42772
42773 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
42774 {
42775 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
42776 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
42777 cp_lexer_consume_token (lexer: parser->lexer);
42778
42779 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
42780 {
42781 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
42782 location_t cloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
42783 const char *p = IDENTIFIER_POINTER (id);
42784 enum tree_code new_code = ERROR_MARK;
42785 enum omp_memory_order new_memory_order
42786 = OMP_MEMORY_ORDER_UNSPECIFIED;
42787 bool new_capture = false;
42788 bool new_compare = false;
42789 bool new_weak = false;
42790 enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
42791
42792 if (!strcmp (s1: p, s2: "read"))
42793 new_code = OMP_ATOMIC_READ;
42794 else if (!strcmp (s1: p, s2: "write"))
42795 new_code = NOP_EXPR;
42796 else if (!strcmp (s1: p, s2: "update"))
42797 new_code = OMP_ATOMIC;
42798 else if (openacc && !strcmp (s1: p, s2: "capture"))
42799 new_code = OMP_ATOMIC_CAPTURE_NEW;
42800 else if (openacc)
42801 {
42802 p = NULL;
42803 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
42804 "or %<capture%> clause");
42805 }
42806 else if (!strcmp (s1: p, s2: "capture"))
42807 new_capture = true;
42808 else if (!strcmp (s1: p, s2: "compare"))
42809 new_compare = true;
42810 else if (!strcmp (s1: p, s2: "weak"))
42811 new_weak = true;
42812 else if (!strcmp (s1: p, s2: "fail"))
42813 {
42814 matching_parens parens;
42815
42816 cp_lexer_consume_token (lexer: parser->lexer);
42817 if (!parens.require_open (parser))
42818 continue;
42819
42820 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
42821 {
42822 id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
42823 const char *q = IDENTIFIER_POINTER (id);
42824
42825 if (!strcmp (s1: q, s2: "seq_cst"))
42826 new_fail = OMP_MEMORY_ORDER_SEQ_CST;
42827 else if (!strcmp (s1: q, s2: "acquire"))
42828 new_fail = OMP_MEMORY_ORDER_ACQUIRE;
42829 else if (!strcmp (s1: q, s2: "relaxed"))
42830 new_fail = OMP_MEMORY_ORDER_RELAXED;
42831 }
42832
42833 if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
42834 {
42835 cp_lexer_consume_token (lexer: parser->lexer);
42836 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
42837 error_at (cloc, "too many %qs clauses", "fail");
42838 else
42839 fail = new_fail;
42840 }
42841 else
42842 cp_parser_error (parser, gmsgid: "expected %<seq_cst%>, %<acquire%> "
42843 "or %<relaxed%>");
42844 if (new_fail == OMP_MEMORY_ORDER_UNSPECIFIED
42845 || !parens.require_close (parser))
42846 cp_parser_skip_to_closing_parenthesis (parser,
42847 /*recovering=*/true,
42848 /*or_comma=*/false,
42849 /*consume_paren=*/true);
42850 continue;
42851 }
42852 else if (!strcmp (s1: p, s2: "seq_cst"))
42853 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
42854 else if (!strcmp (s1: p, s2: "acq_rel"))
42855 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
42856 else if (!strcmp (s1: p, s2: "release"))
42857 new_memory_order = OMP_MEMORY_ORDER_RELEASE;
42858 else if (!strcmp (s1: p, s2: "acquire"))
42859 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
42860 else if (!strcmp (s1: p, s2: "relaxed"))
42861 new_memory_order = OMP_MEMORY_ORDER_RELAXED;
42862 else if (!strcmp (s1: p, s2: "hint"))
42863 {
42864 cp_lexer_consume_token (lexer: parser->lexer);
42865 clauses = cp_parser_omp_clause_hint (parser, list: clauses, location: cloc);
42866 continue;
42867 }
42868 else
42869 {
42870 p = NULL;
42871 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
42872 "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
42873 "%<seq_cst%>, %<acq_rel%>, %<release%>, "
42874 "%<relaxed%> or %<hint%> clause");
42875 }
42876 if (p)
42877 {
42878 if (new_code != ERROR_MARK)
42879 {
42880 /* OpenACC permits 'update capture'. */
42881 if (openacc
42882 && code == OMP_ATOMIC
42883 && new_code == OMP_ATOMIC_CAPTURE_NEW)
42884 code = new_code;
42885 else if (code != ERROR_MARK)
42886 error_at (cloc, "too many atomic clauses");
42887 else
42888 code = new_code;
42889 }
42890 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
42891 {
42892 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
42893 error_at (cloc, "too many memory order clauses");
42894 else
42895 memory_order = new_memory_order;
42896 }
42897 else if (new_capture)
42898 {
42899 if (capture)
42900 error_at (cloc, "too many %qs clauses", "capture");
42901 else
42902 capture = true;
42903 }
42904 else if (new_compare)
42905 {
42906 if (compare)
42907 error_at (cloc, "too many %qs clauses", "compare");
42908 else
42909 compare = true;
42910 }
42911 else if (new_weak)
42912 {
42913 if (weak)
42914 error_at (cloc, "too many %qs clauses", "weak");
42915 else
42916 weak = true;
42917 }
42918 cp_lexer_consume_token (lexer: parser->lexer);
42919 continue;
42920 }
42921 }
42922 break;
42923 }
42924 cp_parser_require_pragma_eol (parser, pragma_tok);
42925
42926 if (code == ERROR_MARK)
42927 code = OMP_ATOMIC;
42928 if (capture)
42929 {
42930 if (code != OMP_ATOMIC)
42931 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
42932 "clauses", "capture");
42933 else
42934 code = OMP_ATOMIC_CAPTURE_NEW;
42935 }
42936 if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
42937 {
42938 error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
42939 "clauses", "compare");
42940 compare = false;
42941 }
42942 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
42943 {
42944 error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
42945 fail = OMP_MEMORY_ORDER_UNSPECIFIED;
42946 }
42947 if (weak && !compare)
42948 {
42949 error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
42950 weak = false;
42951 }
42952 if (openacc)
42953 memory_order = OMP_MEMORY_ORDER_RELAXED;
42954 else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
42955 {
42956 omp_requires_mask
42957 = (enum omp_requires) (omp_requires_mask
42958 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
42959 switch ((enum omp_memory_order)
42960 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
42961 {
42962 case OMP_MEMORY_ORDER_UNSPECIFIED:
42963 case OMP_MEMORY_ORDER_RELAXED:
42964 memory_order = OMP_MEMORY_ORDER_RELAXED;
42965 break;
42966 case OMP_MEMORY_ORDER_SEQ_CST:
42967 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
42968 break;
42969 case OMP_MEMORY_ORDER_ACQUIRE:
42970 if (code == NOP_EXPR) /* atomic write */
42971 {
42972 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
42973 "%<acquire%> clause implicitly provided by a "
42974 "%<requires%> directive");
42975 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
42976 }
42977 else
42978 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
42979 break;
42980 case OMP_MEMORY_ORDER_RELEASE:
42981 if (code == OMP_ATOMIC_READ)
42982 {
42983 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
42984 "%<release%> clause implicitly provided by a "
42985 "%<requires%> directive");
42986 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
42987 }
42988 else
42989 memory_order = OMP_MEMORY_ORDER_RELEASE;
42990 break;
42991 case OMP_MEMORY_ORDER_ACQ_REL:
42992 switch (code)
42993 {
42994 case OMP_ATOMIC_READ:
42995 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
42996 break;
42997 case NOP_EXPR: /* atomic write */
42998 memory_order = OMP_MEMORY_ORDER_RELEASE;
42999 break;
43000 default:
43001 memory_order = OMP_MEMORY_ORDER_ACQ_REL;
43002 break;
43003 }
43004 break;
43005 default:
43006 gcc_unreachable ();
43007 }
43008 }
43009 else
43010 switch (code)
43011 {
43012 case OMP_ATOMIC_READ:
43013 if (memory_order == OMP_MEMORY_ORDER_RELEASE)
43014 {
43015 error_at (loc, "%<#pragma omp atomic read%> incompatible with "
43016 "%<release%> clause");
43017 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
43018 }
43019 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
43020 memory_order = OMP_MEMORY_ORDER_ACQUIRE;
43021 break;
43022 case NOP_EXPR: /* atomic write */
43023 if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
43024 {
43025 error_at (loc, "%<#pragma omp atomic write%> incompatible with "
43026 "%<acquire%> clause");
43027 memory_order = OMP_MEMORY_ORDER_SEQ_CST;
43028 }
43029 else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
43030 memory_order = OMP_MEMORY_ORDER_RELEASE;
43031 break;
43032 default:
43033 break;
43034 }
43035 if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
43036 memory_order
43037 = (enum omp_memory_order) (memory_order
43038 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
43039
43040 switch (code)
43041 {
43042 case OMP_ATOMIC_READ:
43043 case NOP_EXPR: /* atomic write */
43044 v = cp_parser_unary_expression (parser);
43045 if (v == error_mark_node)
43046 goto saw_error;
43047 if (!cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ))
43048 goto saw_error;
43049 if (code == NOP_EXPR)
43050 lhs = cp_parser_expression (parser);
43051 else
43052 lhs = cp_parser_unary_expression (parser);
43053 if (lhs == error_mark_node)
43054 goto saw_error;
43055 if (code == NOP_EXPR)
43056 {
43057 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
43058 opcode. */
43059 code = OMP_ATOMIC;
43060 rhs = lhs;
43061 lhs = v;
43062 v = NULL_TREE;
43063 }
43064 goto done;
43065 case OMP_ATOMIC_CAPTURE_NEW:
43066 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
43067 {
43068 cp_lexer_consume_token (lexer: parser->lexer);
43069 structured_block = true;
43070 }
43071 else if (compare
43072 && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_IF))
43073 break;
43074 else
43075 {
43076 v = cp_parser_unary_expression (parser);
43077 if (v == error_mark_node)
43078 goto saw_error;
43079 if (!cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ))
43080 goto saw_error;
43081 if (compare
43082 && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_IF))
43083 {
43084 location_t eloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
43085 error_at (eloc, "expected expression");
43086 goto saw_error;
43087 }
43088 }
43089 default:
43090 break;
43091 }
43092
43093restart:
43094 if (compare && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_IF))
43095 {
43096 cp_lexer_consume_token (lexer: parser->lexer);
43097
43098 matching_parens parens;
43099 if (!parens.require_open (parser))
43100 goto saw_error;
43101 location_t eloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
43102 tree cmp_expr;
43103 if (r)
43104 cmp_expr = cp_parser_unary_expression (parser);
43105 else
43106 cmp_expr = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: true,
43107 prec: PREC_NOT_OPERATOR, NULL);
43108 if (!parens.require_close (parser))
43109 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false, consume_paren: true);
43110 if (cmp_expr == error_mark_node)
43111 goto saw_error;
43112 if (r)
43113 {
43114 if (!cp_tree_equal (cmp_expr, r))
43115 goto bad_if;
43116 cmp_expr = rhs;
43117 rhs = NULL_TREE;
43118 gcc_assert (TREE_CODE (cmp_expr) == EQ_EXPR);
43119 }
43120 if (TREE_CODE (cmp_expr) == EQ_EXPR)
43121 ;
43122 else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
43123 {
43124 error_at (EXPR_LOC_OR_LOC (cmp_expr, eloc),
43125 "expected %<==%> comparison in %<if%> condition");
43126 goto saw_error;
43127 }
43128 else if (TREE_CODE (cmp_expr) != GT_EXPR
43129 && TREE_CODE (cmp_expr) != LT_EXPR)
43130 {
43131 error_at (EXPR_LOC_OR_LOC (cmp_expr, eloc),
43132 "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
43133 "condition");
43134 goto saw_error;
43135 }
43136 if (!cp_parser_require (parser, type: CPP_OPEN_BRACE, token_desc: RT_OPEN_BRACE))
43137 goto saw_error;
43138
43139 extra_scope = true;
43140 eloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
43141 lhs = cp_parser_unary_expression (parser);
43142 orig_lhs = lhs;
43143 if (lhs == error_mark_node)
43144 goto saw_error;
43145 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
43146 {
43147 cp_parser_error (parser, gmsgid: "expected %<=%>");
43148 goto saw_error;
43149 }
43150 cp_lexer_consume_token (lexer: parser->lexer);
43151 eloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
43152 if (TREE_CODE (cmp_expr) == EQ_EXPR)
43153 rhs1 = cp_parser_expression (parser);
43154 else
43155 rhs1 = cp_parser_simple_cast_expression (parser);
43156
43157 if (!cp_parser_require (parser, type: CPP_SEMICOLON, token_desc: RT_SEMICOLON))
43158 goto saw_error;
43159
43160 if (!cp_parser_require (parser, type: CPP_CLOSE_BRACE, token_desc: RT_CLOSE_BRACE))
43161 goto saw_error;
43162
43163 extra_scope = false;
43164 no_semicolon = true;
43165
43166 if (cp_tree_equal (TREE_OPERAND (cmp_expr, 0), lhs))
43167 {
43168 if (TREE_CODE (cmp_expr) == EQ_EXPR)
43169 {
43170 opcode = COND_EXPR;
43171 rhs = TREE_OPERAND (cmp_expr, 1);
43172 }
43173 else if (cp_tree_equal (TREE_OPERAND (cmp_expr, 1), rhs1))
43174 {
43175 opcode = (TREE_CODE (cmp_expr) == GT_EXPR
43176 ? MIN_EXPR : MAX_EXPR);
43177 rhs = rhs1;
43178 rhs1 = TREE_OPERAND (cmp_expr, 0);
43179 }
43180 else
43181 goto bad_if;
43182 }
43183 else if (TREE_CODE (cmp_expr) == EQ_EXPR)
43184 goto bad_if;
43185 else if (cp_tree_equal (TREE_OPERAND (cmp_expr, 1), lhs)
43186 && cp_tree_equal (TREE_OPERAND (cmp_expr, 0), rhs1))
43187 {
43188 opcode = (TREE_CODE (cmp_expr) == GT_EXPR
43189 ? MAX_EXPR : MIN_EXPR);
43190 rhs = rhs1;
43191 rhs1 = TREE_OPERAND (cmp_expr, 1);
43192 }
43193 else
43194 {
43195 bad_if:
43196 cp_parser_error (parser,
43197 gmsgid: "invalid form of %<#pragma omp atomic compare%>");
43198 goto saw_error;
43199 }
43200
43201 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_ELSE))
43202 {
43203 if (code != OMP_ATOMIC_CAPTURE_NEW
43204 || (structured_block && r == NULL_TREE)
43205 || TREE_CODE (cmp_expr) != EQ_EXPR)
43206 {
43207 eloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
43208 error_at (eloc, "unexpected %<else%>");
43209 goto saw_error;
43210 }
43211
43212 cp_lexer_consume_token (lexer: parser->lexer);
43213
43214 if (!cp_parser_require (parser, type: CPP_OPEN_BRACE, token_desc: RT_OPEN_BRACE))
43215 goto saw_error;
43216
43217 extra_scope = true;
43218 v = cp_parser_unary_expression (parser);
43219 if (v == error_mark_node)
43220 goto saw_error;
43221 if (!cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ))
43222 goto saw_error;
43223
43224 tree expr = cp_parser_simple_cast_expression (parser);
43225
43226 if (!cp_tree_equal (expr, lhs))
43227 goto bad_if;
43228
43229 if (!cp_parser_require (parser, type: CPP_SEMICOLON, token_desc: RT_SEMICOLON))
43230 goto saw_error;
43231
43232 if (!cp_parser_require (parser, type: CPP_CLOSE_BRACE, token_desc: RT_CLOSE_BRACE))
43233 goto saw_error;
43234
43235 extra_scope = false;
43236 code = OMP_ATOMIC_CAPTURE_OLD;
43237 if (r == NULL_TREE)
43238 /* Signal to c_finish_omp_atomic that in
43239 if (x == e) { x = d; } else { v = x; }
43240 case the store to v should be conditional. */
43241 r = void_list_node;
43242 }
43243 else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
43244 {
43245 cp_parser_error (parser, gmsgid: "expected %<else%>");
43246 goto saw_error;
43247 }
43248 else if (code == OMP_ATOMIC_CAPTURE_NEW
43249 && r != NULL_TREE
43250 && v == NULL_TREE)
43251 code = OMP_ATOMIC;
43252 goto stmt_done;
43253 }
43254 lhs = cp_parser_unary_expression (parser);
43255 orig_lhs = lhs;
43256 switch (TREE_CODE (lhs))
43257 {
43258 case ERROR_MARK:
43259 goto saw_error;
43260
43261 case POSTINCREMENT_EXPR:
43262 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
43263 code = OMP_ATOMIC_CAPTURE_OLD;
43264 /* FALLTHROUGH */
43265 case PREINCREMENT_EXPR:
43266 lhs = TREE_OPERAND (lhs, 0);
43267 opcode = PLUS_EXPR;
43268 rhs = integer_one_node;
43269 if (compare)
43270 goto invalid_compare;
43271 break;
43272
43273 case POSTDECREMENT_EXPR:
43274 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
43275 code = OMP_ATOMIC_CAPTURE_OLD;
43276 /* FALLTHROUGH */
43277 case PREDECREMENT_EXPR:
43278 lhs = TREE_OPERAND (lhs, 0);
43279 opcode = MINUS_EXPR;
43280 rhs = integer_one_node;
43281 if (compare)
43282 goto invalid_compare;
43283 break;
43284
43285 case COMPOUND_EXPR:
43286 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
43287 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
43288 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
43289 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
43290 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
43291 (TREE_OPERAND (lhs, 1), 0), 0)))
43292 == BOOLEAN_TYPE)
43293 /* Undo effects of boolean_increment for post {in,de}crement. */
43294 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
43295 /* FALLTHRU */
43296 case MODIFY_EXPR:
43297 if (TREE_CODE (lhs) == MODIFY_EXPR
43298 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
43299 {
43300 /* Undo effects of boolean_increment. */
43301 if (integer_onep (TREE_OPERAND (lhs, 1)))
43302 {
43303 /* This is pre or post increment. */
43304 rhs = TREE_OPERAND (lhs, 1);
43305 lhs = TREE_OPERAND (lhs, 0);
43306 opcode = NOP_EXPR;
43307 if (code == OMP_ATOMIC_CAPTURE_NEW
43308 && !structured_block
43309 && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
43310 code = OMP_ATOMIC_CAPTURE_OLD;
43311 if (compare)
43312 goto invalid_compare;
43313 break;
43314 }
43315 }
43316 /* FALLTHRU */
43317 default:
43318 if (compare && !cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_EQ))
43319 {
43320 cp_parser_error (parser, gmsgid: "expected %<=%>");
43321 goto saw_error;
43322 }
43323 switch (cp_lexer_peek_token (lexer: parser->lexer)->type)
43324 {
43325 case CPP_MULT_EQ:
43326 opcode = MULT_EXPR;
43327 break;
43328 case CPP_DIV_EQ:
43329 opcode = TRUNC_DIV_EXPR;
43330 break;
43331 case CPP_PLUS_EQ:
43332 opcode = PLUS_EXPR;
43333 break;
43334 case CPP_MINUS_EQ:
43335 opcode = MINUS_EXPR;
43336 break;
43337 case CPP_LSHIFT_EQ:
43338 opcode = LSHIFT_EXPR;
43339 break;
43340 case CPP_RSHIFT_EQ:
43341 opcode = RSHIFT_EXPR;
43342 break;
43343 case CPP_AND_EQ:
43344 opcode = BIT_AND_EXPR;
43345 break;
43346 case CPP_OR_EQ:
43347 opcode = BIT_IOR_EXPR;
43348 break;
43349 case CPP_XOR_EQ:
43350 opcode = BIT_XOR_EXPR;
43351 break;
43352 case CPP_EQ:
43353 enum cp_parser_prec oprec;
43354 cp_token *token;
43355 cp_lexer_consume_token (lexer: parser->lexer);
43356 cp_parser_parse_tentatively (parser);
43357 rhs1 = cp_parser_simple_cast_expression (parser);
43358 if (rhs1 == error_mark_node)
43359 {
43360 cp_parser_abort_tentative_parse (parser);
43361 cp_parser_simple_cast_expression (parser);
43362 goto saw_error;
43363 }
43364 token = cp_lexer_peek_token (lexer: parser->lexer);
43365 if (token->type != CPP_SEMICOLON
43366 && (!compare || token->type != CPP_QUERY)
43367 && !cp_tree_equal (lhs, rhs1))
43368 {
43369 cp_parser_abort_tentative_parse (parser);
43370 cp_parser_parse_tentatively (parser);
43371 rhs = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: true,
43372 prec: PREC_NOT_OPERATOR, NULL);
43373 if (rhs == error_mark_node)
43374 {
43375 cp_parser_abort_tentative_parse (parser);
43376 cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: true,
43377 prec: PREC_NOT_OPERATOR, NULL);
43378 goto saw_error;
43379 }
43380 switch (TREE_CODE (rhs))
43381 {
43382 case MULT_EXPR:
43383 case TRUNC_DIV_EXPR:
43384 case RDIV_EXPR:
43385 case PLUS_EXPR:
43386 case MINUS_EXPR:
43387 case LSHIFT_EXPR:
43388 case RSHIFT_EXPR:
43389 case BIT_AND_EXPR:
43390 case BIT_IOR_EXPR:
43391 case BIT_XOR_EXPR:
43392 if (compare)
43393 break;
43394 if (cp_tree_equal (lhs, TREE_OPERAND (rhs, 1)))
43395 {
43396 if (cp_parser_parse_definitely (parser))
43397 {
43398 opcode = TREE_CODE (rhs);
43399 rhs1 = TREE_OPERAND (rhs, 0);
43400 rhs = TREE_OPERAND (rhs, 1);
43401 goto stmt_done;
43402 }
43403 else
43404 goto saw_error;
43405 }
43406 break;
43407 case EQ_EXPR:
43408 if (!compare
43409 || code != OMP_ATOMIC_CAPTURE_NEW
43410 || !structured_block
43411 || v
43412 || r)
43413 break;
43414 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON)
43415 && cp_lexer_nth_token_is_keyword (lexer: parser->lexer,
43416 n: 2, keyword: RID_IF))
43417 {
43418 if (cp_parser_parse_definitely (parser))
43419 {
43420 r = lhs;
43421 lhs = NULL_TREE;
43422 rhs1 = NULL_TREE;
43423 cp_lexer_consume_token (lexer: parser->lexer);
43424 goto restart;
43425 }
43426 }
43427 break;
43428 case GT_EXPR:
43429 case LT_EXPR:
43430 if (compare
43431 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_QUERY)
43432 && cp_tree_equal (lhs, TREE_OPERAND (rhs, 1))
43433 && cp_parser_parse_definitely (parser))
43434 {
43435 opcode = TREE_CODE (rhs);
43436 rhs1 = TREE_OPERAND (rhs, 0);
43437 rhs = TREE_OPERAND (rhs, 1);
43438 cond_expr:
43439 cp_lexer_consume_token (lexer: parser->lexer);
43440 bool saved_colon_corrects_to_scope_p
43441 = parser->colon_corrects_to_scope_p;
43442 parser->colon_corrects_to_scope_p = false;
43443 tree e1 = cp_parser_expression (parser);
43444 parser->colon_corrects_to_scope_p
43445 = saved_colon_corrects_to_scope_p;
43446 cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON);
43447 tree e2 = cp_parser_simple_cast_expression (parser);
43448 if (cp_tree_equal (lhs, e2))
43449 {
43450 if (cp_tree_equal (lhs, rhs1))
43451 {
43452 if (opcode == EQ_EXPR)
43453 {
43454 opcode = COND_EXPR;
43455 rhs1 = e1;
43456 goto stmt_done;
43457 }
43458 if (cp_tree_equal (rhs, e1))
43459 {
43460 opcode
43461 = opcode == GT_EXPR ? MIN_EXPR : MAX_EXPR;
43462 rhs = e1;
43463 goto stmt_done;
43464 }
43465 }
43466 else
43467 {
43468 gcc_assert (opcode != EQ_EXPR);
43469 if (cp_tree_equal (rhs1, e1))
43470 {
43471 opcode
43472 = opcode == GT_EXPR ? MAX_EXPR : MIN_EXPR;
43473 rhs1 = rhs;
43474 rhs = e1;
43475 goto stmt_done;
43476 }
43477 }
43478 }
43479 cp_parser_error (parser,
43480 gmsgid: "invalid form of "
43481 "%<#pragma omp atomic compare%>");
43482 goto saw_error;
43483 }
43484 break;
43485 default:
43486 break;
43487 }
43488 cp_parser_abort_tentative_parse (parser);
43489 if (structured_block
43490 && code == OMP_ATOMIC_CAPTURE_OLD
43491 && !compare)
43492 {
43493 rhs = cp_parser_expression (parser);
43494 if (rhs == error_mark_node)
43495 goto saw_error;
43496 opcode = NOP_EXPR;
43497 rhs1 = NULL_TREE;
43498 goto stmt_done;
43499 }
43500 cp_parser_error (parser,
43501 gmsgid: "invalid form of %<#pragma omp atomic%>");
43502 goto saw_error;
43503 }
43504 if (!cp_parser_parse_definitely (parser))
43505 goto saw_error;
43506 switch (token->type)
43507 {
43508 case CPP_SEMICOLON:
43509 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
43510 {
43511 code = OMP_ATOMIC_CAPTURE_OLD;
43512 v = lhs;
43513 lhs = NULL_TREE;
43514 lhs1 = rhs1;
43515 rhs1 = NULL_TREE;
43516 cp_lexer_consume_token (lexer: parser->lexer);
43517 goto restart;
43518 }
43519 else if (structured_block && !compare)
43520 {
43521 opcode = NOP_EXPR;
43522 rhs = rhs1;
43523 rhs1 = NULL_TREE;
43524 goto stmt_done;
43525 }
43526 cp_parser_error (parser,
43527 gmsgid: "invalid form of %<#pragma omp atomic%>");
43528 goto saw_error;
43529 case CPP_MULT:
43530 opcode = MULT_EXPR;
43531 break;
43532 case CPP_DIV:
43533 opcode = TRUNC_DIV_EXPR;
43534 break;
43535 case CPP_PLUS:
43536 opcode = PLUS_EXPR;
43537 break;
43538 case CPP_MINUS:
43539 opcode = MINUS_EXPR;
43540 break;
43541 case CPP_LSHIFT:
43542 opcode = LSHIFT_EXPR;
43543 break;
43544 case CPP_RSHIFT:
43545 opcode = RSHIFT_EXPR;
43546 break;
43547 case CPP_AND:
43548 opcode = BIT_AND_EXPR;
43549 break;
43550 case CPP_OR:
43551 opcode = BIT_IOR_EXPR;
43552 break;
43553 case CPP_XOR:
43554 opcode = BIT_XOR_EXPR;
43555 break;
43556 case CPP_EQ_EQ:
43557 opcode = EQ_EXPR;
43558 break;
43559 case CPP_GREATER:
43560 opcode = GT_EXPR;
43561 break;
43562 case CPP_LESS:
43563 opcode = LT_EXPR;
43564 break;
43565 default:
43566 cp_parser_error (parser,
43567 gmsgid: "invalid operator for %<#pragma omp atomic%>");
43568 goto saw_error;
43569 }
43570 if (compare
43571 && TREE_CODE_CLASS (opcode) != tcc_comparison)
43572 {
43573 cp_parser_error (parser,
43574 gmsgid: "invalid form of "
43575 "%<#pragma omp atomic compare%>");
43576 goto saw_error;
43577 }
43578 oprec = TOKEN_PRECEDENCE (token);
43579 gcc_assert (oprec != PREC_NOT_OPERATOR);
43580 if (commutative_tree_code (opcode))
43581 oprec = (enum cp_parser_prec) (oprec - 1);
43582 cp_lexer_consume_token (lexer: parser->lexer);
43583 rhs = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: false,
43584 prec: oprec, NULL);
43585 if (rhs == error_mark_node)
43586 goto saw_error;
43587 if (compare)
43588 {
43589 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_QUERY))
43590 {
43591 cp_parser_error (parser,
43592 gmsgid: "invalid form of "
43593 "%<#pragma omp atomic compare%>");
43594 goto saw_error;
43595 }
43596 goto cond_expr;
43597 }
43598 goto stmt_done;
43599 default:
43600 cp_parser_error (parser,
43601 gmsgid: "invalid operator for %<#pragma omp atomic%>");
43602 goto saw_error;
43603 }
43604 cp_lexer_consume_token (lexer: parser->lexer);
43605
43606 rhs = cp_parser_expression (parser);
43607 if (rhs == error_mark_node)
43608 goto saw_error;
43609 break;
43610 }
43611stmt_done:
43612 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
43613 {
43614 if (!no_semicolon
43615 && !cp_parser_require (parser, type: CPP_SEMICOLON, token_desc: RT_SEMICOLON))
43616 goto saw_error;
43617 no_semicolon = false;
43618 v = cp_parser_unary_expression (parser);
43619 if (v == error_mark_node)
43620 goto saw_error;
43621 if (!cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ))
43622 goto saw_error;
43623 lhs1 = cp_parser_unary_expression (parser);
43624 if (lhs1 == error_mark_node)
43625 goto saw_error;
43626 }
43627 if (structured_block)
43628 {
43629 if (!no_semicolon)
43630 cp_parser_consume_semicolon_at_end_of_statement (parser);
43631 cp_parser_require (parser, type: CPP_CLOSE_BRACE, token_desc: RT_CLOSE_BRACE);
43632 }
43633done:
43634 if (weak && opcode != COND_EXPR)
43635 {
43636 error_at (loc, "%<weak%> clause requires atomic equality comparison");
43637 weak = false;
43638 }
43639 clauses = finish_omp_clauses (clauses, C_ORT_OMP);
43640 finish_omp_atomic (pragma_tok->location, code, opcode, lhs, rhs, v, lhs1,
43641 rhs1, r, clauses, memory_order, weak);
43642 if (!structured_block && !no_semicolon)
43643 cp_parser_consume_semicolon_at_end_of_statement (parser);
43644 return;
43645
43646 invalid_compare:
43647 error ("invalid form of %<pragma omp atomic compare%>");
43648 /* FALLTHRU */
43649 saw_error:
43650 cp_parser_skip_to_end_of_block_or_statement (parser);
43651 if (extra_scope && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
43652 cp_lexer_consume_token (lexer: parser->lexer);
43653 if (structured_block)
43654 {
43655 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
43656 cp_lexer_consume_token (lexer: parser->lexer);
43657 else if (code == OMP_ATOMIC_CAPTURE_NEW)
43658 {
43659 cp_parser_skip_to_end_of_block_or_statement (parser);
43660 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
43661 cp_lexer_consume_token (lexer: parser->lexer);
43662 }
43663 }
43664}
43665
43666
43667/* OpenMP 2.5:
43668 # pragma omp barrier new-line */
43669
43670static void
43671cp_parser_omp_barrier (cp_parser *parser, cp_token *pragma_tok)
43672{
43673 cp_parser_require_pragma_eol (parser, pragma_tok);
43674 finish_omp_barrier ();
43675}
43676
43677/* OpenMP 2.5:
43678 # pragma omp critical [(name)] new-line
43679 structured-block
43680
43681 OpenMP 4.5:
43682 # pragma omp critical [(name) [hint(expression)]] new-line
43683 structured-block */
43684
43685#define OMP_CRITICAL_CLAUSE_MASK \
43686 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
43687
43688static tree
43689cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
43690{
43691 tree stmt, name = NULL_TREE, clauses = NULL_TREE;
43692
43693 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
43694 {
43695 matching_parens parens;
43696 parens.consume_open (parser);
43697
43698 name = cp_parser_identifier (parser);
43699
43700 if (name == error_mark_node
43701 || !parens.require_close (parser))
43702 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
43703 /*or_comma=*/false,
43704 /*consume_paren=*/true);
43705 if (name == error_mark_node)
43706 name = NULL;
43707
43708 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
43709 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
43710 cp_lexer_consume_token (lexer: parser->lexer);
43711 }
43712
43713 clauses = cp_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
43714 where: "#pragma omp critical", pragma_tok);
43715
43716 stmt = cp_parser_omp_structured_block (parser, if_p);
43717 return c_finish_omp_critical (input_location, stmt, name, clauses);
43718}
43719
43720/* OpenMP 5.0:
43721 # pragma omp depobj ( depobj ) depobj-clause new-line
43722
43723 depobj-clause:
43724 depend (dependence-type : locator)
43725 destroy
43726 update (dependence-type)
43727
43728 OpenMP 5.2 additionally:
43729 destroy ( depobj )
43730
43731 dependence-type:
43732 in
43733 out
43734 inout
43735 mutexinout */
43736
43737static void
43738cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
43739{
43740 location_t loc = pragma_tok->location;
43741 matching_parens parens;
43742 if (!parens.require_open (parser))
43743 {
43744 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
43745 return;
43746 }
43747
43748 tree depobj = cp_parser_assignment_expression (parser);
43749
43750 if (!parens.require_close (parser))
43751 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
43752 /*or_comma=*/false,
43753 /*consume_paren=*/true);
43754
43755 tree clause = NULL_TREE;
43756 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
43757 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
43758 cp_lexer_consume_token (lexer: parser->lexer);
43759 location_t c_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
43760 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
43761 {
43762 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
43763 const char *p = IDENTIFIER_POINTER (id);
43764
43765 cp_lexer_consume_token (lexer: parser->lexer);
43766 if (!strcmp (s1: "depend", s2: p))
43767 {
43768 /* Don't create location wrapper nodes within the depend clause. */
43769 auto_suppress_location_wrappers sentinel;
43770 clause = cp_parser_omp_clause_depend (parser, NULL_TREE, loc: c_loc);
43771 if (clause)
43772 clause = finish_omp_clauses (clause, C_ORT_OMP);
43773 if (!clause)
43774 clause = error_mark_node;
43775 }
43776 else if (!strcmp (s1: "destroy", s2: p))
43777 {
43778 kind = OMP_CLAUSE_DEPEND_LAST;
43779 matching_parens c_parens;
43780 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN)
43781 && c_parens.require_open (parser))
43782 {
43783 tree destobj = cp_parser_assignment_expression (parser);
43784 if (depobj != error_mark_node
43785 && destobj != error_mark_node
43786 && !operand_equal_p (destobj, depobj, flags: OEP_MATCH_SIDE_EFFECTS
43787 | OEP_LEXICOGRAPHIC))
43788 warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
43789 "the %<destroy%> expression %qE should be the same "
43790 "as the %<depobj%> argument %qE", destobj, depobj);
43791 if (!c_parens.require_close (parser))
43792 cp_parser_skip_to_closing_parenthesis (parser,
43793 /*recovering=*/true,
43794 /*or_comma=*/false,
43795 /*consume_paren=*/true);
43796 }
43797 }
43798 else if (!strcmp (s1: "update", s2: p))
43799 {
43800 matching_parens c_parens;
43801 if (c_parens.require_open (parser))
43802 {
43803 location_t c2_loc
43804 = cp_lexer_peek_token (lexer: parser->lexer)->location;
43805 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
43806 {
43807 tree id2 = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
43808 const char *p2 = IDENTIFIER_POINTER (id2);
43809
43810 cp_lexer_consume_token (lexer: parser->lexer);
43811 if (!strcmp (s1: "in", s2: p2))
43812 kind = OMP_CLAUSE_DEPEND_IN;
43813 else if (!strcmp (s1: "out", s2: p2))
43814 kind = OMP_CLAUSE_DEPEND_OUT;
43815 else if (!strcmp (s1: "inout", s2: p2))
43816 kind = OMP_CLAUSE_DEPEND_INOUT;
43817 else if (!strcmp (s1: "mutexinoutset", s2: p2))
43818 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
43819 else if (!strcmp (s1: "inoutset", s2: p2))
43820 kind = OMP_CLAUSE_DEPEND_INOUTSET;
43821 }
43822 if (kind == OMP_CLAUSE_DEPEND_INVALID)
43823 {
43824 clause = error_mark_node;
43825 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
43826 "%<mutexinoutset%> or %<inoutset%>");
43827 }
43828 if (!c_parens.require_close (parser))
43829 cp_parser_skip_to_closing_parenthesis (parser,
43830 /*recovering=*/true,
43831 /*or_comma=*/false,
43832 /*consume_paren=*/true);
43833 }
43834 else
43835 clause = error_mark_node;
43836 }
43837 }
43838 if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
43839 {
43840 clause = error_mark_node;
43841 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
43842 }
43843 cp_parser_require_pragma_eol (parser, pragma_tok);
43844
43845 finish_omp_depobj (loc, depobj, kind, clause);
43846}
43847
43848
43849/* OpenMP 2.5:
43850 # pragma omp flush flush-vars[opt] new-line
43851
43852 flush-vars:
43853 ( variable-list )
43854
43855 OpenMP 5.0:
43856 # pragma omp flush memory-order-clause new-line */
43857
43858static void
43859cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
43860{
43861 enum memmodel mo = MEMMODEL_LAST;
43862 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
43863 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
43864 cp_lexer_consume_token (lexer: parser->lexer);
43865 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
43866 {
43867 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
43868 const char *p = IDENTIFIER_POINTER (id);
43869 if (!strcmp (s1: p, s2: "seq_cst"))
43870 mo = MEMMODEL_SEQ_CST;
43871 else if (!strcmp (s1: p, s2: "acq_rel"))
43872 mo = MEMMODEL_ACQ_REL;
43873 else if (!strcmp (s1: p, s2: "release"))
43874 mo = MEMMODEL_RELEASE;
43875 else if (!strcmp (s1: p, s2: "acquire"))
43876 mo = MEMMODEL_ACQUIRE;
43877 else
43878 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
43879 "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
43880 "%<acquire%>");
43881 cp_lexer_consume_token (lexer: parser->lexer);
43882 }
43883 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
43884 {
43885 if (mo != MEMMODEL_LAST)
43886 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
43887 "%<flush%> list specified together with memory order "
43888 "clause");
43889 (void) cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_ERROR, NULL);
43890 }
43891 cp_parser_require_pragma_eol (parser, pragma_tok);
43892
43893 finish_omp_flush (mo);
43894}
43895
43896/* Helper function, to parse omp for increment expression. */
43897
43898static tree
43899cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
43900{
43901 tree cond = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: true,
43902 prec: PREC_NOT_OPERATOR, NULL);
43903 if (cond == error_mark_node
43904 || cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
43905 {
43906 cp_parser_skip_to_end_of_statement (parser);
43907 return error_mark_node;
43908 }
43909
43910 switch (TREE_CODE (cond))
43911 {
43912 case GT_EXPR:
43913 case GE_EXPR:
43914 case LT_EXPR:
43915 case LE_EXPR:
43916 break;
43917 case NE_EXPR:
43918 if (code != OACC_LOOP)
43919 break;
43920 gcc_fallthrough ();
43921 default:
43922 return error_mark_node;
43923 }
43924
43925 /* If decl is an iterator, preserve LHS and RHS of the relational
43926 expr until finish_omp_for. */
43927 if (decl
43928 && (type_dependent_expression_p (decl)
43929 || CLASS_TYPE_P (TREE_TYPE (decl))))
43930 return cond;
43931
43932 return build_x_binary_op (cp_expr_loc_or_input_loc (t: cond),
43933 TREE_CODE (cond),
43934 TREE_OPERAND (cond, 0), ERROR_MARK,
43935 TREE_OPERAND (cond, 1), ERROR_MARK,
43936 NULL_TREE, /*overload=*/NULL, tf_warning_or_error);
43937}
43938
43939/* Helper function, to parse omp for increment expression. */
43940
43941static tree
43942cp_parser_omp_for_incr (cp_parser *parser, tree decl)
43943{
43944 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
43945 enum tree_code op;
43946 tree lhs, rhs;
43947 cp_id_kind idk;
43948 bool decl_first;
43949
43950 if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
43951 {
43952 op = (token->type == CPP_PLUS_PLUS
43953 ? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
43954 cp_lexer_consume_token (lexer: parser->lexer);
43955 lhs = cp_parser_simple_cast_expression (parser);
43956 if (lhs != decl
43957 && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
43958 return error_mark_node;
43959 return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
43960 }
43961
43962 lhs = cp_parser_primary_expression (parser, address_p: false, cast_p: false, template_arg_p: false, idk: &idk);
43963 if (lhs != decl
43964 && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
43965 return error_mark_node;
43966
43967 token = cp_lexer_peek_token (lexer: parser->lexer);
43968 if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
43969 {
43970 op = (token->type == CPP_PLUS_PLUS
43971 ? POSTINCREMENT_EXPR : POSTDECREMENT_EXPR);
43972 cp_lexer_consume_token (lexer: parser->lexer);
43973 return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
43974 }
43975
43976 op = cp_parser_assignment_operator_opt (parser);
43977 if (op == ERROR_MARK)
43978 return error_mark_node;
43979
43980 if (op != NOP_EXPR)
43981 {
43982 rhs = cp_parser_assignment_expression (parser);
43983 rhs = build2 (op, TREE_TYPE (decl), decl, rhs);
43984 return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
43985 }
43986
43987 lhs = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: false,
43988 prec: PREC_ADDITIVE_EXPRESSION, NULL);
43989 token = cp_lexer_peek_token (lexer: parser->lexer);
43990 decl_first = (lhs == decl
43991 || (processing_template_decl && cp_tree_equal (lhs, decl)));
43992 if (decl_first)
43993 lhs = NULL_TREE;
43994 if (token->type != CPP_PLUS
43995 && token->type != CPP_MINUS)
43996 return error_mark_node;
43997
43998 do
43999 {
44000 op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
44001 cp_lexer_consume_token (lexer: parser->lexer);
44002 rhs = cp_parser_binary_expression (parser, cast_p: false, no_toplevel_fold_p: false,
44003 prec: PREC_ADDITIVE_EXPRESSION, NULL);
44004 token = cp_lexer_peek_token (lexer: parser->lexer);
44005 if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
44006 {
44007 if (lhs == NULL_TREE)
44008 {
44009 if (op == PLUS_EXPR)
44010 lhs = rhs;
44011 else
44012 lhs = build_x_unary_op (input_location, NEGATE_EXPR, rhs,
44013 NULL_TREE, tf_warning_or_error);
44014 }
44015 else
44016 lhs = build_x_binary_op (input_location, op,
44017 lhs, ERROR_MARK,
44018 rhs, ERROR_MARK,
44019 NULL_TREE, NULL, tf_warning_or_error);
44020 }
44021 }
44022 while (token->type == CPP_PLUS || token->type == CPP_MINUS);
44023
44024 if (!decl_first)
44025 {
44026 if ((rhs != decl
44027 && (!processing_template_decl || !cp_tree_equal (rhs, decl)))
44028 || op == MINUS_EXPR)
44029 return error_mark_node;
44030 rhs = build2 (op, TREE_TYPE (decl), lhs, decl);
44031 }
44032 else
44033 rhs = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, lhs);
44034
44035 return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
44036}
44037
44038/* Parse the initialization statement of an OpenMP for loop. Range-for
44039 is handled separately in cp_convert_omp_range_for.
44040
44041 On entry SL is the current statement list. Parsing of some forms
44042 of initialization pops this list and stores its contents in either INIT
44043 or THIS_PRE_BODY, and sets SL to null. Initialization for class
44044 iterators is added directly to SL and it is not popped until later.
44045
44046 On return, DECL is set if the initialization is by binding the
44047 iteration variable. If the initialization is by assignment, REAL_DECL
44048 is set to point to a variable in an outer scope. ORIG_INIT is set
44049 if the iteration variable is of class type; this is a copy saved for
44050 error checking in finish_omp_for.
44051
44052 Return true if the resulting construct should have an
44053 OMP_CLAUSE_PRIVATE added to it. */
44054
44055static tree
44056cp_parser_omp_for_loop_init (cp_parser *parser,
44057 tree &this_pre_body,
44058 tree &sl,
44059 tree &init,
44060 tree &orig_init,
44061 tree &decl,
44062 tree &real_decl)
44063{
44064 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_SEMICOLON))
44065 return NULL_TREE;
44066
44067 tree add_private_clause = NULL_TREE;
44068
44069 /* See 2.5.1 (in OpenMP 3.0, similar wording is in 2.5 standard too):
44070
44071 init-expr:
44072 var = lb
44073 integer-type var = lb
44074 random-access-iterator-type var = lb
44075 pointer-type var = lb
44076 */
44077 cp_decl_specifier_seq type_specifiers;
44078
44079 /* First, try to parse as an initialized declaration. See
44080 cp_parser_condition, from whence the bulk of this is copied. */
44081
44082 cp_parser_parse_tentatively (parser);
44083 cp_parser_type_specifier_seq (parser, flags: CP_PARSER_FLAGS_NONE,
44084 /*is_declaration=*/true,
44085 /*is_trailing_return=*/false,
44086 type_specifier_seq: &type_specifiers);
44087 if (cp_parser_parse_definitely (parser))
44088 {
44089 /* If parsing a type specifier seq succeeded, then this
44090 MUST be a initialized declaration. */
44091 tree asm_specification, attributes;
44092 cp_declarator *declarator;
44093
44094 declarator = cp_parser_declarator (parser,
44095 dcl_kind: CP_PARSER_DECLARATOR_NAMED,
44096 flags: CP_PARSER_FLAGS_NONE,
44097 /*ctor_dtor_or_conv_p=*/NULL,
44098 /*parenthesized_p=*/NULL,
44099 /*member_p=*/false,
44100 /*friend_p=*/false,
44101 /*static_p=*/false);
44102 attributes = cp_parser_attributes_opt (parser);
44103 asm_specification = cp_parser_asm_specification_opt (parser);
44104
44105 if (declarator == cp_error_declarator)
44106 cp_parser_skip_to_end_of_statement (parser);
44107
44108 else
44109 {
44110 tree pushed_scope, auto_node;
44111
44112 decl = start_decl (declarator, &type_specifiers,
44113 SD_INITIALIZED, attributes,
44114 /*prefix_attributes=*/NULL_TREE,
44115 &pushed_scope);
44116
44117 auto_node = type_uses_auto (TREE_TYPE (decl));
44118 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_EQ))
44119 {
44120 if (cp_lexer_next_token_is (lexer: parser->lexer,
44121 type: CPP_OPEN_PAREN))
44122 error ("parenthesized initialization is not allowed in "
44123 "OpenMP %<for%> loop");
44124 else
44125 /* Trigger an error. */
44126 cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ);
44127
44128 init = error_mark_node;
44129 cp_parser_skip_to_end_of_statement (parser);
44130 }
44131 else if (CLASS_TYPE_P (TREE_TYPE (decl))
44132 || type_dependent_expression_p (decl)
44133 || auto_node)
44134 {
44135 bool is_non_constant_init;
44136
44137 init = cp_parser_initializer (parser,
44138 /*is_direct_init=*/nullptr,
44139 non_constant_p: &is_non_constant_init);
44140
44141 if (auto_node)
44142 {
44143 TREE_TYPE (decl)
44144 = do_auto_deduction (TREE_TYPE (decl), init,
44145 auto_node);
44146
44147 if (!CLASS_TYPE_P (TREE_TYPE (decl))
44148 && !type_dependent_expression_p (decl))
44149 goto non_class;
44150 }
44151
44152 cp_finish_decl (decl, init, !is_non_constant_init,
44153 asm_specification,
44154 LOOKUP_ONLYCONVERTING);
44155 orig_init = init;
44156
44157 /* In the case of a class iterator, do not pop sl here.
44158 Both class initialization and finalization must happen in
44159 the enclosing init block scope. For now set the init
44160 expression to null; it'll be filled in properly in
44161 finish_omp_for before stuffing it in the OMP_FOR. */
44162 if (CLASS_TYPE_P (TREE_TYPE (decl)))
44163 init = NULL_TREE;
44164 else /* It is a parameterized type. */
44165 {
44166 init = pop_stmt_list (sl);
44167 sl = NULL_TREE;
44168 if (init && TREE_CODE (init) == STATEMENT_LIST)
44169 {
44170 tree_stmt_iterator i = tsi_start (t: init);
44171 /* Move lambda DECL_EXPRs to the enclosing block. */
44172 while (!tsi_end_p (i))
44173 {
44174 tree t = tsi_stmt (i);
44175 if (TREE_CODE (t) == DECL_EXPR
44176 && TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
44177 {
44178 tsi_delink (&i);
44179 add_stmt (t);
44180 continue;
44181 }
44182 break;
44183 }
44184 if (tsi_one_before_end_p (i))
44185 {
44186 tree t = tsi_stmt (i);
44187 tsi_delink (&i);
44188 free_stmt_list (init);
44189 init = t;
44190 }
44191 }
44192 }
44193 }
44194 else
44195 /* This is an initialized declaration of non-class,
44196 non-parameterized type iteration variable. */
44197 {
44198 /* Consume '='. */
44199 cp_lexer_consume_token (lexer: parser->lexer);
44200 init = cp_parser_assignment_expression (parser);
44201
44202 non_class:
44203 if (TYPE_REF_P (TREE_TYPE (decl)))
44204 init = error_mark_node;
44205 else
44206 cp_finish_decl (decl, NULL_TREE,
44207 /*init_const_expr_p=*/false,
44208 asm_specification,
44209 LOOKUP_ONLYCONVERTING);
44210 this_pre_body = pop_stmt_list (sl);
44211 sl = NULL_TREE;
44212 }
44213
44214 if (pushed_scope)
44215 pop_scope (pushed_scope);
44216 }
44217 }
44218 else
44219 {
44220 cp_id_kind idk;
44221 /* If parsing a type specifier sequence failed, then
44222 this MUST be a simple expression. */
44223 cp_parser_parse_tentatively (parser);
44224 decl = cp_parser_primary_expression (parser, address_p: false, cast_p: false,
44225 template_arg_p: false, idk: &idk);
44226 cp_token *last_tok = cp_lexer_peek_token (lexer: parser->lexer);
44227 if (!cp_parser_error_occurred (parser)
44228 && decl
44229 && (TREE_CODE (decl) == COMPONENT_REF
44230 || (TREE_CODE (decl) == SCOPE_REF && TREE_TYPE (decl))))
44231 {
44232 cp_parser_abort_tentative_parse (parser);
44233 cp_parser_parse_tentatively (parser);
44234 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
44235 tree name = cp_parser_id_expression (parser, /*template_p=*/template_keyword_p: false,
44236 /*check_dependency_p=*/true,
44237 /*template_p=*/NULL,
44238 /*declarator_p=*/false,
44239 /*optional_p=*/false);
44240 if (name != error_mark_node
44241 && last_tok == cp_lexer_peek_token (lexer: parser->lexer))
44242 {
44243 decl = cp_parser_lookup_name_simple (parser, name,
44244 location: token->location);
44245 if (TREE_CODE (decl) == FIELD_DECL)
44246 add_private_clause = omp_privatize_field (decl, false);
44247 }
44248 cp_parser_abort_tentative_parse (parser);
44249 cp_parser_parse_tentatively (parser);
44250 decl = cp_parser_primary_expression (parser, address_p: false, cast_p: false,
44251 template_arg_p: false, idk: &idk);
44252 }
44253 if (!cp_parser_error_occurred (parser)
44254 && decl
44255 && DECL_P (decl)
44256 && CLASS_TYPE_P (TREE_TYPE (decl)))
44257 {
44258 tree rhs;
44259
44260 cp_parser_parse_definitely (parser);
44261 cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ);
44262 rhs = cp_parser_assignment_expression (parser);
44263 orig_init = rhs;
44264 finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs),
44265 decl, NOP_EXPR,
44266 rhs, NULL_TREE,
44267 tf_warning_or_error));
44268 if (!add_private_clause)
44269 add_private_clause = decl;
44270 }
44271 else
44272 {
44273 decl = NULL;
44274 cp_parser_abort_tentative_parse (parser);
44275 init = cp_parser_expression (parser);
44276 if (init)
44277 {
44278 if (TREE_CODE (init) == MODIFY_EXPR
44279 || TREE_CODE (init) == MODOP_EXPR)
44280 real_decl = TREE_OPERAND (init, 0);
44281 }
44282 }
44283 this_pre_body = pop_stmt_list (sl);
44284 sl = NULL_TREE;
44285 }
44286 return add_private_clause;
44287}
44288
44289/* Helper for cp_parser_omp_loop_nest, handle one range-for loop
44290 including introducing new temporaries for the range start and end,
44291 doing auto deduction, and processing decomposition variables.
44292
44293 This function is also called from pt.cc during template instantiation.
44294 In that case SL is NULL_TREE, otherwise it is the current statement
44295 list. */
44296void
44297cp_convert_omp_range_for (tree &this_pre_body, tree &sl,
44298 tree &decl, tree &orig_decl, tree &init,
44299 tree &orig_init, tree &cond, tree &incr)
44300{
44301 tree begin, end, range_temp_decl = NULL_TREE;
44302 tree iter_type, begin_expr, end_expr;
44303 bool clear_has_value_expr = false;
44304
44305 if (processing_template_decl)
44306 {
44307 if (check_for_bare_parameter_packs (init))
44308 init = error_mark_node;
44309 if (!type_dependent_expression_p (init)
44310 /* do_auto_deduction doesn't mess with template init-lists. */
44311 && !BRACE_ENCLOSED_INITIALIZER_P (init))
44312 {
44313 tree d = decl;
44314 cp_decomp decomp_d, *decomp = NULL;
44315 if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
44316 {
44317 tree v = DECL_VALUE_EXPR (decl);
44318 if (TREE_CODE (v) == ARRAY_REF
44319 && VAR_P (TREE_OPERAND (v, 0))
44320 && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
44321 {
44322 d = TREE_OPERAND (v, 0);
44323 decomp = &decomp_d;
44324 decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
44325 decomp->decl = decl;
44326 }
44327 }
44328 do_range_for_auto_deduction (decl: d, range_expr: init, decomp);
44329 }
44330 cond = global_namespace;
44331 incr = NULL_TREE;
44332 orig_init = init;
44333 if (sl)
44334 {
44335 this_pre_body = pop_stmt_list (sl);
44336 sl = NULL_TREE;
44337 }
44338 return;
44339 }
44340
44341 init = mark_lvalue_use (init);
44342
44343 if (decl == error_mark_node || init == error_mark_node)
44344 /* If an error happened previously do nothing or else a lot of
44345 unhelpful errors would be issued. */
44346 begin_expr = end_expr = iter_type = error_mark_node;
44347 else
44348 {
44349 tree range_temp;
44350
44351 if (VAR_P (init)
44352 && array_of_runtime_bound_p (TREE_TYPE (init)))
44353 /* Can't bind a reference to an array of runtime bound. */
44354 range_temp = init;
44355 else
44356 {
44357 range_temp = build_range_temp (range_expr: init);
44358 DECL_NAME (range_temp) = NULL_TREE;
44359 pushdecl (range_temp);
44360 cp_finish_decl (range_temp, init,
44361 /*is_constant_init*/false, NULL_TREE,
44362 LOOKUP_ONLYCONVERTING);
44363 range_temp_decl = range_temp;
44364 range_temp = convert_from_reference (range_temp);
44365 }
44366 iter_type = cp_parser_perform_range_for_lookup (range: range_temp,
44367 begin: &begin_expr, end: &end_expr);
44368 }
44369
44370 tree end_iter_type = iter_type;
44371 if (cxx_dialect >= cxx17)
44372 end_iter_type = cv_unqualified (TREE_TYPE (end_expr));
44373 end = build_decl (input_location, VAR_DECL, NULL_TREE, end_iter_type);
44374 TREE_USED (end) = 1;
44375 DECL_ARTIFICIAL (end) = 1;
44376 pushdecl (end);
44377 cp_finish_decl (end, end_expr,
44378 /*is_constant_init*/false, NULL_TREE,
44379 LOOKUP_ONLYCONVERTING);
44380
44381 /* The new for initialization statement. */
44382 begin = build_decl (input_location, VAR_DECL, NULL_TREE, iter_type);
44383 TREE_USED (begin) = 1;
44384 DECL_ARTIFICIAL (begin) = 1;
44385 pushdecl (begin);
44386 orig_init = init;
44387 if (CLASS_TYPE_P (iter_type))
44388 init = NULL_TREE;
44389 else
44390 {
44391 init = begin_expr;
44392 begin_expr = NULL_TREE;
44393 }
44394 cp_finish_decl (begin, begin_expr,
44395 /*is_constant_init*/false, NULL_TREE,
44396 LOOKUP_ONLYCONVERTING);
44397
44398 /* The new for condition. */
44399 if (CLASS_TYPE_P (iter_type))
44400 cond = build2 (NE_EXPR, boolean_type_node, begin, end);
44401 else
44402 cond = build_x_binary_op (input_location, NE_EXPR,
44403 begin, ERROR_MARK,
44404 end, ERROR_MARK,
44405 NULL_TREE, NULL, tf_warning_or_error);
44406
44407 /* The new increment expression. */
44408 if (CLASS_TYPE_P (iter_type))
44409 incr = build2 (PREINCREMENT_EXPR, iter_type, begin, NULL_TREE);
44410 else
44411 incr = finish_unary_op_expr (input_location,
44412 PREINCREMENT_EXPR, begin,
44413 tf_warning_or_error);
44414
44415 orig_decl = decl;
44416 decl = begin;
44417 /* Defer popping sl here. */
44418
44419 cp_decomp decomp_d, *decomp = NULL;
44420 if (orig_decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (orig_decl))
44421 {
44422 tree v = DECL_VALUE_EXPR (orig_decl);
44423 if (TREE_CODE (v) == ARRAY_REF
44424 && VAR_P (TREE_OPERAND (v, 0))
44425 && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
44426 {
44427 tree d = orig_decl;
44428 orig_decl = TREE_OPERAND (v, 0);
44429 decomp = &decomp_d;
44430 decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
44431 decomp->decl = d;
44432 }
44433 }
44434
44435 tree auto_node = type_uses_auto (TREE_TYPE (orig_decl));
44436 if (auto_node)
44437 {
44438 tree t = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
44439 NULL_TREE, tf_none);
44440 if (!error_operand_p (t))
44441 {
44442 TREE_TYPE (orig_decl) = do_auto_deduction (TREE_TYPE (orig_decl),
44443 t, auto_node);
44444 if (decomp)
44445 {
44446 ++processing_template_decl;
44447 cp_finish_decomp (orig_decl, decomp);
44448 --processing_template_decl;
44449 if (!processing_template_decl)
44450 clear_has_value_expr = true;
44451 }
44452 }
44453 }
44454
44455 /* The output ORIG_DECL is not a decl. Instead, it is a tree structure
44456 that holds decls for variables implementing the iterator, represented
44457 as a TREE_LIST whose TREE_CHAIN is a vector. The first two elements
44458 of the vector are decls of scratch variables for the range start and
44459 end that will eventually be bound in the implicit scope surrounding
44460 the whole loop nest. The remaining elements are decls of derived
44461 decomposition variables that are bound inside the loop body. This
44462 structure is further mangled by finish_omp_for into the form required
44463 for the OMP_FOR_ORIG_DECLS field of the OMP_FOR tree node. */\
44464 unsigned decomp_cnt = decomp ? decomp->count : 0;
44465 tree v = make_tree_vec (decomp_cnt + 3);
44466 TREE_VEC_ELT (v, 0) = range_temp_decl;
44467 TREE_VEC_ELT (v, 1) = end;
44468 TREE_VEC_ELT (v, 2) = orig_decl;
44469 if (clear_has_value_expr)
44470 TREE_PUBLIC (v) = 1;
44471 for (unsigned i = 0; i < decomp_cnt; i++)
44472 {
44473 if (clear_has_value_expr)
44474 {
44475 /* If cp_finish_decomp was called with processing_template_decl
44476 temporarily set to 1, then decomp names will have deduced
44477 name but the DECL_VALUE_EXPR will be dependent. Hide those
44478 from folding of other loop initializers e.g. for warning
44479 purposes until cp_finish_omp_range_for. */
44480 gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (decomp->decl)
44481 || (TREE_TYPE (decomp->decl)
44482 == error_mark_node));
44483 DECL_HAS_VALUE_EXPR_P (decomp->decl) = 0;
44484 }
44485 TREE_VEC_ELT (v, i + 3) = decomp->decl;
44486 decomp->decl = DECL_CHAIN (decomp->decl);
44487 }
44488 orig_decl = tree_cons (NULL_TREE, NULL_TREE, v);
44489}
44490
44491/* Helper for cp_parser_omp_for_loop, finalize part of range for
44492 inside of the collapsed body. */
44493
44494void
44495cp_finish_omp_range_for (tree orig, tree begin)
44496{
44497 gcc_assert (TREE_CODE (orig) == TREE_LIST
44498 && TREE_CODE (TREE_CHAIN (orig)) == TREE_VEC);
44499 tree decl = TREE_VEC_ELT (TREE_CHAIN (orig), 2);
44500 cp_decomp decomp_d, *decomp = NULL;
44501
44502 if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
44503 {
44504 decomp = &decomp_d;
44505 decomp_d.decl = TREE_VEC_ELT (TREE_CHAIN (orig), 3);
44506 decomp_d.count = TREE_VEC_LENGTH (TREE_CHAIN (orig)) - 3;
44507 if (TREE_PUBLIC (TREE_CHAIN (orig)))
44508 {
44509 /* Undo temporary clearing of DECL_HAS_VALUE_EXPR_P done
44510 by cp_convert_omp_range_for above. */
44511 TREE_PUBLIC (TREE_CHAIN (orig)) = 0;
44512 tree d = decomp_d.decl;
44513 for (unsigned i = 0; i < decomp_d.count; i++)
44514 {
44515 if (TREE_TYPE (d) != error_mark_node)
44516 DECL_HAS_VALUE_EXPR_P (d) = 1;
44517 d = DECL_CHAIN (d);
44518 }
44519 }
44520 }
44521
44522 /* The declaration is initialized with *__begin inside the loop body. */
44523 cp_finish_decl (decl,
44524 build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
44525 NULL_TREE, tf_warning_or_error),
44526 /*is_constant_init*/false, NULL_TREE,
44527 LOOKUP_ONLYCONVERTING, decomp);
44528 if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
44529 cp_finish_decomp (decl, decomp);
44530}
44531
44532/* Return true if next tokens contain a standard attribute that contains
44533 omp::directive (DIRECTIVE). */
44534
44535static bool
44536cp_parser_omp_section_scan (cp_parser *parser, const char *directive,
44537 bool tentative)
44538{
44539 size_t n = cp_parser_skip_attributes_opt (parser, n: 1), i;
44540 if (n < 10)
44541 return false;
44542 for (i = 5; i < n - 4; i++)
44543 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: i, type: CPP_NAME)
44544 && cp_lexer_nth_token_is (lexer: parser->lexer, n: i + 1, type: CPP_OPEN_PAREN)
44545 && cp_lexer_nth_token_is (lexer: parser->lexer, n: i + 2, type: CPP_NAME))
44546 {
44547 tree first = cp_lexer_peek_nth_token (lexer: parser->lexer, n: i)->u.value;
44548 tree second = cp_lexer_peek_nth_token (lexer: parser->lexer, n: i + 2)->u.value;
44549 if (strcmp (IDENTIFIER_POINTER (first), s2: "directive")
44550 && strcmp (IDENTIFIER_POINTER (first), s2: "__directive__"))
44551 continue;
44552 if (strcmp (IDENTIFIER_POINTER (second), s2: directive) == 0)
44553 break;
44554 }
44555 if (i == n - 4)
44556 return false;
44557 cp_parser_parse_tentatively (parser);
44558 location_t first_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
44559 location_t last_loc
44560 = cp_lexer_peek_nth_token (lexer: parser->lexer, n: n - 1)->location;
44561 location_t middle_loc = UNKNOWN_LOCATION;
44562 tree std_attrs = cp_parser_std_attribute_spec_seq (parser);
44563 int cnt = 0;
44564 bool seen = false;
44565 for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
44566 if (get_attribute_namespace (attr) == omp_identifier
44567 && is_attribute_p (attr_name: "directive", ident: get_attribute_name (attr)))
44568 {
44569 for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
44570 {
44571 tree d = TREE_VALUE (a);
44572 gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
44573 cp_token *first = DEFPARSE_TOKENS (d)->first;
44574 cnt++;
44575 if (first->type == CPP_NAME
44576 && strcmp (IDENTIFIER_POINTER (first->u.value),
44577 s2: directive) == 0)
44578 {
44579 seen = true;
44580 if (middle_loc == UNKNOWN_LOCATION)
44581 middle_loc = first->location;
44582 }
44583 }
44584 }
44585 if (!seen || tentative)
44586 {
44587 cp_parser_abort_tentative_parse (parser);
44588 return seen;
44589 }
44590 if (cnt != 1 || TREE_CHAIN (std_attrs))
44591 {
44592 error_at (make_location (caret: first_loc, start: last_loc, finish: middle_loc),
44593 "%<[[omp::directive(%s)]]%> must be the only specified "
44594 "attribute on a statement", directive);
44595 cp_parser_abort_tentative_parse (parser);
44596 return false;
44597 }
44598 if (!cp_parser_parse_definitely (parser))
44599 return false;
44600 cp_parser_handle_statement_omp_attributes (parser, attrs: std_attrs);
44601 return true;
44602}
44603
44604/* Parse an OpenMP structured block sequence. KIND is the corresponding
44605 separating directive. */
44606
44607static tree
44608cp_parser_omp_structured_block_sequence (cp_parser *parser,
44609 enum pragma_kind kind)
44610{
44611 tree stmt = begin_omp_structured_block ();
44612 unsigned int save = cp_parser_begin_omp_structured_block (parser);
44613
44614 cp_parser_statement (parser, NULL_TREE, in_compound: false, NULL);
44615 while (true)
44616 {
44617 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
44618
44619 if (token->type == CPP_CLOSE_BRACE
44620 || token->type == CPP_EOF
44621 || token->type == CPP_PRAGMA_EOL
44622 || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END)
44623 || (kind != PRAGMA_NONE
44624 && cp_parser_pragma_kind (token) == kind))
44625 break;
44626
44627 if (kind != PRAGMA_NONE
44628 && cp_parser_omp_section_scan (parser,
44629 directive: kind == PRAGMA_OMP_SCAN
44630 ? "scan" : "section", tentative: false))
44631 break;
44632
44633 cp_parser_statement (parser, NULL_TREE, in_compound: false, NULL);
44634 }
44635
44636 cp_parser_end_omp_structured_block (parser, save);
44637 return finish_omp_structured_block (stmt);
44638}
44639
44640
44641/* OpenMP 5.0:
44642
44643 scan-loop-body:
44644 { structured-block scan-directive structured-block } */
44645
44646static void
44647cp_parser_omp_scan_loop_body (cp_parser *parser)
44648{
44649 tree substmt, clauses = NULL_TREE;
44650 bool found_scan = false;
44651
44652 matching_braces braces;
44653 if (!braces.require_open (parser))
44654 return;
44655
44656 cp_token *tok = cp_lexer_peek_token (lexer: parser->lexer);
44657 if (cp_parser_pragma_kind (token: tok) != PRAGMA_OMP_SCAN)
44658 substmt = cp_parser_omp_structured_block_sequence (parser, kind: PRAGMA_OMP_SCAN);
44659 else
44660 {
44661 warning_at (tok->location, OPT_Wopenmp,
44662 "%<#pragma omp scan%> with zero preceding executable "
44663 "statements");
44664 substmt = build_empty_stmt (tok->location);
44665 }
44666 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
44667 add_stmt (substmt);
44668
44669 tok = cp_lexer_peek_token (lexer: parser->lexer);
44670 if (cp_parser_pragma_kind (token: tok) == PRAGMA_OMP_SCAN)
44671 {
44672 enum omp_clause_code clause = OMP_CLAUSE_ERROR;
44673 found_scan = true;
44674
44675 cp_lexer_consume_token (lexer: parser->lexer);
44676
44677 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
44678 cp_lexer_consume_token (lexer: parser->lexer);
44679
44680 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
44681 {
44682 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
44683 const char *p = IDENTIFIER_POINTER (id);
44684 if (strcmp (s1: p, s2: "inclusive") == 0)
44685 clause = OMP_CLAUSE_INCLUSIVE;
44686 else if (strcmp (s1: p, s2: "exclusive") == 0)
44687 clause = OMP_CLAUSE_EXCLUSIVE;
44688 }
44689 if (clause != OMP_CLAUSE_ERROR)
44690 {
44691 cp_lexer_consume_token (lexer: parser->lexer);
44692 clauses = cp_parser_omp_var_list (parser, kind: clause, NULL_TREE);
44693 }
44694 else
44695 cp_parser_error (parser, gmsgid: "expected %<inclusive%> or "
44696 "%<exclusive%> clause");
44697
44698 cp_parser_require_pragma_eol (parser, pragma_tok: tok);
44699 }
44700 else
44701 error ("expected %<#pragma omp scan%>");
44702
44703 clauses = finish_omp_clauses (clauses, C_ORT_OMP);
44704 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_BRACE))
44705 substmt = cp_parser_omp_structured_block_sequence (parser, kind: PRAGMA_NONE);
44706 else
44707 {
44708 if (found_scan)
44709 warning_at (tok->location, OPT_Wopenmp,
44710 "%<#pragma omp scan%> with zero succeeding executable "
44711 "statements");
44712 substmt = build_empty_stmt (tok->location);
44713 }
44714 substmt = build2_loc (loc: tok->location, code: OMP_SCAN, void_type_node, arg0: substmt,
44715 arg1: clauses);
44716 add_stmt (substmt);
44717
44718 braces.require_close (parser);
44719}
44720
44721
44722/* This function parses a single level of a loop nest, invoking itself
44723 recursively if necessary.
44724
44725 loop-nest :: for (...) loop-body
44726 loop-body :: loop-nest
44727 | { [intervening-code] loop-body [intervening-code] }
44728 | final-loop-body
44729 intervening-code :: structured-block-sequence
44730 final-loop-body :: structured-block
44731
44732 For a collapsed loop nest, only a single OMP_FOR is built, pulling out
44733 all the iterator information from the inner loops into vectors in the
44734 parser->omp_for_parse_state structure.
44735
44736 In the "range for" case, it is transformed into a regular "for" iterator
44737 by introducing some temporary variables for the begin/end,
44738 as well as bindings of the actual iteration variables which are
44739 injected into the body of the loop.
44740
44741 Initialization code for iterator variables may end up either in the
44742 init vector (simple assignments), in omp_for_parse_state->pre_body
44743 (decl_exprs for iterators bound in the for statement), or in the
44744 scope surrounding this level of loop initialization.
44745
44746 The scopes of class iterator variables and their finalizers need to
44747 be adjusted after parsing so that all of the initialization happens
44748 in a scope surrounding all of the intervening and body code. For
44749 this reason we separately store the initialization and body blocks
44750 for each level of loops in the omp_for_parse_state structure and
44751 reassemble/reorder them in cp_parser_omp_for. See additional
44752 comments there about the use of placeholders, etc. */
44753
44754static tree
44755cp_parser_omp_loop_nest (cp_parser *parser, bool *if_p)
44756{
44757 tree decl, cond, incr, init;
44758 tree orig_init, real_decl, orig_decl;
44759 tree init_block, body_block;
44760 tree init_placeholder, body_placeholder;
44761 tree init_scope;
44762 tree this_pre_body = NULL_TREE;
44763 bool moreloops;
44764 unsigned char save_in_statement;
44765 tree add_private_clause = NULL_TREE;
44766 location_t loc;
44767 bool is_range_for = false;
44768 tree sl = NULL_TREE;
44769 struct omp_for_parse_data *omp_for_parse_state
44770 = parser->omp_for_parse_state;
44771 gcc_assert (omp_for_parse_state);
44772 int depth = omp_for_parse_state->depth;
44773
44774 /* We have already matched the FOR token but not consumed it yet. */
44775 gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR));
44776 loc = cp_lexer_consume_token (lexer: parser->lexer)->location;
44777
44778 /* Forbid break/continue in the loop initializer, condition, and
44779 increment expressions. */
44780 save_in_statement = parser->in_statement;
44781 parser->in_statement = IN_OMP_BLOCK;
44782
44783 /* We are not in intervening code now. */
44784 omp_for_parse_state->in_intervening_code = false;
44785
44786 /* Don't create location wrapper nodes within an OpenMP "for"
44787 statement. */
44788 auto_suppress_location_wrappers sentinel;
44789
44790 matching_parens parens;
44791 if (!parens.require_open (parser))
44792 return NULL;
44793
44794 init = orig_init = decl = real_decl = orig_decl = NULL_TREE;
44795
44796 init_placeholder = build_stmt (input_location, EXPR_STMT,
44797 integer_zero_node);
44798 vec_safe_push (r&: omp_for_parse_state->init_placeholderv, t: init_placeholder);
44799
44800 /* The init_block acts as a container for this level of loop goo. */
44801 init_block = push_stmt_list ();
44802 vec_safe_push (r&: omp_for_parse_state->init_blockv, t: init_block);
44803
44804 /* Wrap a scope around this entire level of loop to hold bindings
44805 of loop iteration variables. We can't insert them directly
44806 in the containing scope because that would cause their visibility to
44807 be incorrect with respect to intervening code after this loop.
44808 We will combine the nested init_scopes in postprocessing after the
44809 entire loop is parsed. */
44810 init_scope = begin_compound_stmt (0);
44811
44812 /* Now we need another level of statement list container to capture the
44813 initialization (and possible finalization) bits. In some cases this
44814 container may be popped off during initializer parsing to store code in
44815 INIT or THIS_PRE_BODY, depending on the form of initialization. If
44816 we have a class iterator we will pop it at the end of parsing this
44817 level, so the cleanups are handled correctly. */
44818 sl = push_stmt_list ();
44819
44820 if (omp_for_parse_state->code != OACC_LOOP && cxx_dialect >= cxx11)
44821 {
44822 /* Save tokens so that we can put them back. */
44823 cp_lexer_save_tokens (lexer: parser->lexer);
44824
44825 /* Look for ':' that is not nested in () or {}. */
44826 is_range_for
44827 = (cp_parser_skip_to_closing_parenthesis_1 (parser,
44828 /*recovering=*/false,
44829 or_ttype: CPP_COLON,
44830 /*consume_paren=*/
44831 false) == -1);
44832
44833 /* Roll back the tokens we skipped. */
44834 cp_lexer_rollback_tokens (lexer: parser->lexer);
44835
44836 if (is_range_for)
44837 {
44838 bool saved_colon_corrects_to_scope_p
44839 = parser->colon_corrects_to_scope_p;
44840
44841 /* A colon is used in range-based for. */
44842 parser->colon_corrects_to_scope_p = false;
44843
44844 /* Parse the declaration. */
44845 cp_parser_simple_declaration (parser,
44846 /*function_definition_allowed_p=*/
44847 false, maybe_range_for_decl: &decl);
44848 parser->colon_corrects_to_scope_p
44849 = saved_colon_corrects_to_scope_p;
44850
44851 cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON);
44852
44853 init = cp_parser_range_for (parser, NULL_TREE, NULL_TREE, range_decl: decl,
44854 ivdep: false, NULL_TREE, novector: false, is_omp: true);
44855
44856 cp_convert_omp_range_for (this_pre_body, sl, decl,
44857 orig_decl, init, orig_init,
44858 cond, incr);
44859
44860 if (omp_for_parse_state->ordered_cl)
44861 error_at (OMP_CLAUSE_LOCATION (omp_for_parse_state->ordered_cl),
44862 "%<ordered%> clause with parameter on "
44863 "range-based %<for%> loop");
44864
44865 goto parse_close_paren;
44866 }
44867 }
44868
44869 add_private_clause
44870 = cp_parser_omp_for_loop_init (parser, this_pre_body, sl,
44871 init, orig_init, decl, real_decl);
44872
44873 cp_parser_require (parser, type: CPP_SEMICOLON, token_desc: RT_SEMICOLON);
44874
44875 /* If the iteration variable was introduced via a declaration in the
44876 for statement, DECL points at it. Otherwise DECL is null and
44877 REAL_DECL is a variable previously declared in an outer scope.
44878 Make REAL_DECL point at the iteration variable no matter where it
44879 was introduced. */
44880 if (decl)
44881 real_decl = decl;
44882
44883 /* Some clauses treat iterator variables specially. */
44884 if (omp_for_parse_state->cclauses != NULL
44885 && omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL
44886 && real_decl != NULL_TREE
44887 && omp_for_parse_state->code != OMP_LOOP)
44888 {
44889 tree *c;
44890 for (c = &(omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]);
44891 *c ; )
44892 if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE
44893 && OMP_CLAUSE_DECL (*c) == real_decl)
44894 {
44895 error_at (loc, "iteration variable %qD"
44896 " should not be firstprivate", real_decl);
44897 *c = OMP_CLAUSE_CHAIN (*c);
44898 }
44899 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_LASTPRIVATE
44900 && OMP_CLAUSE_DECL (*c) == real_decl)
44901 {
44902 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */
44903 tree l = *c;
44904 *c = OMP_CLAUSE_CHAIN (*c);
44905 if (omp_for_parse_state->code == OMP_SIMD)
44906 {
44907 OMP_CLAUSE_CHAIN (l)
44908 = omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_FOR];
44909 omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
44910 }
44911 else
44912 {
44913 OMP_CLAUSE_CHAIN (l) = omp_for_parse_state->clauses;
44914 omp_for_parse_state->clauses = l;
44915 }
44916 add_private_clause = NULL_TREE;
44917 }
44918 else
44919 {
44920 if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_PRIVATE
44921 && OMP_CLAUSE_DECL (*c) == real_decl)
44922 add_private_clause = NULL_TREE;
44923 c = &OMP_CLAUSE_CHAIN (*c);
44924 }
44925 }
44926
44927 if (add_private_clause)
44928 {
44929 tree c;
44930 for (c = omp_for_parse_state->clauses; c ; c = OMP_CLAUSE_CHAIN (c))
44931 {
44932 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
44933 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
44934 && OMP_CLAUSE_DECL (c) == decl)
44935 break;
44936 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
44937 && OMP_CLAUSE_DECL (c) == decl)
44938 error_at (loc, "iteration variable %qD "
44939 "should not be firstprivate",
44940 decl);
44941 else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
44942 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
44943 && OMP_CLAUSE_DECL (c) == decl)
44944 error_at (loc, "iteration variable %qD should not be reduction",
44945 decl);
44946 }
44947 if (c == NULL)
44948 {
44949 if ((omp_for_parse_state->code == OMP_SIMD
44950 && omp_for_parse_state->count != 1)
44951 || omp_for_parse_state->code == OMP_LOOP)
44952 c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
44953 else if (omp_for_parse_state->code != OMP_SIMD)
44954 c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
44955 else
44956 c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
44957 OMP_CLAUSE_DECL (c) = add_private_clause;
44958 c = finish_omp_clauses (c, C_ORT_OMP);
44959 if (c)
44960 {
44961 OMP_CLAUSE_CHAIN (c) = omp_for_parse_state->clauses;
44962 omp_for_parse_state->clauses = c;
44963 /* For linear, signal that we need to fill up
44964 the so far unknown linear step. */
44965 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
44966 OMP_CLAUSE_LINEAR_STEP (c) = NULL_TREE;
44967 }
44968 }
44969 }
44970
44971 cond = NULL;
44972 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_SEMICOLON))
44973 cond = cp_parser_omp_for_cond (parser, decl, code: omp_for_parse_state->code);
44974 cp_parser_require (parser, type: CPP_SEMICOLON, token_desc: RT_SEMICOLON);
44975
44976 incr = NULL;
44977 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_CLOSE_PAREN))
44978 {
44979 /* If decl is an iterator, preserve the operator on decl
44980 until finish_omp_for. */
44981 if (real_decl
44982 && ((processing_template_decl
44983 && (TREE_TYPE (real_decl) == NULL_TREE
44984 || !INDIRECT_TYPE_P (TREE_TYPE (real_decl))))
44985 || CLASS_TYPE_P (TREE_TYPE (real_decl))))
44986 incr = cp_parser_omp_for_incr (parser, decl: real_decl);
44987 else
44988 incr = cp_parser_expression (parser);
44989 protected_set_expr_location_if_unset (incr, input_location);
44990 }
44991
44992 parse_close_paren:
44993 if (!parens.require_close (parser))
44994 cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
44995 /*or_comma=*/false,
44996 /*consume_paren=*/true);
44997
44998 /* We've parsed all the for (...) stuff now. Store the bits. */
44999 TREE_VEC_ELT (omp_for_parse_state->declv, depth) = decl;
45000 TREE_VEC_ELT (omp_for_parse_state->initv, depth) = init;
45001 TREE_VEC_ELT (omp_for_parse_state->condv, depth) = cond;
45002 TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = incr;
45003 if (orig_init)
45004 {
45005 omp_for_parse_state->orig_inits.safe_grow_cleared (len: depth + 1, exact: true);
45006 omp_for_parse_state->orig_inits[depth] = orig_init;
45007 }
45008 if (orig_decl)
45009 {
45010 if (!omp_for_parse_state->orig_declv)
45011 omp_for_parse_state->orig_declv
45012 = copy_node (omp_for_parse_state->declv);
45013 TREE_VEC_ELT (omp_for_parse_state->orig_declv, depth) = orig_decl;
45014 }
45015 else if (omp_for_parse_state->orig_declv)
45016 TREE_VEC_ELT (omp_for_parse_state->orig_declv, depth) = decl;
45017 if (this_pre_body)
45018 append_to_statement_list_force (this_pre_body,
45019 &(omp_for_parse_state->pre_body));
45020
45021 /* Start a nested block for the loop body. */
45022 body_placeholder = build_stmt (input_location, EXPR_STMT,
45023 integer_zero_node);
45024 vec_safe_push (r&: omp_for_parse_state->body_placeholderv, t: body_placeholder);
45025 body_block = push_stmt_list ();
45026 vec_safe_push (r&: omp_for_parse_state->body_blockv, t: body_block);
45027
45028 moreloops = depth < omp_for_parse_state->count - 1;
45029 omp_for_parse_state->want_nested_loop = moreloops;
45030 if (moreloops && cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_FOR))
45031 {
45032 omp_for_parse_state->depth++;
45033 add_stmt (cp_parser_omp_loop_nest (parser, if_p));
45034 omp_for_parse_state->depth--;
45035 }
45036 else if (moreloops
45037 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_BRACE))
45038 {
45039 /* This is the open brace in the loop-body grammar production. Rather
45040 than trying to special-case braces, just parse it as a compound
45041 statement and handle the nested loop-body case there. Note that
45042 when we see a further open brace inside the compound statement
45043 loop-body, we don't know whether it is the start of intervening
45044 code that is a compound statement, or a level of braces
45045 surrounding a nested loop-body. Use the WANT_NESTED_LOOP state
45046 bit to ensure we have only one nested loop at each level. */
45047
45048 omp_for_parse_state->in_intervening_code = true;
45049 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_NORMAL, function_body: false);
45050 omp_for_parse_state->in_intervening_code = false;
45051
45052 if (omp_for_parse_state->want_nested_loop)
45053 {
45054 /* We have already parsed the whole loop body and not found a
45055 nested loop. */
45056 error_at (omp_for_parse_state->for_loc,
45057 "not enough nested loops");
45058 omp_for_parse_state->fail = true;
45059 }
45060 if_p = NULL;
45061 }
45062 else
45063 {
45064 /* This is the final-loop-body case in the grammar: we have something
45065 that is not a FOR and not an open brace. */
45066 if (moreloops)
45067 {
45068 /* If we were expecting a nested loop, give an error and mark
45069 that parsing has failed, and try to recover by parsing the
45070 body as regular code without further collapsing. */
45071 error_at (omp_for_parse_state->for_loc,
45072 "not enough nested loops");
45073 omp_for_parse_state->fail = true;
45074 }
45075 parser->in_statement = IN_OMP_FOR;
45076
45077 /* Generate the parts of range for that belong in the loop body,
45078 to be executed on every iteration. This includes setting the
45079 user-declared decomposition variables from the compiler-generated
45080 temporaries that are the real iteration variables for OMP_FOR.
45081 FIXME: Not sure if this is correct with respect to visibility
45082 of the variables from intervening code. However, putting this
45083 code in each level of loop instead of all around the innermost
45084 body also makes the decomposition variables visible to the
45085 inner for init/bound/step exressions, which is not supposed to
45086 happen and causes test failures. */
45087 if (omp_for_parse_state->orig_declv)
45088 for (int i = 0; i < omp_for_parse_state->count; i++)
45089 {
45090 tree o = TREE_VEC_ELT (omp_for_parse_state->orig_declv, i);
45091 tree d = TREE_VEC_ELT (omp_for_parse_state->declv, i);
45092 if (o != d)
45093 cp_finish_omp_range_for (orig: o, begin: d);
45094 }
45095
45096 /* Now parse the final-loop-body for the innermost loop. */
45097 parser->omp_for_parse_state = NULL;
45098 if (omp_for_parse_state->inscan)
45099 cp_parser_omp_scan_loop_body (parser);
45100 else
45101 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p);
45102 parser->omp_for_parse_state = omp_for_parse_state;
45103 }
45104 parser->in_statement = save_in_statement;
45105 omp_for_parse_state->want_nested_loop = false;
45106 omp_for_parse_state->in_intervening_code = true;
45107
45108 /* Pop and remember the body block. Add the body placeholder
45109 to the surrounding statement list instead. This is just a unique
45110 token that will be replaced when we reassemble the generated
45111 code for the entire omp for statement. */
45112 body_block = pop_stmt_list (body_block);
45113 omp_for_parse_state->body_blockv[depth] = body_block;
45114 add_stmt (body_placeholder);
45115
45116 /* Pop and remember the init block. */
45117 if (sl)
45118 add_stmt (pop_stmt_list (sl));
45119 finish_compound_stmt (init_scope);
45120 init_block = pop_stmt_list (init_block);
45121 omp_for_parse_state->init_blockv[depth] = init_block;
45122
45123 /* Return the init placeholder rather than the remembered init block.
45124 Again, this is just a unique cookie that will be used to reassemble
45125 code pieces when the entire omp for statement has been parsed. */
45126 return init_placeholder;
45127}
45128
45129/* Worker for find_structured_blocks. *TP points to a STATEMENT_LIST
45130 and ITER is the element that is or contains a nested loop. This
45131 function moves the statements before and after ITER into
45132 OMP_STRUCTURED_BLOCKs and modifies *TP. */
45133static void
45134insert_structured_blocks (tree *tp, tree_stmt_iterator iter)
45135{
45136 tree sl = push_stmt_list ();
45137 for (tree_stmt_iterator i = tsi_start (t: *tp); !tsi_end_p (i); )
45138 if (i == iter)
45139 {
45140 sl = pop_stmt_list (sl);
45141 if (TREE_CODE (sl) != STATEMENT_LIST || !tsi_end_p (i: tsi_start (t: sl)))
45142 tsi_link_before (&i,
45143 build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl),
45144 TSI_SAME_STMT);
45145 i++;
45146 sl = push_stmt_list ();
45147 }
45148 else
45149 {
45150 tree s = tsi_stmt (i);
45151 tsi_delink (&i); /* Advances i to next statement. */
45152 add_stmt (s);
45153 }
45154 sl = pop_stmt_list (sl);
45155 if (TREE_CODE (sl) != STATEMENT_LIST || !tsi_end_p (i: tsi_start (t: sl)))
45156 tsi_link_after (&iter,
45157 build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl),
45158 TSI_SAME_STMT);
45159}
45160
45161/* Helper to find and mark structured blocks in intervening code for a
45162 single loop level with markers for later error checking. *TP is the
45163 piece of code to be marked and INNER is the inner loop placeholder.
45164 Returns true if INNER was found (recursively) in *TP. */
45165static bool
45166find_structured_blocks (tree *tp, tree inner)
45167{
45168 if (*tp == inner)
45169 return true;
45170 else if (TREE_CODE (*tp) == BIND_EXPR)
45171 return find_structured_blocks (tp: &(BIND_EXPR_BODY (*tp)), inner);
45172 else if (TREE_CODE (*tp) == STATEMENT_LIST)
45173 {
45174 for (tree_stmt_iterator i = tsi_start (t: *tp); !tsi_end_p (i); ++i)
45175 {
45176 tree *p = tsi_stmt_ptr (i);
45177 /* The normal case is that there is no intervening code and we
45178 do not have to insert any OMP_STRUCTURED_BLOCK markers. */
45179 if (find_structured_blocks (tp: p, inner))
45180 {
45181 if (!(i == tsi_start (t: *tp) && i == tsi_last (t: *tp)))
45182 insert_structured_blocks (tp, iter: i);
45183 return true;
45184 }
45185 }
45186 return false;
45187 }
45188 else if (TREE_CODE (*tp) == TRY_FINALLY_EXPR)
45189 return find_structured_blocks (tp: &(TREE_OPERAND (*tp, 0)), inner);
45190 else if (TREE_CODE (*tp) == CLEANUP_STMT)
45191 return find_structured_blocks (tp: &(CLEANUP_BODY (*tp)), inner);
45192 else
45193 return false;
45194}
45195
45196/* Helpers used for relinking tree structures: In tree rooted at
45197 CONTEXT, replace ORIG with REPLACEMENT. If FLATTEN is true, try to combine
45198 nested BIND_EXPRs. Gives an assertion if it fails to find ORIG. */
45199
45200struct sit_data {
45201 tree orig;
45202 tree repl;
45203 bool flatten;
45204};
45205
45206static tree
45207substitute_in_tree_walker (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
45208 void *dp)
45209{
45210 struct sit_data *sit = (struct sit_data *)dp;
45211 if (*tp == sit->orig)
45212 {
45213 *tp = sit->repl;
45214 return *tp;
45215 }
45216 /* Remove redundant BIND_EXPRs with no bindings even when not specifically
45217 trying to flatten. */
45218 else if (TREE_CODE (*tp) == BIND_EXPR
45219 && BIND_EXPR_BODY (*tp) == sit->orig
45220 && !BIND_EXPR_VARS (*tp)
45221 && (sit->flatten || TREE_CODE (sit->repl) == BIND_EXPR))
45222 {
45223 *tp = sit->repl;
45224 return *tp;
45225 }
45226 else if (sit->flatten
45227 && TREE_CODE (*tp) == BIND_EXPR
45228 && TREE_CODE (sit->repl) == BIND_EXPR)
45229 {
45230 if (BIND_EXPR_BODY (*tp) == sit->orig)
45231 {
45232 /* Merge binding lists for two directly nested BIND_EXPRs,
45233 keeping the outer one. */
45234 BIND_EXPR_VARS (*tp) = chainon (BIND_EXPR_VARS (*tp),
45235 BIND_EXPR_VARS (sit->repl));
45236 BIND_EXPR_BODY (*tp) = BIND_EXPR_BODY (sit->repl);
45237 return *tp;
45238 }
45239 else if (TREE_CODE (BIND_EXPR_BODY (*tp)) == STATEMENT_LIST)
45240 /* There might be a statement list containing cleanup_points
45241 etc between the two levels of BIND_EXPR. We can still merge
45242 them, again keeping the outer BIND_EXPR. */
45243 for (tree_stmt_iterator i = tsi_start (BIND_EXPR_BODY (*tp));
45244 !tsi_end_p (i); ++i)
45245 {
45246 tree *p = tsi_stmt_ptr (i);
45247 if (*p == sit->orig)
45248 {
45249 BIND_EXPR_VARS (*tp) = chainon (BIND_EXPR_VARS (*tp),
45250 BIND_EXPR_VARS (sit->repl));
45251 *p = BIND_EXPR_BODY (sit->repl);
45252 return *tp;
45253 }
45254 }
45255 }
45256 return NULL;
45257}
45258
45259static void
45260substitute_in_tree (tree *context, tree orig, tree repl, bool flatten)
45261{
45262 struct sit_data data;
45263
45264 gcc_assert (*context && orig && repl);
45265 if (TREE_CODE (repl) == BIND_EXPR && !BIND_EXPR_VARS (repl))
45266 repl = BIND_EXPR_BODY (repl);
45267 data.orig = orig;
45268 data.repl = repl;
45269 data.flatten = flatten;
45270
45271 tree result = cp_walk_tree (context, substitute_in_tree_walker,
45272 (void *)&data, NULL);
45273 gcc_assert (result != NULL_TREE);
45274}
45275
45276/* Walker to patch up the BLOCK_NODE hierarchy after the above surgery.
45277 *DP is the parent block. */
45278
45279static tree
45280fixup_blocks_walker (tree *tp, int *walk_subtrees, void *dp)
45281{
45282 tree superblock = *(tree *)dp;
45283
45284 /* BIND_EXPR_BLOCK may be null if the expression is not a
45285 full-expression; if there's no block, no patching is necessary
45286 for this node. */
45287 if (TREE_CODE (*tp) == BIND_EXPR && BIND_EXPR_BLOCK (*tp))
45288 {
45289 tree block = BIND_EXPR_BLOCK (*tp);
45290 if (superblock)
45291 {
45292 BLOCK_SUPERCONTEXT (block) = superblock;
45293 BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (superblock);
45294 BLOCK_SUBBLOCKS (superblock) = block;
45295 }
45296 BLOCK_SUBBLOCKS (block) = NULL_TREE;
45297 cp_walk_tree (&BIND_EXPR_BODY (*tp), fixup_blocks_walker,
45298 (void *)&block, NULL);
45299 *walk_subtrees = 0;
45300 }
45301
45302 return NULL;
45303}
45304
45305/* Parse the restricted form of the for statement allowed by OpenMP. */
45306
45307static tree
45308cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
45309 tree *cclauses, bool *if_p)
45310{
45311 tree ret;
45312 tree cl, ordered_cl = NULL_TREE;
45313 int collapse = 1, ordered = 0;
45314 unsigned int count;
45315 bool tiling = false;
45316 bool inscan = false;
45317 struct omp_for_parse_data data;
45318 struct omp_for_parse_data *save_data = parser->omp_for_parse_state;
45319 tree result;
45320 location_t loc_first = cp_lexer_peek_token (lexer: parser->lexer)->location;
45321
45322 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
45323 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
45324 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
45325 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
45326 {
45327 tiling = true;
45328 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
45329 }
45330 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
45331 && OMP_CLAUSE_ORDERED_EXPR (cl))
45332 {
45333 ordered_cl = cl;
45334 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
45335 }
45336 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
45337 && OMP_CLAUSE_REDUCTION_INSCAN (cl)
45338 && (code == OMP_SIMD || code == OMP_FOR))
45339 inscan = true;
45340
45341 if (ordered && ordered < collapse)
45342 {
45343 error_at (OMP_CLAUSE_LOCATION (ordered_cl),
45344 "%<ordered%> clause parameter is less than %<collapse%>");
45345 OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
45346 = build_int_cst (NULL_TREE, collapse);
45347 ordered = collapse;
45348 }
45349
45350 gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
45351 count = ordered ? ordered : collapse;
45352
45353 if (!cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_FOR))
45354 {
45355 cp_parser_error (parser, gmsgid: "for statement expected");
45356 return NULL;
45357 }
45358
45359 /* Initialize parse state for recursive descent. */
45360 data.declv = make_tree_vec (count);
45361 data.initv = make_tree_vec (count);
45362 data.condv = make_tree_vec (count);
45363 data.incrv = make_tree_vec (count);
45364 data.pre_body = NULL_TREE;
45365 data.for_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
45366 data.count = count;
45367 data.depth = 0;
45368 data.want_nested_loop = true;
45369 data.ordered = ordered > 0;
45370 data.in_intervening_code = false;
45371 data.perfect_nesting_fail = false;
45372 data.fail = false;
45373 data.inscan = inscan;
45374 data.saw_intervening_code = false;
45375 data.code = code;
45376 data.orig_declv = NULL_TREE;
45377 data.clauses = clauses;
45378 data.cclauses = cclauses;
45379 data.ordered_cl = ordered_cl;
45380 parser->omp_for_parse_state = &data;
45381
45382 cp_parser_omp_loop_nest (parser, if_p);
45383
45384 /* Bomb out early if there was an error (not enough loops, etc). */
45385 if (data.fail || data.declv == NULL_TREE)
45386 {
45387 parser->omp_for_parse_state = save_data;
45388 return NULL_TREE;
45389 }
45390
45391 /* Relink the init and body blocks that were built during parsing. At
45392 this point we have a structure nested like
45393 init 0
45394 body 0
45395 init 1
45396 body 1
45397 init 2
45398 body 2
45399 and we want to turn it into
45400 init 0
45401 init 1
45402 init 2
45403 omp_for
45404 body 0
45405 body 1
45406 body 2
45407 We also need to flatten the init blocks, as some code for later
45408 processing of combined directives gets confused otherwise. */
45409
45410 gcc_assert (vec_safe_length (data.init_blockv) == count);
45411 gcc_assert (vec_safe_length (data.body_blockv) == count);
45412 gcc_assert (vec_safe_length (data.init_placeholderv) == count);
45413 gcc_assert (vec_safe_length (data.body_placeholderv) == count);
45414
45415 /* First insert markers for structured blocks for intervening code in
45416 the loop bodies. */
45417 for (unsigned int i = 0; i < count - 1; i++)
45418 {
45419 bool good = find_structured_blocks (tp: &(data.body_blockv[i]),
45420 inner: data.init_placeholderv[i+1]);
45421 gcc_assert (good);
45422 }
45423
45424 /* Do the substitution from the inside out. */
45425 for (unsigned int i = count - 1; i > 0; i--)
45426 {
45427 substitute_in_tree (context: &(data.body_blockv[i-1]),
45428 orig: data.init_placeholderv[i],
45429 repl: data.body_blockv[i], flatten: false);
45430 substitute_in_tree (context: &(data.init_blockv[i-1]),
45431 orig: data.body_placeholderv[i-1],
45432 repl: data.init_blockv[i], flatten: true);
45433 }
45434
45435 /* Generate the OMP_FOR. Note finish_omp_for adds the OMP_FOR
45436 (and possibly other stuff) to the current statement list but
45437 returns a pointer to the OMP_FOR itself, or null in case of error. */
45438 result = push_stmt_list ();
45439 ret = finish_omp_for (loc_first, code, data.declv, data.orig_declv,
45440 data.initv, data.condv, data.incrv,
45441 data.body_blockv[0],
45442 data.pre_body, &data.orig_inits, data.clauses);
45443 result = pop_stmt_list (result);
45444
45445 /* Check for errors involving lb/ub/incr expressions referencing
45446 variables declared in intervening code. */
45447 if (data.saw_intervening_code
45448 && !c_omp_check_loop_binding_exprs (ret, &data.orig_inits))
45449 ret = NULL_TREE;
45450
45451 if (ret)
45452 {
45453 /* Splice the omp_for into the nest of init blocks. */
45454 substitute_in_tree (context: &(data.init_blockv[0]),
45455 orig: data.body_placeholderv[count - 1],
45456 repl: result, flatten: true);
45457
45458 /* Some later processing for combined directives assumes
45459 that the BIND_EXPR containing range for variables appears
45460 at top level in the OMP_FOR body. Fix that up if it's
45461 not the case, e.g. because there is intervening code. */
45462 if (code != OACC_LOOP)
45463 finish_omp_for_block (data.init_blockv[0], ret);
45464
45465 /* Clean up the block subblock/superblock links. Per comment in
45466 begin_compound_stmt, "we don't build BLOCK nodes when processing
45467 templates", so skip this step in that case. */
45468 if (!processing_template_decl)
45469 {
45470 tree superblock = NULL_TREE;
45471 cp_walk_tree (&data.init_blockv[0], fixup_blocks_walker,
45472 (void *)&superblock, NULL);
45473 }
45474
45475 /* Finally record the result. */
45476 add_stmt (data.init_blockv[0]);
45477 }
45478
45479 parser->omp_for_parse_state = save_data;
45480 return ret;
45481}
45482
45483/* Helper function for OpenMP parsing, split clauses and call
45484 finish_omp_clauses on each of the set of clauses afterwards. */
45485
45486static void
45487cp_omp_split_clauses (location_t loc, enum tree_code code,
45488 omp_clause_mask mask, tree clauses, tree *cclauses)
45489{
45490 int i;
45491 c_omp_split_clauses (loc, code, mask, clauses, cclauses);
45492 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
45493 if (cclauses[i])
45494 cclauses[i] = finish_omp_clauses (cclauses[i],
45495 i == C_OMP_CLAUSE_SPLIT_TARGET
45496 ? C_ORT_OMP_TARGET : C_ORT_OMP);
45497}
45498
45499/* OpenMP 5.0:
45500 #pragma omp loop loop-clause[optseq] new-line
45501 for-loop */
45502
45503#define OMP_LOOP_CLAUSE_MASK \
45504 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
45505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
45506 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
45507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
45508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
45509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
45510
45511static tree
45512cp_parser_omp_loop (cp_parser *parser, cp_token *pragma_tok,
45513 char *p_name, omp_clause_mask mask, tree *cclauses,
45514 bool *if_p)
45515{
45516 tree clauses, sb, ret;
45517 unsigned int save;
45518 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
45519
45520 strcat (dest: p_name, src: " loop");
45521 mask |= OMP_LOOP_CLAUSE_MASK;
45522
45523 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
45524 finish_p: cclauses == NULL);
45525 if (cclauses)
45526 {
45527 cp_omp_split_clauses (loc, code: OMP_LOOP, mask, clauses, cclauses);
45528 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
45529 }
45530
45531 keep_next_level (true);
45532 sb = begin_omp_structured_block ();
45533 save = cp_parser_begin_omp_structured_block (parser);
45534
45535 ret = cp_parser_omp_for_loop (parser, code: OMP_LOOP, clauses, cclauses, if_p);
45536
45537 cp_parser_end_omp_structured_block (parser, save);
45538 add_stmt (finish_omp_structured_block (sb));
45539
45540 return ret;
45541}
45542
45543/* OpenMP 4.0:
45544 #pragma omp simd simd-clause[optseq] new-line
45545 for-loop */
45546
45547#define OMP_SIMD_CLAUSE_MASK \
45548 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
45549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
45550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
45551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
45552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
45553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
45554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
45555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
45556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
45557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
45558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
45559
45560static tree
45561cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
45562 char *p_name, omp_clause_mask mask, tree *cclauses,
45563 bool *if_p)
45564{
45565 tree clauses, sb, ret;
45566 unsigned int save;
45567 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
45568
45569 strcat (dest: p_name, src: " simd");
45570 mask |= OMP_SIMD_CLAUSE_MASK;
45571
45572 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
45573 finish_p: cclauses == NULL);
45574 if (cclauses)
45575 {
45576 cp_omp_split_clauses (loc, code: OMP_SIMD, mask, clauses, cclauses);
45577 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
45578 }
45579
45580 keep_next_level (true);
45581 sb = begin_omp_structured_block ();
45582 save = cp_parser_begin_omp_structured_block (parser);
45583
45584 ret = cp_parser_omp_for_loop (parser, code: OMP_SIMD, clauses, cclauses, if_p);
45585
45586 cp_parser_end_omp_structured_block (parser, save);
45587 add_stmt (finish_omp_structured_block (sb));
45588
45589 return ret;
45590}
45591
45592/* OpenMP 2.5:
45593 #pragma omp for for-clause[optseq] new-line
45594 for-loop
45595
45596 OpenMP 4.0:
45597 #pragma omp for simd for-simd-clause[optseq] new-line
45598 for-loop */
45599
45600#define OMP_FOR_CLAUSE_MASK \
45601 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
45602 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
45603 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
45604 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
45605 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
45606 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
45607 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
45608 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
45609 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
45610 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
45611 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
45612
45613static tree
45614cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
45615 char *p_name, omp_clause_mask mask, tree *cclauses,
45616 bool *if_p)
45617{
45618 tree clauses, sb, ret;
45619 unsigned int save;
45620 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
45621
45622 strcat (dest: p_name, src: " for");
45623 mask |= OMP_FOR_CLAUSE_MASK;
45624 /* parallel for{, simd} disallows nowait clause, but for
45625 target {teams distribute ,}parallel for{, simd} it should be accepted. */
45626 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
45627 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
45628 /* Composite distribute parallel for{, simd} disallows ordered clause. */
45629 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
45630 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
45631
45632 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
45633 {
45634 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
45635 const char *p = IDENTIFIER_POINTER (id);
45636
45637 if (strcmp (s1: p, s2: "simd") == 0)
45638 {
45639 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
45640 if (cclauses == NULL)
45641 cclauses = cclauses_buf;
45642
45643 cp_lexer_consume_token (lexer: parser->lexer);
45644 if (!flag_openmp) /* flag_openmp_simd */
45645 return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
45646 cclauses, if_p);
45647 sb = begin_omp_structured_block ();
45648 save = cp_parser_begin_omp_structured_block (parser);
45649 ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
45650 cclauses, if_p);
45651 cp_parser_end_omp_structured_block (parser, save);
45652 tree body = finish_omp_structured_block (sb);
45653 if (ret == NULL)
45654 return ret;
45655 ret = make_node (OMP_FOR);
45656 TREE_TYPE (ret) = void_type_node;
45657 OMP_FOR_BODY (ret) = body;
45658 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
45659 SET_EXPR_LOCATION (ret, loc);
45660 add_stmt (ret);
45661 return ret;
45662 }
45663 }
45664 if (!flag_openmp) /* flag_openmp_simd */
45665 {
45666 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
45667 return NULL_TREE;
45668 }
45669
45670 /* Composite distribute parallel for disallows linear clause. */
45671 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
45672 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
45673
45674 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
45675 finish_p: cclauses == NULL);
45676 if (cclauses)
45677 {
45678 cp_omp_split_clauses (loc, code: OMP_FOR, mask, clauses, cclauses);
45679 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
45680 }
45681
45682 keep_next_level (true);
45683 sb = begin_omp_structured_block ();
45684 save = cp_parser_begin_omp_structured_block (parser);
45685
45686 ret = cp_parser_omp_for_loop (parser, code: OMP_FOR, clauses, cclauses, if_p);
45687
45688 cp_parser_end_omp_structured_block (parser, save);
45689 add_stmt (finish_omp_structured_block (sb));
45690
45691 return ret;
45692}
45693
45694static tree cp_parser_omp_taskloop (cp_parser *, cp_token *, char *,
45695 omp_clause_mask, tree *, bool *);
45696
45697/* OpenMP 2.5:
45698 # pragma omp master new-line
45699 structured-block */
45700
45701static tree
45702cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok,
45703 char *p_name, omp_clause_mask mask, tree *cclauses,
45704 bool *if_p)
45705{
45706 tree clauses, sb, ret;
45707 unsigned int save;
45708 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
45709
45710 strcat (dest: p_name, src: " master");
45711
45712 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
45713 {
45714 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
45715 const char *p = IDENTIFIER_POINTER (id);
45716
45717 if (strcmp (s1: p, s2: "taskloop") == 0)
45718 {
45719 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
45720 if (cclauses == NULL)
45721 cclauses = cclauses_buf;
45722
45723 cp_lexer_consume_token (lexer: parser->lexer);
45724 if (!flag_openmp) /* flag_openmp_simd */
45725 return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
45726 cclauses, if_p);
45727 sb = begin_omp_structured_block ();
45728 save = cp_parser_begin_omp_structured_block (parser);
45729 ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
45730 cclauses, if_p);
45731 cp_parser_end_omp_structured_block (parser, save);
45732 tree body = finish_omp_structured_block (sb);
45733 if (ret == NULL)
45734 return ret;
45735 ret = c_finish_omp_master (loc, body);
45736 OMP_MASTER_COMBINED (ret) = 1;
45737 return ret;
45738 }
45739 }
45740 if (!flag_openmp) /* flag_openmp_simd */
45741 {
45742 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
45743 return NULL_TREE;
45744 }
45745
45746 if (cclauses)
45747 {
45748 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
45749 finish_p: false);
45750 cp_omp_split_clauses (loc, code: OMP_MASTER, mask, clauses, cclauses);
45751 }
45752 else
45753 cp_parser_require_pragma_eol (parser, pragma_tok);
45754
45755 return c_finish_omp_master (loc,
45756 cp_parser_omp_structured_block (parser, if_p));
45757}
45758
45759/* OpenMP 5.1:
45760 # pragma omp masked masked-clauses new-line
45761 structured-block */
45762
45763#define OMP_MASKED_CLAUSE_MASK \
45764 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
45765
45766static tree
45767cp_parser_omp_masked (cp_parser *parser, cp_token *pragma_tok,
45768 char *p_name, omp_clause_mask mask, tree *cclauses,
45769 bool *if_p)
45770{
45771 tree clauses, sb, ret;
45772 unsigned int save;
45773 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
45774
45775 strcat (dest: p_name, src: " masked");
45776 mask |= OMP_MASKED_CLAUSE_MASK;
45777
45778 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
45779 {
45780 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
45781 const char *p = IDENTIFIER_POINTER (id);
45782
45783 if (strcmp (s1: p, s2: "taskloop") == 0)
45784 {
45785 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
45786 if (cclauses == NULL)
45787 cclauses = cclauses_buf;
45788
45789 cp_lexer_consume_token (lexer: parser->lexer);
45790 if (!flag_openmp) /* flag_openmp_simd */
45791 return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
45792 cclauses, if_p);
45793 sb = begin_omp_structured_block ();
45794 save = cp_parser_begin_omp_structured_block (parser);
45795 ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
45796 cclauses, if_p);
45797 cp_parser_end_omp_structured_block (parser, save);
45798 tree body = finish_omp_structured_block (sb);
45799 if (ret == NULL)
45800 return ret;
45801 ret = c_finish_omp_masked (loc, body,
45802 cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
45803 OMP_MASKED_COMBINED (ret) = 1;
45804 return ret;
45805 }
45806 }
45807 if (!flag_openmp) /* flag_openmp_simd */
45808 {
45809 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
45810 return NULL_TREE;
45811 }
45812
45813 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
45814 finish_p: cclauses == NULL);
45815 if (cclauses)
45816 {
45817 cp_omp_split_clauses (loc, code: OMP_MASTER, mask, clauses, cclauses);
45818 clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
45819 }
45820
45821 return c_finish_omp_masked (loc,
45822 cp_parser_omp_structured_block (parser, if_p),
45823 clauses);
45824}
45825
45826/* OpenMP 2.5:
45827 # pragma omp ordered new-line
45828 structured-block
45829
45830 OpenMP 4.5:
45831 # pragma omp ordered ordered-clauses new-line
45832 structured-block */
45833
45834#define OMP_ORDERED_CLAUSE_MASK \
45835 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
45836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
45837
45838#define OMP_ORDERED_DEPEND_CLAUSE_MASK \
45839 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
45840 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
45841
45842static bool
45843cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
45844 enum pragma_context context, bool *if_p)
45845{
45846 location_t loc = pragma_tok->location;
45847 int n = 1;
45848
45849 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
45850 n = 2;
45851
45852 if (cp_lexer_nth_token_is (lexer: parser->lexer, n, type: CPP_NAME))
45853 {
45854 tree id = cp_lexer_peek_nth_token (lexer: parser->lexer, n)->u.value;
45855 const char *p = IDENTIFIER_POINTER (id);
45856
45857 if (strcmp (s1: p, s2: "depend") == 0 || strcmp (s1: p, s2: "doacross") == 0)
45858 {
45859 if (!flag_openmp) /* flag_openmp_simd */
45860 {
45861 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
45862 return false;
45863 }
45864 if (context == pragma_stmt)
45865 {
45866 error_at (pragma_tok->location, "%<#pragma omp ordered%> with "
45867 "%qs clause may only be used in compound "
45868 "statements", p);
45869 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
45870 return true;
45871 }
45872 tree clauses
45873 = cp_parser_omp_all_clauses (parser,
45874 OMP_ORDERED_DEPEND_CLAUSE_MASK,
45875 where: "#pragma omp ordered", pragma_tok);
45876 c_finish_omp_ordered (loc, clauses, NULL_TREE);
45877 return false;
45878 }
45879 }
45880
45881 tree clauses
45882 = cp_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
45883 where: "#pragma omp ordered", pragma_tok);
45884
45885 if (!flag_openmp /* flag_openmp_simd */
45886 && omp_find_clause (clauses, kind: OMP_CLAUSE_SIMD) == NULL_TREE)
45887 return false;
45888
45889 c_finish_omp_ordered (loc, clauses,
45890 cp_parser_omp_structured_block (parser, if_p));
45891 return true;
45892}
45893
45894/* OpenMP 2.5:
45895
45896 section-scope:
45897 { section-sequence }
45898
45899 section-sequence:
45900 section-directive[opt] structured-block
45901 section-sequence section-directive structured-block */
45902
45903static tree
45904cp_parser_omp_sections_scope (cp_parser *parser)
45905{
45906 tree stmt, substmt;
45907 bool error_suppress = false;
45908 cp_token *tok;
45909
45910 matching_braces braces;
45911 if (!braces.require_open (parser))
45912 return NULL_TREE;
45913
45914 stmt = push_stmt_list ();
45915
45916 if (cp_parser_pragma_kind (token: cp_lexer_peek_token (lexer: parser->lexer))
45917 != PRAGMA_OMP_SECTION
45918 && !cp_parser_omp_section_scan (parser, directive: "section", tentative: true))
45919 {
45920 substmt = cp_parser_omp_structured_block_sequence (parser,
45921 kind: PRAGMA_OMP_SECTION);
45922 substmt = build1 (OMP_SECTION, void_type_node, substmt);
45923 add_stmt (substmt);
45924 }
45925
45926 while (1)
45927 {
45928 tok = cp_lexer_peek_token (lexer: parser->lexer);
45929 if (tok->type == CPP_CLOSE_BRACE)
45930 break;
45931 if (tok->type == CPP_EOF)
45932 break;
45933
45934 if (cp_parser_omp_section_scan (parser, directive: "section", tentative: false))
45935 tok = cp_lexer_peek_token (lexer: parser->lexer);
45936 if (cp_parser_pragma_kind (token: tok) == PRAGMA_OMP_SECTION)
45937 {
45938 cp_lexer_consume_token (lexer: parser->lexer);
45939 cp_parser_require_pragma_eol (parser, pragma_tok: tok);
45940 error_suppress = false;
45941 }
45942 else if (!error_suppress)
45943 {
45944 cp_parser_error (parser, gmsgid: "expected %<#pragma omp section%> or %<}%>");
45945 error_suppress = true;
45946 }
45947
45948 substmt = cp_parser_omp_structured_block_sequence (parser,
45949 kind: PRAGMA_OMP_SECTION);
45950 substmt = build1 (OMP_SECTION, void_type_node, substmt);
45951 add_stmt (substmt);
45952 }
45953 braces.require_close (parser);
45954
45955 substmt = pop_stmt_list (stmt);
45956
45957 stmt = make_node (OMP_SECTIONS);
45958 TREE_TYPE (stmt) = void_type_node;
45959 OMP_SECTIONS_BODY (stmt) = substmt;
45960
45961 add_stmt (stmt);
45962 return stmt;
45963}
45964
45965/* OpenMP 2.5:
45966 # pragma omp sections sections-clause[optseq] newline
45967 sections-scope */
45968
45969#define OMP_SECTIONS_CLAUSE_MASK \
45970 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
45971 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
45972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
45973 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
45974 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
45975 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
45976
45977static tree
45978cp_parser_omp_sections (cp_parser *parser, cp_token *pragma_tok,
45979 char *p_name, omp_clause_mask mask, tree *cclauses)
45980{
45981 tree clauses, ret;
45982 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
45983
45984 strcat (dest: p_name, src: " sections");
45985 mask |= OMP_SECTIONS_CLAUSE_MASK;
45986 if (cclauses)
45987 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
45988
45989 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
45990 finish_p: cclauses == NULL);
45991 if (cclauses)
45992 {
45993 cp_omp_split_clauses (loc, code: OMP_SECTIONS, mask, clauses, cclauses);
45994 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
45995 }
45996
45997 ret = cp_parser_omp_sections_scope (parser);
45998 if (ret)
45999 OMP_SECTIONS_CLAUSES (ret) = clauses;
46000
46001 return ret;
46002}
46003
46004/* OpenMP 2.5:
46005 # pragma omp parallel parallel-clause[optseq] new-line
46006 structured-block
46007 # pragma omp parallel for parallel-for-clause[optseq] new-line
46008 structured-block
46009 # pragma omp parallel sections parallel-sections-clause[optseq] new-line
46010 structured-block
46011
46012 OpenMP 4.0:
46013 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
46014 structured-block */
46015
46016#define OMP_PARALLEL_CLAUSE_MASK \
46017 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
46018 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
46019 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
46020 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
46021 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
46022 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
46023 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
46024 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
46025 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
46026 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
46027
46028static tree
46029cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
46030 char *p_name, omp_clause_mask mask, tree *cclauses,
46031 bool *if_p)
46032{
46033 tree stmt, clauses, block;
46034 unsigned int save;
46035 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
46036
46037 strcat (dest: p_name, src: " parallel");
46038 mask |= OMP_PARALLEL_CLAUSE_MASK;
46039 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */
46040 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
46041 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
46042 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
46043
46044 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_FOR))
46045 {
46046 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46047 if (cclauses == NULL)
46048 cclauses = cclauses_buf;
46049
46050 cp_lexer_consume_token (lexer: parser->lexer);
46051 if (!flag_openmp) /* flag_openmp_simd */
46052 return cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses,
46053 if_p);
46054 block = begin_omp_parallel ();
46055 save = cp_parser_begin_omp_structured_block (parser);
46056 tree ret = cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses,
46057 if_p);
46058 cp_parser_end_omp_structured_block (parser, save);
46059 stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
46060 block);
46061 if (ret == NULL_TREE)
46062 return ret;
46063 OMP_PARALLEL_COMBINED (stmt) = 1;
46064 return stmt;
46065 }
46066 /* When combined with distribute, parallel has to be followed by for.
46067 #pragma omp target parallel is allowed though. */
46068 else if (cclauses
46069 && (mask & (OMP_CLAUSE_MASK_1
46070 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
46071 {
46072 error_at (loc, "expected %<for%> after %qs", p_name);
46073 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46074 return NULL_TREE;
46075 }
46076 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
46077 {
46078 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
46079 const char *p = IDENTIFIER_POINTER (id);
46080 if (cclauses == NULL && strcmp (s1: p, s2: "masked") == 0)
46081 {
46082 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46083 cclauses = cclauses_buf;
46084
46085 cp_lexer_consume_token (lexer: parser->lexer);
46086 if (!flag_openmp) /* flag_openmp_simd */
46087 return cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
46088 cclauses, if_p);
46089 block = begin_omp_parallel ();
46090 save = cp_parser_begin_omp_structured_block (parser);
46091 tree ret = cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
46092 cclauses, if_p);
46093 cp_parser_end_omp_structured_block (parser, save);
46094 stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
46095 block);
46096 if (ret == NULL_TREE)
46097 return ret;
46098 /* masked does have just filter clause, but during gimplification
46099 isn't represented by a gimplification omp context, so for
46100 #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
46101 so that
46102 #pragma omp parallel masked
46103 #pragma omp taskloop simd lastprivate (x)
46104 isn't confused with
46105 #pragma omp parallel masked taskloop simd lastprivate (x) */
46106 if (OMP_MASKED_COMBINED (ret))
46107 OMP_PARALLEL_COMBINED (stmt) = 1;
46108 return stmt;
46109 }
46110 else if (cclauses == NULL && strcmp (s1: p, s2: "master") == 0)
46111 {
46112 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46113 cclauses = cclauses_buf;
46114
46115 cp_lexer_consume_token (lexer: parser->lexer);
46116 if (!flag_openmp) /* flag_openmp_simd */
46117 return cp_parser_omp_master (parser, pragma_tok, p_name, mask,
46118 cclauses, if_p);
46119 block = begin_omp_parallel ();
46120 save = cp_parser_begin_omp_structured_block (parser);
46121 tree ret = cp_parser_omp_master (parser, pragma_tok, p_name, mask,
46122 cclauses, if_p);
46123 cp_parser_end_omp_structured_block (parser, save);
46124 stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
46125 block);
46126 if (ret == NULL_TREE)
46127 return ret;
46128 /* master doesn't have any clauses and during gimplification
46129 isn't represented by a gimplification omp context, so for
46130 #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
46131 so that
46132 #pragma omp parallel master
46133 #pragma omp taskloop simd lastprivate (x)
46134 isn't confused with
46135 #pragma omp parallel master taskloop simd lastprivate (x) */
46136 if (OMP_MASTER_COMBINED (ret))
46137 OMP_PARALLEL_COMBINED (stmt) = 1;
46138 return stmt;
46139 }
46140 else if (strcmp (s1: p, s2: "loop") == 0)
46141 {
46142 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46143 if (cclauses == NULL)
46144 cclauses = cclauses_buf;
46145
46146 cp_lexer_consume_token (lexer: parser->lexer);
46147 if (!flag_openmp) /* flag_openmp_simd */
46148 return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
46149 cclauses, if_p);
46150 block = begin_omp_parallel ();
46151 save = cp_parser_begin_omp_structured_block (parser);
46152 tree ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
46153 cclauses, if_p);
46154 cp_parser_end_omp_structured_block (parser, save);
46155 stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
46156 block);
46157 if (ret == NULL_TREE)
46158 return ret;
46159 OMP_PARALLEL_COMBINED (stmt) = 1;
46160 return stmt;
46161 }
46162 else if (!flag_openmp) /* flag_openmp_simd */
46163 {
46164 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46165 return NULL_TREE;
46166 }
46167 else if (cclauses == NULL && strcmp (s1: p, s2: "sections") == 0)
46168 {
46169 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46170 cclauses = cclauses_buf;
46171
46172 cp_lexer_consume_token (lexer: parser->lexer);
46173 block = begin_omp_parallel ();
46174 save = cp_parser_begin_omp_structured_block (parser);
46175 cp_parser_omp_sections (parser, pragma_tok, p_name, mask, cclauses);
46176 cp_parser_end_omp_structured_block (parser, save);
46177 stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
46178 block);
46179 OMP_PARALLEL_COMBINED (stmt) = 1;
46180 return stmt;
46181 }
46182 }
46183 else if (!flag_openmp) /* flag_openmp_simd */
46184 {
46185 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46186 return NULL_TREE;
46187 }
46188
46189 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
46190 finish_p: cclauses == NULL);
46191 if (cclauses)
46192 {
46193 cp_omp_split_clauses (loc, code: OMP_PARALLEL, mask, clauses, cclauses);
46194 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
46195 }
46196
46197 block = begin_omp_parallel ();
46198 save = cp_parser_begin_omp_structured_block (parser);
46199 parser->omp_attrs_forbidden_p = true;
46200 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p);
46201 cp_parser_end_omp_structured_block (parser, save);
46202 stmt = finish_omp_parallel (clauses, block);
46203 return stmt;
46204}
46205
46206/* OpenMP 2.5:
46207 # pragma omp single single-clause[optseq] new-line
46208 structured-block */
46209
46210#define OMP_SINGLE_CLAUSE_MASK \
46211 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
46212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
46213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \
46214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
46215 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
46216
46217static tree
46218cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
46219{
46220 tree stmt = make_node (OMP_SINGLE);
46221 TREE_TYPE (stmt) = void_type_node;
46222 SET_EXPR_LOCATION (stmt, pragma_tok->location);
46223
46224 OMP_SINGLE_CLAUSES (stmt)
46225 = cp_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
46226 where: "#pragma omp single", pragma_tok);
46227 OMP_SINGLE_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
46228
46229 return add_stmt (stmt);
46230}
46231
46232/* OpenMP 5.1:
46233 # pragma omp scope scope-clause[optseq] new-line
46234 structured-block */
46235
46236#define OMP_SCOPE_CLAUSE_MASK \
46237 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
46238 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
46239 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
46240 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
46241 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
46242
46243static tree
46244cp_parser_omp_scope (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
46245{
46246 tree stmt = make_node (OMP_SCOPE);
46247 TREE_TYPE (stmt) = void_type_node;
46248 SET_EXPR_LOCATION (stmt, pragma_tok->location);
46249
46250 OMP_SCOPE_CLAUSES (stmt)
46251 = cp_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
46252 where: "#pragma omp scope", pragma_tok);
46253 OMP_SCOPE_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
46254
46255 return add_stmt (stmt);
46256}
46257
46258/* OpenMP 3.0:
46259 # pragma omp task task-clause[optseq] new-line
46260 structured-block */
46261
46262#define OMP_TASK_CLAUSE_MASK \
46263 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
46264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
46265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
46266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
46267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
46268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
46269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
46270 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
46271 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
46272 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
46273 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
46274 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
46275 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
46276 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
46277
46278static tree
46279cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
46280{
46281 tree clauses, block;
46282 unsigned int save;
46283
46284 clauses = cp_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
46285 where: "#pragma omp task", pragma_tok);
46286 block = begin_omp_task ();
46287 save = cp_parser_begin_omp_structured_block (parser);
46288 parser->omp_attrs_forbidden_p = true;
46289 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p);
46290 cp_parser_end_omp_structured_block (parser, save);
46291 return finish_omp_task (clauses, block);
46292}
46293
46294/* OpenMP 3.0:
46295 # pragma omp taskwait new-line
46296
46297 OpenMP 5.0:
46298 # pragma omp taskwait taskwait-clause[opt] new-line */
46299
46300#define OMP_TASKWAIT_CLAUSE_MASK \
46301 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
46302 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
46303
46304static void
46305cp_parser_omp_taskwait (cp_parser *parser, cp_token *pragma_tok)
46306{
46307 tree clauses
46308 = cp_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
46309 where: "#pragma omp taskwait", pragma_tok);
46310
46311 if (clauses)
46312 {
46313 tree stmt = make_node (OMP_TASK);
46314 TREE_TYPE (stmt) = void_node;
46315 OMP_TASK_CLAUSES (stmt) = clauses;
46316 OMP_TASK_BODY (stmt) = NULL_TREE;
46317 SET_EXPR_LOCATION (stmt, pragma_tok->location);
46318 add_stmt (stmt);
46319 }
46320 else
46321 finish_omp_taskwait ();
46322}
46323
46324/* OpenMP 3.1:
46325 # pragma omp taskyield new-line */
46326
46327static void
46328cp_parser_omp_taskyield (cp_parser *parser, cp_token *pragma_tok)
46329{
46330 cp_parser_require_pragma_eol (parser, pragma_tok);
46331 finish_omp_taskyield ();
46332}
46333
46334/* OpenMP 4.0:
46335 # pragma omp taskgroup new-line
46336 structured-block
46337
46338 OpenMP 5.0:
46339 # pragma omp taskgroup taskgroup-clause[optseq] new-line */
46340
46341#define OMP_TASKGROUP_CLAUSE_MASK \
46342 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
46343 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
46344
46345static tree
46346cp_parser_omp_taskgroup (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
46347{
46348 tree clauses
46349 = cp_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
46350 where: "#pragma omp taskgroup", pragma_tok);
46351 return c_finish_omp_taskgroup (input_location,
46352 cp_parser_omp_structured_block (parser,
46353 if_p),
46354 clauses);
46355}
46356
46357
46358/* OpenMP 2.5:
46359 # pragma omp threadprivate (variable-list) */
46360
46361static void
46362cp_parser_omp_threadprivate (cp_parser *parser, cp_token *pragma_tok)
46363{
46364 tree vars;
46365
46366 vars = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_ERROR, NULL);
46367 cp_parser_require_pragma_eol (parser, pragma_tok);
46368
46369 finish_omp_threadprivate (vars);
46370}
46371
46372/* OpenMP 4.0:
46373 # pragma omp cancel cancel-clause[optseq] new-line */
46374
46375#define OMP_CANCEL_CLAUSE_MASK \
46376 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
46377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
46378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
46379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \
46380 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
46381
46382static void
46383cp_parser_omp_cancel (cp_parser *parser, cp_token *pragma_tok)
46384{
46385 tree clauses = cp_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
46386 where: "#pragma omp cancel", pragma_tok);
46387 finish_omp_cancel (clauses);
46388}
46389
46390/* OpenMP 4.0:
46391 # pragma omp cancellation point cancelpt-clause[optseq] new-line */
46392
46393#define OMP_CANCELLATION_POINT_CLAUSE_MASK \
46394 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \
46395 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \
46396 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \
46397 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
46398
46399static bool
46400cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok,
46401 enum pragma_context context)
46402{
46403 tree clauses;
46404 bool point_seen = false;
46405
46406 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
46407 {
46408 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
46409 const char *p = IDENTIFIER_POINTER (id);
46410
46411 if (strcmp (s1: p, s2: "point") == 0)
46412 {
46413 cp_lexer_consume_token (lexer: parser->lexer);
46414 point_seen = true;
46415 }
46416 }
46417 if (!point_seen)
46418 {
46419 cp_parser_error (parser, gmsgid: "expected %<point%>");
46420 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46421 return false;
46422 }
46423
46424 if (context != pragma_compound)
46425 {
46426 if (context == pragma_stmt)
46427 error_at (pragma_tok->location,
46428 "%<#pragma %s%> may only be used in compound statements",
46429 "omp cancellation point");
46430 else
46431 cp_parser_error (parser, gmsgid: "expected declaration specifiers");
46432 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46433 return true;
46434 }
46435
46436 clauses = cp_parser_omp_all_clauses (parser,
46437 OMP_CANCELLATION_POINT_CLAUSE_MASK,
46438 where: "#pragma omp cancellation point",
46439 pragma_tok);
46440 finish_omp_cancellation_point (clauses);
46441 return true;
46442}
46443
46444/* OpenMP 4.0:
46445 #pragma omp distribute distribute-clause[optseq] new-line
46446 for-loop */
46447
46448#define OMP_DISTRIBUTE_CLAUSE_MASK \
46449 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
46450 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
46451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
46452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
46453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
46454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
46455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
46456
46457static tree
46458cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok,
46459 char *p_name, omp_clause_mask mask, tree *cclauses,
46460 bool *if_p)
46461{
46462 tree clauses, sb, ret;
46463 unsigned int save;
46464 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
46465
46466 strcat (dest: p_name, src: " distribute");
46467 mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
46468
46469 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
46470 {
46471 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
46472 const char *p = IDENTIFIER_POINTER (id);
46473 bool simd = false;
46474 bool parallel = false;
46475
46476 if (strcmp (s1: p, s2: "simd") == 0)
46477 simd = true;
46478 else
46479 parallel = strcmp (s1: p, s2: "parallel") == 0;
46480 if (parallel || simd)
46481 {
46482 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46483 if (cclauses == NULL)
46484 cclauses = cclauses_buf;
46485 cp_lexer_consume_token (lexer: parser->lexer);
46486 if (!flag_openmp) /* flag_openmp_simd */
46487 {
46488 if (simd)
46489 return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
46490 cclauses, if_p);
46491 else
46492 return cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
46493 cclauses, if_p);
46494 }
46495 sb = begin_omp_structured_block ();
46496 save = cp_parser_begin_omp_structured_block (parser);
46497 if (simd)
46498 ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
46499 cclauses, if_p);
46500 else
46501 ret = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
46502 cclauses, if_p);
46503 cp_parser_end_omp_structured_block (parser, save);
46504 tree body = finish_omp_structured_block (sb);
46505 if (ret == NULL)
46506 return ret;
46507 ret = make_node (OMP_DISTRIBUTE);
46508 TREE_TYPE (ret) = void_type_node;
46509 OMP_FOR_BODY (ret) = body;
46510 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
46511 SET_EXPR_LOCATION (ret, loc);
46512 add_stmt (ret);
46513 return ret;
46514 }
46515 }
46516 if (!flag_openmp) /* flag_openmp_simd */
46517 {
46518 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46519 return NULL_TREE;
46520 }
46521
46522 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
46523 finish_p: cclauses == NULL);
46524 if (cclauses)
46525 {
46526 cp_omp_split_clauses (loc, code: OMP_DISTRIBUTE, mask, clauses, cclauses);
46527 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
46528 }
46529
46530 keep_next_level (true);
46531 sb = begin_omp_structured_block ();
46532 save = cp_parser_begin_omp_structured_block (parser);
46533
46534 ret = cp_parser_omp_for_loop (parser, code: OMP_DISTRIBUTE, clauses, NULL, if_p);
46535
46536 cp_parser_end_omp_structured_block (parser, save);
46537 add_stmt (finish_omp_structured_block (sb));
46538
46539 return ret;
46540}
46541
46542/* OpenMP 4.0:
46543 # pragma omp teams teams-clause[optseq] new-line
46544 structured-block */
46545
46546#define OMP_TEAMS_CLAUSE_MASK \
46547 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
46548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
46549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
46550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
46551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
46552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
46553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
46554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
46555
46556static tree
46557cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
46558 char *p_name, omp_clause_mask mask, tree *cclauses,
46559 bool *if_p)
46560{
46561 tree clauses, sb, ret;
46562 unsigned int save;
46563 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
46564
46565 strcat (dest: p_name, src: " teams");
46566 mask |= OMP_TEAMS_CLAUSE_MASK;
46567
46568 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
46569 {
46570 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
46571 const char *p = IDENTIFIER_POINTER (id);
46572 if (strcmp (s1: p, s2: "distribute") == 0)
46573 {
46574 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46575 if (cclauses == NULL)
46576 cclauses = cclauses_buf;
46577
46578 cp_lexer_consume_token (lexer: parser->lexer);
46579 if (!flag_openmp) /* flag_openmp_simd */
46580 return cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
46581 cclauses, if_p);
46582 keep_next_level (true);
46583 sb = begin_omp_structured_block ();
46584 save = cp_parser_begin_omp_structured_block (parser);
46585 ret = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
46586 cclauses, if_p);
46587 cp_parser_end_omp_structured_block (parser, save);
46588 tree body = finish_omp_structured_block (sb);
46589 if (ret == NULL)
46590 return ret;
46591 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
46592 ret = make_node (OMP_TEAMS);
46593 TREE_TYPE (ret) = void_type_node;
46594 OMP_TEAMS_CLAUSES (ret) = clauses;
46595 OMP_TEAMS_BODY (ret) = body;
46596 OMP_TEAMS_COMBINED (ret) = 1;
46597 SET_EXPR_LOCATION (ret, loc);
46598 return add_stmt (ret);
46599 }
46600 else if (strcmp (s1: p, s2: "loop") == 0)
46601 {
46602 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
46603 if (cclauses == NULL)
46604 cclauses = cclauses_buf;
46605
46606 cp_lexer_consume_token (lexer: parser->lexer);
46607 if (!flag_openmp) /* flag_openmp_simd */
46608 return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
46609 cclauses, if_p);
46610 keep_next_level (true);
46611 sb = begin_omp_structured_block ();
46612 save = cp_parser_begin_omp_structured_block (parser);
46613 ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
46614 cclauses, if_p);
46615 cp_parser_end_omp_structured_block (parser, save);
46616 tree body = finish_omp_structured_block (sb);
46617 if (ret == NULL)
46618 return ret;
46619 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
46620 ret = make_node (OMP_TEAMS);
46621 TREE_TYPE (ret) = void_type_node;
46622 OMP_TEAMS_CLAUSES (ret) = clauses;
46623 OMP_TEAMS_BODY (ret) = body;
46624 OMP_TEAMS_COMBINED (ret) = 1;
46625 SET_EXPR_LOCATION (ret, loc);
46626 return add_stmt (ret);
46627 }
46628 }
46629 if (!flag_openmp) /* flag_openmp_simd */
46630 {
46631 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46632 return NULL_TREE;
46633 }
46634
46635 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
46636 finish_p: cclauses == NULL);
46637 if (cclauses)
46638 {
46639 cp_omp_split_clauses (loc, code: OMP_TEAMS, mask, clauses, cclauses);
46640 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
46641 }
46642
46643 tree stmt = make_node (OMP_TEAMS);
46644 TREE_TYPE (stmt) = void_type_node;
46645 OMP_TEAMS_CLAUSES (stmt) = clauses;
46646 keep_next_level (true);
46647 OMP_TEAMS_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
46648 SET_EXPR_LOCATION (stmt, loc);
46649
46650 return add_stmt (stmt);
46651}
46652
46653/* OpenMP 4.0:
46654 # pragma omp target data target-data-clause[optseq] new-line
46655 structured-block */
46656
46657#define OMP_TARGET_DATA_CLAUSE_MASK \
46658 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
46659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
46660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
46661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
46662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
46663
46664static tree
46665cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
46666{
46667 if (flag_openmp)
46668 omp_requires_mask
46669 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
46670
46671 tree clauses
46672 = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
46673 where: "#pragma omp target data", pragma_tok);
46674 c_omp_adjust_map_clauses (clauses, false);
46675 int map_seen = 0;
46676 for (tree *pc = &clauses; *pc;)
46677 {
46678 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
46679 switch (OMP_CLAUSE_MAP_KIND (*pc))
46680 {
46681 case GOMP_MAP_TO:
46682 case GOMP_MAP_ALWAYS_TO:
46683 case GOMP_MAP_PRESENT_TO:
46684 case GOMP_MAP_ALWAYS_PRESENT_TO:
46685 case GOMP_MAP_FROM:
46686 case GOMP_MAP_ALWAYS_FROM:
46687 case GOMP_MAP_PRESENT_FROM:
46688 case GOMP_MAP_ALWAYS_PRESENT_FROM:
46689 case GOMP_MAP_TOFROM:
46690 case GOMP_MAP_ALWAYS_TOFROM:
46691 case GOMP_MAP_PRESENT_TOFROM:
46692 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
46693 case GOMP_MAP_ALLOC:
46694 case GOMP_MAP_PRESENT_ALLOC:
46695 map_seen = 3;
46696 break;
46697 case GOMP_MAP_FIRSTPRIVATE_POINTER:
46698 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
46699 case GOMP_MAP_ALWAYS_POINTER:
46700 case GOMP_MAP_ATTACH_DETACH:
46701 case GOMP_MAP_ATTACH:
46702 break;
46703 default:
46704 map_seen |= 1;
46705 error_at (OMP_CLAUSE_LOCATION (*pc),
46706 "%<#pragma omp target data%> with map-type other "
46707 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
46708 "on %<map%> clause");
46709 *pc = OMP_CLAUSE_CHAIN (*pc);
46710 continue;
46711 }
46712 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
46713 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
46714 map_seen = 3;
46715 pc = &OMP_CLAUSE_CHAIN (*pc);
46716 }
46717
46718 if (map_seen != 3)
46719 {
46720 if (map_seen == 0)
46721 error_at (pragma_tok->location,
46722 "%<#pragma omp target data%> must contain at least "
46723 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
46724 "clause");
46725 return NULL_TREE;
46726 }
46727
46728 tree stmt = make_node (OMP_TARGET_DATA);
46729 TREE_TYPE (stmt) = void_type_node;
46730 OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
46731
46732 keep_next_level (true);
46733 OMP_TARGET_DATA_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
46734
46735 SET_EXPR_LOCATION (stmt, pragma_tok->location);
46736 return add_stmt (stmt);
46737}
46738
46739/* OpenMP 4.5:
46740 # pragma omp target enter data target-enter-data-clause[optseq] new-line
46741 structured-block */
46742
46743#define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
46744 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
46745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
46746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
46747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
46748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
46749
46750static bool
46751cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
46752 enum pragma_context context)
46753{
46754 bool data_seen = false;
46755 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
46756 {
46757 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
46758 const char *p = IDENTIFIER_POINTER (id);
46759
46760 if (strcmp (s1: p, s2: "data") == 0)
46761 {
46762 cp_lexer_consume_token (lexer: parser->lexer);
46763 data_seen = true;
46764 }
46765 }
46766 if (!data_seen)
46767 {
46768 cp_parser_error (parser, gmsgid: "expected %<data%>");
46769 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46770 return false;
46771 }
46772
46773 if (context == pragma_stmt)
46774 {
46775 error_at (pragma_tok->location,
46776 "%<#pragma %s%> may only be used in compound statements",
46777 "omp target enter data");
46778 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46779 return true;
46780 }
46781
46782 if (flag_openmp)
46783 omp_requires_mask
46784 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
46785
46786 tree clauses
46787 = cp_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
46788 where: "#pragma omp target enter data", pragma_tok);
46789 c_omp_adjust_map_clauses (clauses, false);
46790 int map_seen = 0;
46791 for (tree *pc = &clauses; *pc;)
46792 {
46793 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
46794 switch (OMP_CLAUSE_MAP_KIND (*pc))
46795 {
46796 case GOMP_MAP_TO:
46797 case GOMP_MAP_ALWAYS_TO:
46798 case GOMP_MAP_PRESENT_TO:
46799 case GOMP_MAP_ALWAYS_PRESENT_TO:
46800 case GOMP_MAP_ALLOC:
46801 case GOMP_MAP_PRESENT_ALLOC:
46802 map_seen = 3;
46803 break;
46804 case GOMP_MAP_TOFROM:
46805 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
46806 map_seen = 3;
46807 break;
46808 case GOMP_MAP_ALWAYS_TOFROM:
46809 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
46810 map_seen = 3;
46811 break;
46812 case GOMP_MAP_PRESENT_TOFROM:
46813 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
46814 map_seen = 3;
46815 break;
46816 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
46817 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
46818 map_seen = 3;
46819 break;
46820 case GOMP_MAP_FIRSTPRIVATE_POINTER:
46821 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
46822 case GOMP_MAP_ALWAYS_POINTER:
46823 case GOMP_MAP_ATTACH_DETACH:
46824 case GOMP_MAP_ATTACH:
46825 break;
46826 default:
46827 map_seen |= 1;
46828 error_at (OMP_CLAUSE_LOCATION (*pc),
46829 "%<#pragma omp target enter data%> with map-type other "
46830 "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
46831 *pc = OMP_CLAUSE_CHAIN (*pc);
46832 continue;
46833 }
46834 pc = &OMP_CLAUSE_CHAIN (*pc);
46835 }
46836
46837 if (map_seen != 3)
46838 {
46839 if (map_seen == 0)
46840 error_at (pragma_tok->location,
46841 "%<#pragma omp target enter data%> must contain at least "
46842 "one %<map%> clause");
46843 return true;
46844 }
46845
46846 tree stmt = make_node (OMP_TARGET_ENTER_DATA);
46847 TREE_TYPE (stmt) = void_type_node;
46848 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
46849 SET_EXPR_LOCATION (stmt, pragma_tok->location);
46850 add_stmt (stmt);
46851 return true;
46852}
46853
46854/* OpenMP 4.5:
46855 # pragma omp target exit data target-enter-data-clause[optseq] new-line
46856 structured-block */
46857
46858#define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
46859 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
46860 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
46861 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
46862 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
46863 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
46864
46865static bool
46866cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
46867 enum pragma_context context)
46868{
46869 bool data_seen = false;
46870 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
46871 {
46872 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
46873 const char *p = IDENTIFIER_POINTER (id);
46874
46875 if (strcmp (s1: p, s2: "data") == 0)
46876 {
46877 cp_lexer_consume_token (lexer: parser->lexer);
46878 data_seen = true;
46879 }
46880 }
46881 if (!data_seen)
46882 {
46883 cp_parser_error (parser, gmsgid: "expected %<data%>");
46884 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46885 return false;
46886 }
46887
46888 if (context == pragma_stmt)
46889 {
46890 error_at (pragma_tok->location,
46891 "%<#pragma %s%> may only be used in compound statements",
46892 "omp target exit data");
46893 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46894 return true;
46895 }
46896
46897 if (flag_openmp)
46898 omp_requires_mask
46899 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
46900
46901 tree clauses
46902 = cp_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
46903 where: "#pragma omp target exit data", pragma_tok,
46904 finish_p: false);
46905 clauses = finish_omp_clauses (clauses, C_ORT_OMP_EXIT_DATA);
46906 c_omp_adjust_map_clauses (clauses, false);
46907 int map_seen = 0;
46908 for (tree *pc = &clauses; *pc;)
46909 {
46910 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
46911 switch (OMP_CLAUSE_MAP_KIND (*pc))
46912 {
46913 case GOMP_MAP_FROM:
46914 case GOMP_MAP_ALWAYS_FROM:
46915 case GOMP_MAP_PRESENT_FROM:
46916 case GOMP_MAP_ALWAYS_PRESENT_FROM:
46917 case GOMP_MAP_RELEASE:
46918 case GOMP_MAP_DELETE:
46919 map_seen = 3;
46920 break;
46921 case GOMP_MAP_TOFROM:
46922 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
46923 map_seen = 3;
46924 break;
46925 case GOMP_MAP_ALWAYS_TOFROM:
46926 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
46927 map_seen = 3;
46928 break;
46929 case GOMP_MAP_PRESENT_TOFROM:
46930 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
46931 map_seen = 3;
46932 break;
46933 case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
46934 OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
46935 map_seen = 3;
46936 break;
46937 case GOMP_MAP_FIRSTPRIVATE_POINTER:
46938 case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
46939 case GOMP_MAP_ALWAYS_POINTER:
46940 case GOMP_MAP_ATTACH_DETACH:
46941 case GOMP_MAP_DETACH:
46942 break;
46943 default:
46944 map_seen |= 1;
46945 error_at (OMP_CLAUSE_LOCATION (*pc),
46946 "%<#pragma omp target exit data%> with map-type other "
46947 "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
46948 "on %<map%> clause");
46949 *pc = OMP_CLAUSE_CHAIN (*pc);
46950 continue;
46951 }
46952 pc = &OMP_CLAUSE_CHAIN (*pc);
46953 }
46954
46955 if (map_seen != 3)
46956 {
46957 if (map_seen == 0)
46958 error_at (pragma_tok->location,
46959 "%<#pragma omp target exit data%> must contain at least "
46960 "one %<map%> clause");
46961 return true;
46962 }
46963
46964 tree stmt = make_node (OMP_TARGET_EXIT_DATA);
46965 TREE_TYPE (stmt) = void_type_node;
46966 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
46967 SET_EXPR_LOCATION (stmt, pragma_tok->location);
46968 add_stmt (stmt);
46969 return true;
46970}
46971
46972/* OpenMP 4.0:
46973 # pragma omp target update target-update-clause[optseq] new-line */
46974
46975#define OMP_TARGET_UPDATE_CLAUSE_MASK \
46976 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
46977 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
46978 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
46979 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
46980 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
46981 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
46982
46983static bool
46984cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
46985 enum pragma_context context)
46986{
46987 if (context == pragma_stmt)
46988 {
46989 error_at (pragma_tok->location,
46990 "%<#pragma %s%> may only be used in compound statements",
46991 "omp target update");
46992 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
46993 return true;
46994 }
46995
46996 tree clauses
46997 = cp_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
46998 where: "#pragma omp target update", pragma_tok);
46999 if (omp_find_clause (clauses, kind: OMP_CLAUSE_TO) == NULL_TREE
47000 && omp_find_clause (clauses, kind: OMP_CLAUSE_FROM) == NULL_TREE)
47001 {
47002 error_at (pragma_tok->location,
47003 "%<#pragma omp target update%> must contain at least one "
47004 "%<from%> or %<to%> clauses");
47005 return true;
47006 }
47007
47008 if (flag_openmp)
47009 omp_requires_mask
47010 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
47011
47012 tree stmt = make_node (OMP_TARGET_UPDATE);
47013 TREE_TYPE (stmt) = void_type_node;
47014 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
47015 SET_EXPR_LOCATION (stmt, pragma_tok->location);
47016 add_stmt (stmt);
47017 return true;
47018}
47019
47020/* OpenMP 4.0:
47021 # pragma omp target target-clause[optseq] new-line
47022 structured-block */
47023
47024#define OMP_TARGET_CLAUSE_MASK \
47025 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
47026 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
47027 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
47028 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
47029 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
47030 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
47031 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
47032 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
47033 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
47034 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
47035 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
47036 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
47037 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
47038
47039static bool
47040cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
47041 enum pragma_context context, bool *if_p)
47042{
47043 if (flag_openmp)
47044 omp_requires_mask
47045 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
47046
47047 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
47048 {
47049 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
47050 const char *p = IDENTIFIER_POINTER (id);
47051 enum tree_code ccode = ERROR_MARK;
47052
47053 if (strcmp (s1: p, s2: "teams") == 0)
47054 ccode = OMP_TEAMS;
47055 else if (strcmp (s1: p, s2: "parallel") == 0)
47056 ccode = OMP_PARALLEL;
47057 else if (strcmp (s1: p, s2: "simd") == 0)
47058 ccode = OMP_SIMD;
47059 if (ccode != ERROR_MARK)
47060 {
47061 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
47062 char p_name[sizeof ("#pragma omp target teams distribute "
47063 "parallel for simd")];
47064
47065 cp_lexer_consume_token (lexer: parser->lexer);
47066 strcpy (dest: p_name, src: "#pragma omp target");
47067 if (!flag_openmp) /* flag_openmp_simd */
47068 {
47069 tree stmt;
47070 switch (ccode)
47071 {
47072 case OMP_TEAMS:
47073 stmt = cp_parser_omp_teams (parser, pragma_tok, p_name,
47074 OMP_TARGET_CLAUSE_MASK,
47075 cclauses, if_p);
47076 break;
47077 case OMP_PARALLEL:
47078 stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name,
47079 OMP_TARGET_CLAUSE_MASK,
47080 cclauses, if_p);
47081 break;
47082 case OMP_SIMD:
47083 stmt = cp_parser_omp_simd (parser, pragma_tok, p_name,
47084 OMP_TARGET_CLAUSE_MASK,
47085 cclauses, if_p);
47086 break;
47087 default:
47088 gcc_unreachable ();
47089 }
47090 return stmt != NULL_TREE;
47091 }
47092 keep_next_level (true);
47093 tree sb = begin_omp_structured_block (), ret;
47094 unsigned save = cp_parser_begin_omp_structured_block (parser);
47095 switch (ccode)
47096 {
47097 case OMP_TEAMS:
47098 ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
47099 OMP_TARGET_CLAUSE_MASK, cclauses,
47100 if_p);
47101 break;
47102 case OMP_PARALLEL:
47103 ret = cp_parser_omp_parallel (parser, pragma_tok, p_name,
47104 OMP_TARGET_CLAUSE_MASK, cclauses,
47105 if_p);
47106 break;
47107 case OMP_SIMD:
47108 ret = cp_parser_omp_simd (parser, pragma_tok, p_name,
47109 OMP_TARGET_CLAUSE_MASK, cclauses,
47110 if_p);
47111 break;
47112 default:
47113 gcc_unreachable ();
47114 }
47115 cp_parser_end_omp_structured_block (parser, save);
47116 tree body = finish_omp_structured_block (sb);
47117 if (ret == NULL_TREE)
47118 return false;
47119 if (ccode == OMP_TEAMS && !processing_template_decl)
47120 /* For combined target teams, ensure the num_teams and
47121 thread_limit clause expressions are evaluated on the host,
47122 before entering the target construct. */
47123 for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
47124 c; c = OMP_CLAUSE_CHAIN (c))
47125 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
47126 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
47127 for (int i = 0;
47128 i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
47129 if (OMP_CLAUSE_OPERAND (c, i)
47130 && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
47131 {
47132 tree expr = OMP_CLAUSE_OPERAND (c, i);
47133 expr = force_target_expr (TREE_TYPE (expr), expr,
47134 tf_none);
47135 if (expr == error_mark_node)
47136 continue;
47137 tree tmp = TARGET_EXPR_SLOT (expr);
47138 add_stmt (expr);
47139 OMP_CLAUSE_OPERAND (c, i) = expr;
47140 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
47141 OMP_CLAUSE_FIRSTPRIVATE);
47142 OMP_CLAUSE_DECL (tc) = tmp;
47143 OMP_CLAUSE_CHAIN (tc)
47144 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
47145 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
47146 }
47147 c_omp_adjust_map_clauses (cclauses[C_OMP_CLAUSE_SPLIT_TARGET], true);
47148 finish_omp_target (pragma_tok->location,
47149 cclauses[C_OMP_CLAUSE_SPLIT_TARGET], body, true);
47150 return true;
47151 }
47152 else if (!flag_openmp) /* flag_openmp_simd */
47153 {
47154 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
47155 return false;
47156 }
47157 else if (strcmp (s1: p, s2: "data") == 0)
47158 {
47159 cp_lexer_consume_token (lexer: parser->lexer);
47160 cp_parser_omp_target_data (parser, pragma_tok, if_p);
47161 return true;
47162 }
47163 else if (strcmp (s1: p, s2: "enter") == 0)
47164 {
47165 cp_lexer_consume_token (lexer: parser->lexer);
47166 return cp_parser_omp_target_enter_data (parser, pragma_tok, context);
47167 }
47168 else if (strcmp (s1: p, s2: "exit") == 0)
47169 {
47170 cp_lexer_consume_token (lexer: parser->lexer);
47171 return cp_parser_omp_target_exit_data (parser, pragma_tok, context);
47172 }
47173 else if (strcmp (s1: p, s2: "update") == 0)
47174 {
47175 cp_lexer_consume_token (lexer: parser->lexer);
47176 return cp_parser_omp_target_update (parser, pragma_tok, context);
47177 }
47178 }
47179 if (!flag_openmp) /* flag_openmp_simd */
47180 {
47181 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
47182 return false;
47183 }
47184
47185 tree clauses = cp_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
47186 where: "#pragma omp target", pragma_tok,
47187 finish_p: false);
47188 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
47189 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
47190 {
47191 tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
47192 OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
47193 OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
47194 OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
47195 OMP_CLAUSE_CHAIN (c) = nc;
47196 }
47197 clauses = finish_omp_clauses (clauses, C_ORT_OMP_TARGET);
47198
47199 c_omp_adjust_map_clauses (clauses, true);
47200 keep_next_level (true);
47201 tree body = cp_parser_omp_structured_block (parser, if_p);
47202
47203 finish_omp_target (pragma_tok->location, clauses, body, false);
47204 return true;
47205}
47206
47207/* OpenACC 2.0:
47208 # pragma acc cache (variable-list) new-line
47209
47210 OpenACC 2.7:
47211 # pragma acc cache (readonly: variable-list) new-line
47212*/
47213
47214static tree
47215cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
47216{
47217 /* Don't create location wrapper nodes within 'OMP_CLAUSE__CACHE_'
47218 clauses. */
47219 auto_suppress_location_wrappers sentinel;
47220
47221 tree stmt, clauses = NULL_TREE;
47222 bool readonly = false;
47223
47224 if (cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
47225 {
47226 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
47227 if (token->type == CPP_NAME
47228 && !strcmp (IDENTIFIER_POINTER (token->u.value), s2: "readonly")
47229 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type == CPP_COLON)
47230 {
47231 cp_lexer_consume_token (lexer: parser->lexer);
47232 cp_lexer_consume_token (lexer: parser->lexer);
47233 readonly = true;
47234 }
47235 clauses = cp_parser_omp_var_list_no_open (parser, kind: OMP_CLAUSE__CACHE_,
47236 NULL, NULL);
47237 }
47238
47239 if (readonly)
47240 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
47241 OMP_CLAUSE__CACHE__READONLY (c) = 1;
47242
47243 clauses = finish_omp_clauses (clauses, C_ORT_ACC);
47244
47245 cp_parser_require_pragma_eol (parser, pragma_tok: cp_lexer_peek_token (lexer: parser->lexer));
47246
47247 stmt = make_node (OACC_CACHE);
47248 TREE_TYPE (stmt) = void_type_node;
47249 OACC_CACHE_CLAUSES (stmt) = clauses;
47250 SET_EXPR_LOCATION (stmt, pragma_tok->location);
47251 add_stmt (stmt);
47252
47253 return stmt;
47254}
47255
47256/* OpenACC 2.0:
47257 # pragma acc data oacc-data-clause[optseq] new-line
47258 structured-block */
47259
47260#define OACC_DATA_CLAUSE_MASK \
47261 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
47262 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
47263 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
47264 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
47265 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
47266 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
47267 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
47268 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
47269 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47270 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
47271 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) )
47272
47273static tree
47274cp_parser_oacc_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
47275{
47276 tree stmt, clauses, block;
47277 unsigned int save;
47278
47279 clauses = cp_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
47280 where: "#pragma acc data", pragma_tok);
47281
47282 block = begin_omp_parallel ();
47283 save = cp_parser_begin_omp_structured_block (parser);
47284 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p);
47285 cp_parser_end_omp_structured_block (parser, save);
47286 stmt = finish_oacc_data (clauses, block);
47287 return stmt;
47288}
47289
47290/* OpenACC 2.0:
47291 # pragma acc host_data <clauses> new-line
47292 structured-block */
47293
47294#define OACC_HOST_DATA_CLAUSE_MASK \
47295 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \
47296 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47297 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
47298
47299static tree
47300cp_parser_oacc_host_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
47301{
47302 tree stmt, clauses, block;
47303 unsigned int save;
47304
47305 clauses = cp_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
47306 where: "#pragma acc host_data", pragma_tok,
47307 finish_p: false);
47308 if (!omp_find_clause (clauses, kind: OMP_CLAUSE_USE_DEVICE_PTR))
47309 {
47310 error_at (pragma_tok->location,
47311 "%<host_data%> construct requires %<use_device%> clause");
47312 return error_mark_node;
47313 }
47314 clauses = finish_omp_clauses (clauses, C_ORT_ACC);
47315 block = begin_omp_parallel ();
47316 save = cp_parser_begin_omp_structured_block (parser);
47317 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p);
47318 cp_parser_end_omp_structured_block (parser, save);
47319 stmt = finish_oacc_host_data (clauses, block);
47320 return stmt;
47321}
47322
47323/* OpenACC 2.0:
47324 # pragma acc declare oacc-data-clause[optseq] new-line
47325*/
47326
47327#define OACC_DECLARE_CLAUSE_MASK \
47328 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
47329 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
47330 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
47331 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
47332 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
47333 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \
47334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \
47335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) )
47336
47337static tree
47338cp_parser_oacc_declare (cp_parser *parser, cp_token *pragma_tok)
47339{
47340 tree clauses, stmt;
47341 bool error = false;
47342 bool found_in_scope = global_bindings_p ();
47343
47344 clauses = cp_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
47345 where: "#pragma acc declare", pragma_tok);
47346
47347
47348 if (omp_find_clause (clauses, kind: OMP_CLAUSE_MAP) == NULL_TREE)
47349 {
47350 error_at (pragma_tok->location,
47351 "no valid clauses specified in %<#pragma acc declare%>");
47352 return NULL_TREE;
47353 }
47354
47355 for (tree t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
47356 {
47357 location_t loc = OMP_CLAUSE_LOCATION (t);
47358 tree decl = OMP_CLAUSE_DECL (t);
47359 if (!DECL_P (decl))
47360 {
47361 error_at (loc, "array section in %<#pragma acc declare%>");
47362 error = true;
47363 continue;
47364 }
47365 gcc_assert (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_MAP);
47366 switch (OMP_CLAUSE_MAP_KIND (t))
47367 {
47368 case GOMP_MAP_FIRSTPRIVATE_POINTER:
47369 case GOMP_MAP_ALLOC:
47370 case GOMP_MAP_TO:
47371 case GOMP_MAP_FORCE_DEVICEPTR:
47372 case GOMP_MAP_DEVICE_RESIDENT:
47373 break;
47374
47375 case GOMP_MAP_LINK:
47376 if (!global_bindings_p ()
47377 && (TREE_STATIC (decl)
47378 || !DECL_EXTERNAL (decl)))
47379 {
47380 error_at (loc,
47381 "%qD must be a global variable in "
47382 "%<#pragma acc declare link%>",
47383 decl);
47384 error = true;
47385 continue;
47386 }
47387 break;
47388
47389 default:
47390 if (global_bindings_p ())
47391 {
47392 error_at (loc, "invalid OpenACC clause at file scope");
47393 error = true;
47394 continue;
47395 }
47396 if (DECL_EXTERNAL (decl))
47397 {
47398 error_at (loc,
47399 "invalid use of %<extern%> variable %qD "
47400 "in %<#pragma acc declare%>", decl);
47401 error = true;
47402 continue;
47403 }
47404 else if (TREE_PUBLIC (decl))
47405 {
47406 error_at (loc,
47407 "invalid use of %<global%> variable %qD "
47408 "in %<#pragma acc declare%>", decl);
47409 error = true;
47410 continue;
47411 }
47412 break;
47413 }
47414
47415 if (!found_in_scope)
47416 /* This seems to ignore the existence of cleanup scopes?
47417 What is the meaning for local extern decls? The local
47418 extern is in this scope, but it is referring to a decl that
47419 is namespace scope. */
47420 for (tree d = current_binding_level->names; d; d = TREE_CHAIN (d))
47421 if (d == decl)
47422 {
47423 found_in_scope = true;
47424 break;
47425 }
47426 if (!found_in_scope)
47427 {
47428 error_at (loc,
47429 "%qD must be a variable declared in the same scope as "
47430 "%<#pragma acc declare%>", decl);
47431 error = true;
47432 continue;
47433 }
47434
47435 if (!error)
47436 {
47437 if (DECL_LOCAL_DECL_P (decl))
47438 /* We need to mark the aliased decl, as that is the entity
47439 that is being referred to. This won't work for
47440 dependent variables, but it didn't work for them before
47441 DECL_LOCAL_DECL_P was a thing either. But then
47442 dependent local extern variable decls are as rare as
47443 hen's teeth. */
47444 if (auto alias = DECL_LOCAL_DECL_ALIAS (decl))
47445 if (alias != error_mark_node)
47446 decl = alias;
47447
47448 if (lookup_attribute (attr_name: "omp declare target", DECL_ATTRIBUTES (decl))
47449 || lookup_attribute (attr_name: "omp declare target link",
47450 DECL_ATTRIBUTES (decl)))
47451 {
47452 error_at (loc, "variable %qD used more than once with "
47453 "%<#pragma acc declare%>", decl);
47454 error = true;
47455 continue;
47456 }
47457
47458 tree id;
47459 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
47460 id = get_identifier ("omp declare target link");
47461 else
47462 id = get_identifier ("omp declare target");
47463
47464 DECL_ATTRIBUTES (decl)
47465 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
47466 if (current_binding_level->kind == sk_namespace)
47467 {
47468 symtab_node *node = symtab_node::get (decl);
47469 if (node != NULL)
47470 {
47471 node->offloadable = 1;
47472 if (ENABLE_OFFLOADING)
47473 {
47474 g->have_offload = true;
47475 if (is_a <varpool_node *> (p: node))
47476 vec_safe_push (v&: offload_vars, obj: decl);
47477 }
47478 }
47479 }
47480 }
47481 }
47482
47483 if (error || current_binding_level->kind == sk_namespace)
47484 return NULL_TREE;
47485
47486 stmt = make_node (OACC_DECLARE);
47487 TREE_TYPE (stmt) = void_type_node;
47488 OACC_DECLARE_CLAUSES (stmt) = clauses;
47489 SET_EXPR_LOCATION (stmt, pragma_tok->location);
47490
47491 add_stmt (stmt);
47492
47493 return NULL_TREE;
47494}
47495
47496/* OpenACC 2.0:
47497 # pragma acc enter data oacc-enter-data-clause[optseq] new-line
47498
47499 or
47500
47501 # pragma acc exit data oacc-exit-data-clause[optseq] new-line
47502
47503 LOC is the location of the #pragma token.
47504*/
47505
47506#define OACC_ENTER_DATA_CLAUSE_MASK \
47507 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
47509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
47510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
47511 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
47512 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
47513
47514#define OACC_EXIT_DATA_CLAUSE_MASK \
47515 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47516 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
47517 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
47518 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \
47519 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \
47520 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \
47521 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
47522
47523static tree
47524cp_parser_oacc_enter_exit_data (cp_parser *parser, cp_token *pragma_tok,
47525 bool enter)
47526{
47527 location_t loc = pragma_tok->location;
47528 tree stmt, clauses;
47529 const char *p = "";
47530
47531 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
47532 p = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
47533
47534 if (strcmp (s1: p, s2: "data") != 0)
47535 {
47536 error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
47537 enter ? "enter" : "exit");
47538 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
47539 return NULL_TREE;
47540 }
47541
47542 cp_lexer_consume_token (lexer: parser->lexer);
47543
47544 if (enter)
47545 clauses = cp_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
47546 where: "#pragma acc enter data", pragma_tok);
47547 else
47548 clauses = cp_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
47549 where: "#pragma acc exit data", pragma_tok);
47550
47551 if (omp_find_clause (clauses, kind: OMP_CLAUSE_MAP) == NULL_TREE)
47552 {
47553 error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
47554 enter ? "enter" : "exit");
47555 return NULL_TREE;
47556 }
47557
47558 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
47559 TREE_TYPE (stmt) = void_type_node;
47560 OMP_STANDALONE_CLAUSES (stmt) = clauses;
47561 SET_EXPR_LOCATION (stmt, loc);
47562 add_stmt (stmt);
47563 return stmt;
47564}
47565
47566/* OpenACC 2.0:
47567 # pragma acc loop oacc-loop-clause[optseq] new-line
47568 structured-block */
47569
47570#define OACC_LOOP_CLAUSE_MASK \
47571 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
47572 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
47573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
47574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
47575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
47576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
47577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
47578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \
47579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
47580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE))
47581
47582static tree
47583cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
47584 omp_clause_mask mask, tree *cclauses, bool *if_p)
47585{
47586 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
47587
47588 strcat (dest: p_name, src: " loop");
47589 mask |= OACC_LOOP_CLAUSE_MASK;
47590
47591 tree clauses = cp_parser_oacc_all_clauses (parser, mask, where: p_name, pragma_tok,
47592 /*finish_p=*/cclauses == NULL,
47593 /*target=*/target_p: is_parallel);
47594 if (cclauses)
47595 {
47596 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
47597 if (*cclauses)
47598 *cclauses = finish_omp_clauses (*cclauses, C_ORT_ACC_TARGET);
47599 if (clauses)
47600 clauses = finish_omp_clauses (clauses, C_ORT_ACC);
47601 }
47602
47603 tree block = begin_omp_structured_block ();
47604 int save = cp_parser_begin_omp_structured_block (parser);
47605 tree stmt = cp_parser_omp_for_loop (parser, code: OACC_LOOP, clauses, NULL, if_p);
47606 cp_parser_end_omp_structured_block (parser, save);
47607
47608 /* Later processing of combined acc loop constructs gets confused
47609 by an extra level of empty nested BIND_EXPRs, so flatten them. */
47610 block = finish_omp_structured_block (block);
47611 if (TREE_CODE (block) == BIND_EXPR
47612 && TREE_CODE (BIND_EXPR_BODY (block)) == BIND_EXPR
47613 && !BIND_EXPR_VARS (block))
47614 block = BIND_EXPR_BODY (block);
47615 add_stmt (block);
47616
47617 return stmt;
47618}
47619
47620/* OpenACC 2.0:
47621 # pragma acc kernels oacc-kernels-clause[optseq] new-line
47622 structured-block
47623
47624 or
47625
47626 # pragma acc parallel oacc-parallel-clause[optseq] new-line
47627 structured-block
47628
47629 OpenACC 2.6:
47630
47631 # pragma acc serial oacc-serial-clause[optseq] new-line
47632*/
47633
47634#define OACC_KERNELS_CLAUSE_MASK \
47635 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
47636 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
47637 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
47638 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
47639 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
47640 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
47641 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
47642 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
47643 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47644 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
47645 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
47646 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
47647 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
47648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
47649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
47650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
47651
47652#define OACC_PARALLEL_CLAUSE_MASK \
47653 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
47654 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
47655 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
47656 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
47657 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
47658 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
47659 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
47660 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
47661 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
47662 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47663 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
47664 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \
47665 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \
47666 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
47667 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
47668 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
47669 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
47670 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
47671 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
47672
47673#define OACC_SERIAL_CLAUSE_MASK \
47674 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
47675 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \
47676 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \
47677 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \
47678 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \
47679 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \
47680 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \
47681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \
47682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \
47684 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \
47685 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \
47686 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \
47687 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \
47688 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
47689 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
47690
47691static tree
47692cp_parser_oacc_compute (cp_parser *parser, cp_token *pragma_tok,
47693 char *p_name, bool *if_p)
47694{
47695 omp_clause_mask mask;
47696 enum tree_code code;
47697 switch (cp_parser_pragma_kind (token: pragma_tok))
47698 {
47699 case PRAGMA_OACC_KERNELS:
47700 strcat (dest: p_name, src: " kernels");
47701 mask = OACC_KERNELS_CLAUSE_MASK;
47702 code = OACC_KERNELS;
47703 break;
47704 case PRAGMA_OACC_PARALLEL:
47705 strcat (dest: p_name, src: " parallel");
47706 mask = OACC_PARALLEL_CLAUSE_MASK;
47707 code = OACC_PARALLEL;
47708 break;
47709 case PRAGMA_OACC_SERIAL:
47710 strcat (dest: p_name, src: " serial");
47711 mask = OACC_SERIAL_CLAUSE_MASK;
47712 code = OACC_SERIAL;
47713 break;
47714 default:
47715 gcc_unreachable ();
47716 }
47717
47718 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
47719 {
47720 const char *p
47721 = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
47722 if (strcmp (s1: p, s2: "loop") == 0)
47723 {
47724 cp_lexer_consume_token (lexer: parser->lexer);
47725 tree block = begin_omp_parallel ();
47726 tree clauses;
47727 tree stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask,
47728 cclauses: &clauses, if_p);
47729 protected_set_expr_location (stmt, pragma_tok->location);
47730 return finish_omp_construct (code, block, clauses);
47731 }
47732 }
47733
47734 tree clauses = cp_parser_oacc_all_clauses (parser, mask, where: p_name, pragma_tok,
47735 /*finish_p=*/true,
47736 /*target=*/target_p: true);
47737
47738 tree block = begin_omp_parallel ();
47739 unsigned int save = cp_parser_begin_omp_structured_block (parser);
47740 cp_parser_statement (parser, NULL_TREE, in_compound: false, if_p);
47741 cp_parser_end_omp_structured_block (parser, save);
47742 return finish_omp_construct (code, block, clauses);
47743}
47744
47745/* OpenACC 2.0:
47746 # pragma acc update oacc-update-clause[optseq] new-line
47747*/
47748
47749#define OACC_UPDATE_CLAUSE_MASK \
47750 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \
47751 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \
47752 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \
47753 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \
47754 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \
47755 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF) \
47756 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT))
47757
47758static tree
47759cp_parser_oacc_update (cp_parser *parser, cp_token *pragma_tok)
47760{
47761 tree stmt, clauses;
47762
47763 clauses = cp_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
47764 where: "#pragma acc update", pragma_tok);
47765
47766 if (omp_find_clause (clauses, kind: OMP_CLAUSE_MAP) == NULL_TREE)
47767 {
47768 error_at (pragma_tok->location,
47769 "%<#pragma acc update%> must contain at least one "
47770 "%<device%> or %<host%> or %<self%> clause");
47771 return NULL_TREE;
47772 }
47773
47774 stmt = make_node (OACC_UPDATE);
47775 TREE_TYPE (stmt) = void_type_node;
47776 OACC_UPDATE_CLAUSES (stmt) = clauses;
47777 SET_EXPR_LOCATION (stmt, pragma_tok->location);
47778 add_stmt (stmt);
47779 return stmt;
47780}
47781
47782/* OpenACC 2.0:
47783 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
47784
47785 LOC is the location of the #pragma token.
47786*/
47787
47788#define OACC_WAIT_CLAUSE_MASK \
47789 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC))
47790
47791static tree
47792cp_parser_oacc_wait (cp_parser *parser, cp_token *pragma_tok)
47793{
47794 tree clauses, list = NULL_TREE, stmt = NULL_TREE;
47795 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
47796
47797 if (cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_OPEN_PAREN)
47798 list = cp_parser_oacc_wait_list (parser, clause_loc: loc, list);
47799
47800 clauses = cp_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK,
47801 where: "#pragma acc wait", pragma_tok);
47802
47803 stmt = c_finish_oacc_wait (loc, list, clauses);
47804 stmt = finish_expr_stmt (stmt);
47805
47806 return stmt;
47807}
47808
47809/* OpenMP 4.0:
47810 # pragma omp declare simd declare-simd-clauses[optseq] new-line */
47811
47812#define OMP_DECLARE_SIMD_CLAUSE_MASK \
47813 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
47814 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
47815 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
47816 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \
47817 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \
47818 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
47819
47820static void
47821cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok,
47822 enum pragma_context context,
47823 bool variant_p)
47824{
47825 bool first_p = parser->omp_declare_simd == NULL;
47826 cp_omp_declare_simd_data data;
47827 if (first_p)
47828 {
47829 data.error_seen = false;
47830 data.fndecl_seen = false;
47831 data.variant_p = variant_p;
47832 data.tokens = vNULL;
47833 data.attribs[0] = NULL;
47834 data.attribs[1] = NULL;
47835 data.loc = UNKNOWN_LOCATION;
47836 /* It is safe to take the address of a local variable; it will only be
47837 used while this scope is live. */
47838 parser->omp_declare_simd = &data;
47839 }
47840 else if (parser->omp_declare_simd->variant_p != variant_p)
47841 {
47842 error_at (pragma_tok->location,
47843 "%<#pragma omp declare %s%> followed by "
47844 "%<#pragma omp declare %s%>",
47845 parser->omp_declare_simd->variant_p ? "variant" : "simd",
47846 parser->omp_declare_simd->variant_p ? "simd" : "variant");
47847 parser->omp_declare_simd->error_seen = true;
47848 }
47849
47850 /* Store away all pragma tokens. */
47851 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
47852 cp_lexer_consume_token (lexer: parser->lexer);
47853 cp_parser_require_pragma_eol (parser, pragma_tok);
47854 struct cp_token_cache *cp
47855 = cp_token_cache_new (first: pragma_tok, last: cp_lexer_peek_token (lexer: parser->lexer));
47856 parser->omp_declare_simd->tokens.safe_push (obj: cp);
47857
47858 if (first_p)
47859 {
47860 while (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_PRAGMA))
47861 cp_parser_pragma (parser, context, NULL);
47862 switch (context)
47863 {
47864 case pragma_external:
47865 cp_parser_declaration (parser, NULL_TREE);
47866 break;
47867 case pragma_member:
47868 cp_parser_member_declaration (parser);
47869 break;
47870 case pragma_objc_icode:
47871 cp_parser_block_declaration (parser, /*statement_p=*/false);
47872 break;
47873 default:
47874 cp_parser_declaration_statement (parser);
47875 break;
47876 }
47877 if (parser->omp_declare_simd
47878 && !parser->omp_declare_simd->error_seen
47879 && !parser->omp_declare_simd->fndecl_seen)
47880 error_at (pragma_tok->location,
47881 "%<#pragma omp declare %s%> not immediately followed by "
47882 "function declaration or definition",
47883 parser->omp_declare_simd->variant_p ? "variant" : "simd");
47884 data.tokens.release ();
47885 parser->omp_declare_simd = NULL;
47886 }
47887}
47888
47889/* OpenMP 5.0:
47890
47891 trait-selector:
47892 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
47893
47894 trait-score:
47895 score(score-expression)
47896
47897 Note that this function returns a list of trait selectors for the
47898 trait-selector-set SET. */
47899
47900static tree
47901cp_parser_omp_context_selector (cp_parser *parser, enum omp_tss_code set,
47902 bool has_parms_p)
47903{
47904 tree ret = NULL_TREE;
47905 do
47906 {
47907 tree selector;
47908 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_KEYWORD)
47909 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
47910 selector = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
47911 else
47912 {
47913 cp_parser_error (parser, gmsgid: "expected trait selector name");
47914 return error_mark_node;
47915 }
47916
47917 enum omp_ts_code sel
47918 = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector));
47919
47920 if (sel == OMP_TRAIT_INVALID)
47921 {
47922 /* Per the spec, "Implementations can ignore specified selectors
47923 that are not those described in this section"; however, we
47924 must record such selectors because they cause match failures. */
47925 warning_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
47926 OPT_Wopenmp,
47927 "unknown selector %qs for context selector set %qs",
47928 IDENTIFIER_POINTER (selector), omp_tss_map[set]);
47929 cp_lexer_consume_token (lexer: parser->lexer);
47930 ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret);
47931 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
47932 for (size_t n = cp_parser_skip_balanced_tokens (parser, n: 1) - 1;
47933 n; --n)
47934 cp_lexer_consume_token (lexer: parser->lexer);
47935 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
47936 {
47937 cp_lexer_consume_token (lexer: parser->lexer);
47938 continue;
47939 }
47940 else
47941 break;
47942 }
47943
47944 cp_lexer_consume_token (lexer: parser->lexer);
47945
47946 tree properties = NULL_TREE;
47947 tree scoreval = NULL_TREE;
47948 enum omp_tp_type property_kind = omp_ts_map[sel].tp_type;
47949 bool allow_score = omp_ts_map[sel].allow_score;
47950 tree t;
47951
47952 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
47953 {
47954 if (property_kind == OMP_TRAIT_PROPERTY_NONE)
47955 {
47956 error ("selector %qs does not accept any properties",
47957 IDENTIFIER_POINTER (selector));
47958 return error_mark_node;
47959 }
47960
47961 matching_parens parens;
47962 parens.consume_open (parser);
47963
47964 cp_token *token = cp_lexer_peek_token (lexer: parser->lexer);
47965 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
47966 && strcmp (IDENTIFIER_POINTER (token->u.value), s2: "score") == 0
47967 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_OPEN_PAREN))
47968 {
47969 cp_lexer_save_tokens (lexer: parser->lexer);
47970 cp_lexer_consume_token (lexer: parser->lexer);
47971 cp_lexer_consume_token (lexer: parser->lexer);
47972 if (cp_parser_skip_to_closing_parenthesis (parser, recovering: false, or_comma: false,
47973 consume_paren: true)
47974 && cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COLON))
47975 {
47976 cp_lexer_rollback_tokens (lexer: parser->lexer);
47977 cp_lexer_consume_token (lexer: parser->lexer);
47978
47979 matching_parens parens2;
47980 parens2.require_open (parser);
47981 tree score = cp_parser_constant_expression (parser);
47982 if (!parens2.require_close (parser))
47983 cp_parser_skip_to_closing_parenthesis (parser, recovering: true,
47984 or_comma: false, consume_paren: true);
47985 cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON);
47986 if (!allow_score)
47987 error_at (token->location,
47988 "%<score%> cannot be specified in traits "
47989 "in the %qs trait-selector-set",
47990 omp_tss_map[set]);
47991 else if (score != error_mark_node)
47992 {
47993 score = fold_non_dependent_expr (score);
47994 if (value_dependent_expression_p (score))
47995 scoreval = score;
47996 else if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
47997 || TREE_CODE (score) != INTEGER_CST)
47998 error_at (token->location, "%<score%> argument must "
47999 "be constant integer expression");
48000 else if (tree_int_cst_sgn (score) < 0)
48001 error_at (token->location, "%<score%> argument must "
48002 "be non-negative");
48003 else
48004 scoreval = score;
48005 }
48006 }
48007 else
48008 cp_lexer_rollback_tokens (lexer: parser->lexer);
48009
48010 token = cp_lexer_peek_token (lexer: parser->lexer);
48011 }
48012
48013 switch (property_kind)
48014 {
48015 case OMP_TRAIT_PROPERTY_ID:
48016 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_KEYWORD)
48017 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
48018 {
48019 tree prop = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
48020 cp_lexer_consume_token (lexer: parser->lexer);
48021 properties = make_trait_property (prop, NULL_TREE,
48022 properties);
48023 }
48024 else
48025 {
48026 cp_parser_error (parser, gmsgid: "expected identifier");
48027 return error_mark_node;
48028 }
48029 break;
48030 case OMP_TRAIT_PROPERTY_NAME_LIST:
48031 do
48032 {
48033 tree prop = OMP_TP_NAMELIST_NODE;
48034 tree value = NULL_TREE;
48035 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_KEYWORD)
48036 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
48037 {
48038 value = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
48039 cp_lexer_consume_token (lexer: parser->lexer);
48040 }
48041 else if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_STRING))
48042 value = cp_parser_string_literal (parser,
48043 /*translate=*/false,
48044 /*wide_ok=*/false);
48045 else
48046 {
48047 cp_parser_error (parser, gmsgid: "expected identifier or "
48048 "string literal");
48049 return error_mark_node;
48050 }
48051
48052 properties = make_trait_property (prop, value, properties);
48053
48054 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
48055 cp_lexer_consume_token (lexer: parser->lexer);
48056 else
48057 break;
48058 }
48059 while (1);
48060 break;
48061 case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
48062 case OMP_TRAIT_PROPERTY_BOOL_EXPR:
48063 /* FIXME: this is bogus, the expression need
48064 not be constant. */
48065 t = cp_parser_constant_expression (parser);
48066 if (t != error_mark_node)
48067 {
48068 t = fold_non_dependent_expr (t);
48069 if (!value_dependent_expression_p (t)
48070 && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
48071 || !tree_fits_shwi_p (t)))
48072 error_at (token->location, "property must be "
48073 "constant integer expression");
48074 else
48075 properties = make_trait_property (NULL_TREE, t,
48076 properties);
48077 }
48078 else
48079 return error_mark_node;
48080 break;
48081 case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
48082 if (sel == OMP_TRAIT_CONSTRUCT_SIMD)
48083 {
48084 if (!has_parms_p)
48085 {
48086 error_at (token->location, "properties for %<simd%> "
48087 "selector may not be specified in "
48088 "%<metadirective%>");
48089 return error_mark_node;
48090 }
48091 properties
48092 = cp_parser_omp_all_clauses (parser,
48093 OMP_DECLARE_SIMD_CLAUSE_MASK,
48094 where: "simd", NULL, finish_p: true, nested: 2);
48095 }
48096 else if (sel == OMP_TRAIT_IMPLEMENTATION_REQUIRES)
48097 {
48098 /* FIXME: The "requires" selector was added in OpenMP 5.1.
48099 Currently only the now-deprecated syntax
48100 from OpenMP 5.0 is supported. */
48101 sorry_at (token->location,
48102 "%<requires%> selector is not supported yet");
48103 return error_mark_node;
48104 }
48105 else
48106 gcc_unreachable ();
48107 break;
48108 default:
48109 gcc_unreachable ();
48110 }
48111
48112 if (!parens.require_close (parser))
48113 cp_parser_skip_to_closing_parenthesis (parser, recovering: true, or_comma: false, consume_paren: true);
48114
48115 properties = nreverse (properties);
48116 }
48117 else if (property_kind != OMP_TRAIT_PROPERTY_NONE
48118 && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST
48119 && property_kind != OMP_TRAIT_PROPERTY_EXTENSION)
48120 {
48121 cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN);
48122 return error_mark_node;
48123 }
48124
48125 ret = make_trait_selector (sel, scoreval, properties, ret);
48126
48127 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
48128 cp_lexer_consume_token (lexer: parser->lexer);
48129 else
48130 break;
48131 }
48132 while (1);
48133
48134 return nreverse (ret);
48135}
48136
48137/* OpenMP 5.0:
48138
48139 trait-set-selector[,trait-set-selector[,...]]
48140
48141 trait-set-selector:
48142 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
48143
48144 trait-set-selector-name:
48145 constructor
48146 device
48147 implementation
48148 user */
48149
48150static tree
48151cp_parser_omp_context_selector_specification (cp_parser *parser,
48152 bool has_parms_p)
48153{
48154 tree ret = NULL_TREE;
48155 do
48156 {
48157 const char *setp = "";
48158 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
48159 setp
48160 = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
48161 enum omp_tss_code set = omp_lookup_tss_code (setp);
48162
48163 if (set == OMP_TRAIT_SET_INVALID)
48164 {
48165 cp_parser_error (parser, gmsgid: "expected context selector set name");
48166 return error_mark_node;
48167 }
48168
48169 cp_lexer_consume_token (lexer: parser->lexer);
48170
48171 if (!cp_parser_require (parser, type: CPP_EQ, token_desc: RT_EQ))
48172 return error_mark_node;
48173
48174 matching_braces braces;
48175 if (!braces.require_open (parser))
48176 return error_mark_node;
48177
48178 tree selectors
48179 = cp_parser_omp_context_selector (parser, set, has_parms_p);
48180 if (selectors == error_mark_node)
48181 {
48182 cp_parser_skip_to_closing_brace (parser);
48183 ret = error_mark_node;
48184 }
48185 else if (ret != error_mark_node)
48186 ret = make_trait_set_selector (set, selectors, ret);
48187
48188 braces.require_close (parser);
48189
48190 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
48191 cp_lexer_consume_token (lexer: parser->lexer);
48192 else
48193 break;
48194 }
48195 while (1);
48196
48197 if (ret == error_mark_node)
48198 return ret;
48199 return nreverse (ret);
48200}
48201
48202/* Assumption clauses:
48203 OpenMP 5.1
48204 absent (directive-name-list)
48205 contains (directive-name-list)
48206 holds (expression)
48207 no_openmp
48208 no_openmp_routines
48209 no_parallelism */
48210
48211static void
48212cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
48213 bool is_assume)
48214{
48215 bool no_openmp = false;
48216 bool no_openmp_routines = false;
48217 bool no_parallelism = false;
48218 bitmap_head absent_head, contains_head;
48219
48220 bitmap_obstack_initialize (NULL);
48221 bitmap_initialize (head: &absent_head, obstack: &bitmap_default_obstack);
48222 bitmap_initialize (head: &contains_head, obstack: &bitmap_default_obstack);
48223
48224 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
48225 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
48226 "expected at least one assumption clause");
48227
48228 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
48229 {
48230 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
48231 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
48232 cp_lexer_consume_token (lexer: parser->lexer);
48233
48234 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
48235 break;
48236
48237 const char *p
48238 = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
48239 location_t cloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
48240
48241 if (!strcmp (s1: p, s2: "no_openmp"))
48242 {
48243 cp_lexer_consume_token (lexer: parser->lexer);
48244 if (no_openmp)
48245 error_at (cloc, "too many %qs clauses", "no_openmp");
48246 no_openmp = true;
48247 }
48248 else if (!strcmp (s1: p, s2: "no_openmp_routines"))
48249 {
48250 cp_lexer_consume_token (lexer: parser->lexer);
48251 if (no_openmp_routines)
48252 error_at (cloc, "too many %qs clauses", "no_openmp_routines");
48253 no_openmp_routines = true;
48254 }
48255 else if (!strcmp (s1: p, s2: "no_parallelism"))
48256 {
48257 cp_lexer_consume_token (lexer: parser->lexer);
48258 if (no_parallelism)
48259 error_at (cloc, "too many %qs clauses", "no_parallelism");
48260 no_parallelism = true;
48261 }
48262 else if (!strcmp (s1: p, s2: "holds"))
48263 {
48264 cp_lexer_consume_token (lexer: parser->lexer);
48265 matching_parens parens;
48266 if (parens.require_open (parser))
48267 {
48268 location_t eloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
48269 tree t = cp_parser_assignment_expression (parser);
48270 if (!type_dependent_expression_p (t))
48271 t = contextual_conv_bool (t, tf_warning_or_error);
48272 if (is_assume && !error_operand_p (t))
48273 finish_expr_stmt (build_assume_call (eloc, t));
48274 if (!parens.require_close (parser))
48275 cp_parser_skip_to_closing_parenthesis (parser,
48276 /*recovering=*/true,
48277 /*or_comma=*/false,
48278 /*consume_paren=*/true);
48279 }
48280 }
48281 else if (!strcmp (s1: p, s2: "absent") || !strcmp (s1: p, s2: "contains"))
48282 {
48283 cp_lexer_consume_token (lexer: parser->lexer);
48284 matching_parens parens;
48285 if (parens.require_open (parser))
48286 {
48287 do
48288 {
48289 const char *directive[3] = {};
48290 int i;
48291 location_t dloc
48292 = cp_lexer_peek_token (lexer: parser->lexer)->location;
48293 for (i = 0; i < 3; i++)
48294 {
48295 tree id;
48296 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: i + 1, type: CPP_NAME))
48297 id = cp_lexer_peek_nth_token (lexer: parser->lexer,
48298 n: i + 1)->u.value;
48299 else if (cp_lexer_nth_token_is (lexer: parser->lexer, n: i + 1,
48300 type: CPP_KEYWORD))
48301 {
48302 enum rid rid
48303 = cp_lexer_peek_nth_token (lexer: parser->lexer,
48304 n: i + 1)->keyword;
48305 id = ridpointers[rid];
48306 }
48307 else
48308 break;
48309 directive[i] = IDENTIFIER_POINTER (id);
48310 }
48311 if (i == 0)
48312 error_at (dloc, "expected directive name");
48313 else
48314 {
48315 const struct c_omp_directive *dir
48316 = c_omp_categorize_directive (directive[0],
48317 directive[1],
48318 directive[2]);
48319 if (dir == NULL
48320 || dir->kind == C_OMP_DIR_DECLARATIVE
48321 || dir->kind == C_OMP_DIR_INFORMATIONAL
48322 || dir->id == PRAGMA_OMP_END
48323 || (!dir->second && directive[1])
48324 || (!dir->third && directive[2]))
48325 error_at (dloc, "unknown OpenMP directive name in "
48326 "%qs clause argument", p);
48327 else
48328 {
48329 int id = dir - c_omp_directives;
48330 if (bitmap_bit_p (p[0] == 'a' ? &contains_head
48331 : &absent_head, id))
48332 error_at (dloc, "%<%s%s%s%s%s%> directive "
48333 "mentioned in both %<absent%> and "
48334 "%<contains%> clauses",
48335 directive[0],
48336 directive[1] ? " " : "",
48337 directive[1] ? directive[1] : "",
48338 directive[2] ? " " : "",
48339 directive[2] ? directive[2] : "");
48340 else if (!bitmap_set_bit (p[0] == 'a'
48341 ? &absent_head
48342 : &contains_head, id))
48343 error_at (dloc, "%<%s%s%s%s%s%> directive "
48344 "mentioned multiple times in %qs "
48345 "clauses",
48346 directive[0],
48347 directive[1] ? " " : "",
48348 directive[1] ? directive[1] : "",
48349 directive[2] ? " " : "",
48350 directive[2] ? directive[2] : "", p);
48351 }
48352 for (; i; --i)
48353 cp_lexer_consume_token (lexer: parser->lexer);
48354 }
48355 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
48356 cp_lexer_consume_token (lexer: parser->lexer);
48357 else
48358 break;
48359 }
48360 while (1);
48361 if (!parens.require_close (parser))
48362 cp_parser_skip_to_closing_parenthesis (parser,
48363 /*recovering=*/true,
48364 /*or_comma=*/false,
48365 /*consume_paren=*/true);
48366 }
48367 }
48368 else if (startswith (str: p, prefix: "ext_"))
48369 {
48370 warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
48371 cp_lexer_consume_token (lexer: parser->lexer);
48372 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
48373 for (size_t n = cp_parser_skip_balanced_tokens (parser, n: 1) - 1;
48374 n; --n)
48375 cp_lexer_consume_token (lexer: parser->lexer);
48376 }
48377 else
48378 {
48379 cp_lexer_consume_token (lexer: parser->lexer);
48380 error_at (cloc, "expected assumption clause");
48381 break;
48382 }
48383 }
48384 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
48385}
48386
48387/* OpenMP 5.1
48388 # pragma omp assume clauses[optseq] new-line */
48389
48390static void
48391cp_parser_omp_assume (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
48392{
48393 cp_parser_omp_assumption_clauses (parser, pragma_tok, is_assume: true);
48394 add_stmt (cp_parser_omp_structured_block (parser, if_p));
48395}
48396
48397/* OpenMP 5.1
48398 # pragma omp assumes clauses[optseq] new-line */
48399
48400static bool
48401cp_parser_omp_assumes (cp_parser *parser, cp_token *pragma_tok)
48402{
48403 cp_parser_omp_assumption_clauses (parser, pragma_tok, is_assume: false);
48404 return false;
48405}
48406
48407/* Finalize #pragma omp declare variant after a fndecl has been parsed, and put
48408 that into "omp declare variant base" attribute. */
48409
48410static tree
48411cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
48412 tree attrs)
48413{
48414 matching_parens parens;
48415 if (!parens.require_open (parser))
48416 {
48417 fail:
48418 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
48419 return attrs;
48420 }
48421
48422 bool template_p;
48423 cp_id_kind idk = CP_ID_KIND_NONE;
48424 cp_token *varid_token = cp_lexer_peek_token (lexer: parser->lexer);
48425 cp_expr varid
48426 = cp_parser_id_expression (parser, /*template_keyword_p=*/false,
48427 /*check_dependency_p=*/true,
48428 /*template_p=*/&template_p,
48429 /*declarator_p=*/false,
48430 /*optional_p=*/false);
48431 parens.require_close (parser);
48432
48433 tree variant;
48434 if (TREE_CODE (varid) == TEMPLATE_ID_EXPR
48435 || TREE_CODE (varid) == TYPE_DECL
48436 || varid == error_mark_node)
48437 variant = varid;
48438 else if (varid_token->type == CPP_NAME && varid_token->error_reported)
48439 variant = NULL_TREE;
48440 else
48441 {
48442 tree ambiguous_decls;
48443 variant = cp_parser_lookup_name (parser, name: varid, tag_type: none_type,
48444 is_template: template_p, /*is_namespace=*/false,
48445 /*check_dependency=*/true,
48446 ambiguous_decls: &ambiguous_decls,
48447 name_location: varid.get_location ());
48448 if (ambiguous_decls)
48449 variant = NULL_TREE;
48450 }
48451 if (variant == NULL_TREE)
48452 variant = error_mark_node;
48453 else if (TREE_CODE (variant) != SCOPE_REF)
48454 {
48455 const char *error_msg;
48456 variant
48457 = finish_id_expression (varid, variant, parser->scope,
48458 &idk, false, true,
48459 &parser->non_integral_constant_expression_p,
48460 template_p, true, false, false, &error_msg,
48461 varid.get_location ());
48462 if (error_msg)
48463 cp_parser_error (parser, gmsgid: error_msg);
48464 }
48465 location_t caret_loc = get_pure_location (loc: varid.get_location ());
48466 location_t start_loc = get_start (loc: varid_token->location);
48467 location_t finish_loc = get_finish (loc: varid.get_location ());
48468 location_t varid_loc = make_location (caret: caret_loc, start: start_loc, finish: finish_loc);
48469
48470 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
48471 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
48472 cp_lexer_consume_token (lexer: parser->lexer);
48473
48474 const char *clause = "";
48475 location_t match_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
48476 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
48477 clause = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
48478 if (strcmp (s1: clause, s2: "match"))
48479 {
48480 cp_parser_error (parser, gmsgid: "expected %<match%>");
48481 goto fail;
48482 }
48483
48484 cp_lexer_consume_token (lexer: parser->lexer);
48485
48486 if (!parens.require_open (parser))
48487 goto fail;
48488
48489 tree ctx = cp_parser_omp_context_selector_specification (parser, has_parms_p: true);
48490 if (ctx == error_mark_node)
48491 goto fail;
48492 ctx = omp_check_context_selector (loc: match_loc, ctx);
48493 if (ctx != error_mark_node && variant != error_mark_node)
48494 {
48495 tree match_loc_node = maybe_wrap_with_location (integer_zero_node,
48496 match_loc);
48497 tree loc_node = maybe_wrap_with_location (integer_zero_node, varid_loc);
48498 loc_node = tree_cons (match_loc_node,
48499 build_int_cst (integer_type_node, idk),
48500 build_tree_list (loc_node, integer_zero_node));
48501 attrs = tree_cons (get_identifier ("omp declare variant base"),
48502 tree_cons (variant, ctx, loc_node), attrs);
48503 if (processing_template_decl)
48504 ATTR_IS_DEPENDENT (attrs) = 1;
48505 }
48506
48507 parens.require_close (parser);
48508 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
48509 return attrs;
48510}
48511
48512
48513/* Finalize #pragma omp declare simd clauses after direct declarator has
48514 been parsed, and put that into "omp declare simd" attribute. */
48515
48516static tree
48517cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
48518{
48519 struct cp_token_cache *ce;
48520 cp_omp_declare_simd_data *data = parser->omp_declare_simd;
48521 int i;
48522
48523 if (!data->error_seen && data->fndecl_seen)
48524 {
48525 error ("%<#pragma omp declare %s%> not immediately followed by "
48526 "a single function declaration or definition",
48527 data->variant_p ? "variant" : "simd");
48528 data->error_seen = true;
48529 }
48530 if (data->error_seen)
48531 return attrs;
48532
48533 FOR_EACH_VEC_ELT (data->tokens, i, ce)
48534 {
48535 tree c, cl;
48536
48537 cp_parser_push_lexer_for_tokens (parser, cache: ce);
48538 parser->lexer->in_pragma = true;
48539 gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);
48540 cp_token *pragma_tok = cp_lexer_consume_token (lexer: parser->lexer);
48541 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
48542 const char *kind = IDENTIFIER_POINTER (id);
48543 cp_lexer_consume_token (lexer: parser->lexer);
48544 if (strcmp (s1: kind, s2: "simd") == 0)
48545 {
48546 cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
48547 where: "#pragma omp declare simd",
48548 pragma_tok);
48549 if (cl)
48550 cl = tree_cons (NULL_TREE, cl, NULL_TREE);
48551 c = build_tree_list (get_identifier ("omp declare simd"), cl);
48552 TREE_CHAIN (c) = attrs;
48553 if (processing_template_decl)
48554 ATTR_IS_DEPENDENT (c) = 1;
48555 attrs = c;
48556 }
48557 else
48558 {
48559 gcc_assert (strcmp (kind, "variant") == 0);
48560 attrs
48561 = cp_finish_omp_declare_variant (parser, pragma_tok, attrs);
48562 }
48563 cp_parser_pop_lexer (parser);
48564 }
48565
48566 cp_lexer *lexer = NULL;
48567 for (int i = 0; i < 2; i++)
48568 {
48569 if (data->attribs[i] == NULL)
48570 continue;
48571 for (tree *pa = data->attribs[i]; *pa; )
48572 if (get_attribute_namespace (*pa) == omp_identifier
48573 && is_attribute_p (attr_name: "directive", ident: get_attribute_name (*pa)))
48574 {
48575 for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
48576 {
48577 tree d = TREE_VALUE (a);
48578 gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
48579 cp_token *first = DEFPARSE_TOKENS (d)->first;
48580 cp_token *last = DEFPARSE_TOKENS (d)->last;
48581 const char *directive[3] = {};
48582 for (int j = 0; j < 3; j++)
48583 {
48584 tree id = NULL_TREE;
48585 if (first + j == last)
48586 break;
48587 if (first[j].type == CPP_NAME)
48588 id = first[j].u.value;
48589 else if (first[j].type == CPP_KEYWORD)
48590 id = ridpointers[(int) first[j].keyword];
48591 else
48592 break;
48593 directive[j] = IDENTIFIER_POINTER (id);
48594 }
48595 const c_omp_directive *dir = NULL;
48596 if (directive[0])
48597 dir = c_omp_categorize_directive (directive[0], directive[1],
48598 directive[2]);
48599 if (dir == NULL)
48600 {
48601 error_at (first->location,
48602 "unknown OpenMP directive name in "
48603 "%qs attribute argument",
48604 TREE_PUBLIC (d)
48605 ? "omp::decl" : "omp::directive");
48606 continue;
48607 }
48608 if (dir->id != PRAGMA_OMP_DECLARE
48609 || (strcmp (s1: directive[1], s2: "simd") != 0
48610 && strcmp (s1: directive[1], s2: "variant") != 0))
48611 {
48612 error_at (first->location,
48613 "OpenMP directive other than %<declare simd%> "
48614 "or %<declare variant%> appertains to a "
48615 "declaration");
48616 continue;
48617 }
48618
48619 if (parser->omp_attrs_forbidden_p)
48620 {
48621 error_at (first->location,
48622 "mixing OpenMP directives with attribute and "
48623 "pragma syntax on the same statement");
48624 parser->omp_attrs_forbidden_p = false;
48625 }
48626
48627 if (!flag_openmp && strcmp (s1: directive[1], s2: "simd") != 0)
48628 continue;
48629 if (lexer == NULL)
48630 {
48631 lexer = cp_lexer_alloc ();
48632 lexer->debugging_p = parser->lexer->debugging_p;
48633 }
48634 vec_safe_reserve (v&: lexer->buffer, nelems: (last - first) + 2);
48635 cp_token tok = {};
48636 tok.type = CPP_PRAGMA;
48637 tok.keyword = RID_MAX;
48638 tok.u.value = build_int_cst (NULL, PRAGMA_OMP_DECLARE);
48639 tok.location = first->location;
48640 lexer->buffer->quick_push (obj: tok);
48641 while (++first < last)
48642 lexer->buffer->quick_push (obj: *first);
48643 tok = {};
48644 tok.type = CPP_PRAGMA_EOL;
48645 tok.keyword = RID_MAX;
48646 tok.location = last->location;
48647 lexer->buffer->quick_push (obj: tok);
48648 tok = {};
48649 tok.type = CPP_EOF;
48650 tok.keyword = RID_MAX;
48651 tok.location = last->location;
48652 lexer->buffer->quick_push (obj: tok);
48653 lexer->next = parser->lexer;
48654 lexer->next_token = lexer->buffer->address ();
48655 lexer->last_token = lexer->next_token
48656 + lexer->buffer->length ()
48657 - 1;
48658 lexer->in_omp_attribute_pragma = true;
48659 parser->lexer = lexer;
48660 /* Move the current source position to that of the first token
48661 in the new lexer. */
48662 cp_lexer_set_source_position_from_token (token: lexer->next_token);
48663
48664 cp_token *pragma_tok = cp_lexer_consume_token (lexer: parser->lexer);
48665 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
48666 const char *kind = IDENTIFIER_POINTER (id);
48667 cp_lexer_consume_token (lexer: parser->lexer);
48668
48669 tree c, cl;
48670 if (strcmp (s1: kind, s2: "simd") == 0)
48671 {
48672 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
48673 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
48674 cp_lexer_consume_token (lexer: parser->lexer);
48675
48676 omp_clause_mask mask = OMP_DECLARE_SIMD_CLAUSE_MASK;
48677 cl = cp_parser_omp_all_clauses (parser, mask,
48678 where: "#pragma omp declare simd",
48679 pragma_tok);
48680 if (cl)
48681 cl = tree_cons (NULL_TREE, cl, NULL_TREE);
48682 c = build_tree_list (get_identifier ("omp declare simd"),
48683 cl);
48684 TREE_CHAIN (c) = attrs;
48685 if (processing_template_decl)
48686 ATTR_IS_DEPENDENT (c) = 1;
48687 attrs = c;
48688 }
48689 else
48690 {
48691 gcc_assert (strcmp (kind, "variant") == 0);
48692 attrs
48693 = cp_finish_omp_declare_variant (parser, pragma_tok,
48694 attrs);
48695 }
48696 gcc_assert (parser->lexer != lexer);
48697 vec_safe_truncate (v: lexer->buffer, size: 0);
48698 }
48699 *pa = TREE_CHAIN (*pa);
48700 }
48701 else
48702 pa = &TREE_CHAIN (*pa);
48703 }
48704 if (lexer)
48705 cp_lexer_destroy (lexer);
48706
48707 data->fndecl_seen = true;
48708 return attrs;
48709}
48710
48711/* D should be DEFERRED_PARSE from omp::decl attribute. If it contains
48712 a threadprivate, groupprivate, allocate or declare target directive,
48713 return true and parse it for DECL. */
48714
48715bool
48716cp_maybe_parse_omp_decl (tree decl, tree d)
48717{
48718 gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
48719 cp_token *first = DEFPARSE_TOKENS (d)->first;
48720 cp_token *last = DEFPARSE_TOKENS (d)->last;
48721 const char *directive[3] = {};
48722 for (int j = 0; j < 3; j++)
48723 {
48724 tree id = NULL_TREE;
48725 if (first + j == last)
48726 break;
48727 if (first[j].type == CPP_NAME)
48728 id = first[j].u.value;
48729 else if (first[j].type == CPP_KEYWORD)
48730 id = ridpointers[(int) first[j].keyword];
48731 else
48732 break;
48733 directive[j] = IDENTIFIER_POINTER (id);
48734 }
48735 const c_omp_directive *dir = NULL;
48736 if (directive[0])
48737 dir = c_omp_categorize_directive (directive[0], directive[1],
48738 directive[2]);
48739 if (dir == NULL)
48740 {
48741 error_at (first->location,
48742 "unknown OpenMP directive name in "
48743 "%qs attribute argument", "omp::decl");
48744 return false;
48745 }
48746 if (dir->id != PRAGMA_OMP_THREADPRIVATE
48747 /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
48748 && dir->id != PRAGMA_OMP_ALLOCATE
48749 && (dir->id != PRAGMA_OMP_DECLARE
48750 || strcmp (s1: directive[1], s2: "target") != 0))
48751 return false;
48752
48753 if (!flag_openmp && !dir->simd)
48754 return true;
48755
48756 cp_parser *parser = the_parser;
48757 cp_lexer *lexer = cp_lexer_alloc ();
48758 lexer->debugging_p = parser->lexer->debugging_p;
48759 lexer->in_omp_decl_attribute = decl;
48760 vec_safe_reserve (v&: lexer->buffer, nelems: last - first + 3, exact: true);
48761 cp_token tok = {};
48762 tok.type = CPP_PRAGMA;
48763 tok.keyword = RID_MAX;
48764 tok.u.value = build_int_cst (NULL, dir->id);
48765 tok.location = first->location;
48766 lexer->buffer->quick_push (obj: tok);
48767 while (++first < last)
48768 lexer->buffer->quick_push (obj: *first);
48769 tok = {};
48770 tok.type = CPP_PRAGMA_EOL;
48771 tok.keyword = RID_MAX;
48772 tok.location = last->location;
48773 lexer->buffer->quick_push (obj: tok);
48774 tok = {};
48775 tok.type = CPP_EOF;
48776 tok.keyword = RID_MAX;
48777 tok.location = last->location;
48778 lexer->buffer->quick_push (obj: tok);
48779 lexer->next = parser->lexer;
48780 lexer->next_token = lexer->buffer->address ();
48781 lexer->last_token = lexer->next_token
48782 + lexer->buffer->length ()
48783 - 1;
48784 lexer->in_omp_attribute_pragma = true;
48785 parser->lexer = lexer;
48786 /* Move the current source position to that of the first token in the
48787 new lexer. */
48788 cp_lexer_set_source_position_from_token (token: lexer->next_token);
48789 cp_parser_pragma (parser, pragma_external, NULL);
48790
48791 return true;
48792}
48793
48794/* Helper for cp_parser_omp_declare_target, handle one to or link clause
48795 on #pragma omp declare target. Return false if errors were reported. */
48796
48797static bool
48798handle_omp_declare_target_clause (tree c, tree t, int device_type,
48799 bool indirect)
48800{
48801 tree at1 = lookup_attribute (attr_name: "omp declare target", DECL_ATTRIBUTES (t));
48802 tree at2 = lookup_attribute (attr_name: "omp declare target link", DECL_ATTRIBUTES (t));
48803 tree id;
48804 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
48805 {
48806 id = get_identifier ("omp declare target link");
48807 std::swap (a&: at1, b&: at2);
48808 }
48809 else
48810 id = get_identifier ("omp declare target");
48811 if (at2)
48812 {
48813 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
48814 error_at (OMP_CLAUSE_LOCATION (c),
48815 "%qD specified both in declare target %<link%> and %qs"
48816 " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
48817 else
48818 error_at (OMP_CLAUSE_LOCATION (c),
48819 "%qD specified both in declare target %<link%> and "
48820 "%<to%> or %<enter%> clauses", t);
48821 return false;
48822 }
48823 if (!at1)
48824 {
48825 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
48826 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
48827 return true;
48828
48829 symtab_node *node = symtab_node::get (decl: t);
48830 if (node != NULL)
48831 {
48832 node->offloadable = 1;
48833 if (ENABLE_OFFLOADING)
48834 {
48835 g->have_offload = true;
48836 if (is_a <varpool_node *> (p: node))
48837 vec_safe_push (v&: offload_vars, obj: t);
48838 }
48839 }
48840 }
48841 if (TREE_CODE (t) != FUNCTION_DECL)
48842 return true;
48843 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
48844 {
48845 tree at3 = lookup_attribute (attr_name: "omp declare target host",
48846 DECL_ATTRIBUTES (t));
48847 if (at3 == NULL_TREE)
48848 {
48849 id = get_identifier ("omp declare target host");
48850 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
48851 }
48852 }
48853 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
48854 {
48855 tree at3 = lookup_attribute (attr_name: "omp declare target nohost",
48856 DECL_ATTRIBUTES (t));
48857 if (at3 == NULL_TREE)
48858 {
48859 id = get_identifier ("omp declare target nohost");
48860 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
48861 }
48862 }
48863 if (indirect)
48864 {
48865 tree at4 = lookup_attribute (attr_name: "omp declare target indirect",
48866 DECL_ATTRIBUTES (t));
48867 if (at4 == NULL_TREE)
48868 {
48869 id = get_identifier ("omp declare target indirect");
48870 DECL_ATTRIBUTES (t)
48871 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
48872 }
48873 }
48874 return true;
48875}
48876
48877/* OpenMP 4.0:
48878 # pragma omp declare target new-line
48879 declarations and definitions
48880 # pragma omp end declare target new-line
48881
48882 OpenMP 4.5:
48883 # pragma omp declare target ( extended-list ) new-line
48884
48885 # pragma omp declare target declare-target-clauses[seq] new-line */
48886
48887#define OMP_DECLARE_TARGET_CLAUSE_MASK \
48888 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
48889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
48890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
48891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
48892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
48893
48894static void
48895cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
48896{
48897 tree clauses = NULL_TREE;
48898 int device_type = 0;
48899 bool indirect = false;
48900 bool only_device_type_or_indirect = true;
48901 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME)
48902 || (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
48903 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME)))
48904 clauses
48905 = cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
48906 where: "#pragma omp declare target", pragma_tok);
48907 else if (parser->lexer->in_omp_decl_attribute
48908 || cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
48909 {
48910 clauses = cp_parser_omp_var_list (parser, kind: OMP_CLAUSE_ENTER,
48911 list: clauses);
48912 clauses = finish_omp_clauses (clauses, C_ORT_OMP);
48913 cp_parser_require_pragma_eol (parser, pragma_tok);
48914 }
48915 else
48916 {
48917 cp_omp_declare_target_attr a
48918 = { .attr_syntax: parser->lexer->in_omp_attribute_pragma, .device_type: -1, .indirect: false };
48919 vec_safe_push (v&: scope_chain->omp_declare_target_attribute, obj: a);
48920 cp_parser_require_pragma_eol (parser, pragma_tok);
48921 return;
48922 }
48923 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
48924 {
48925 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
48926 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
48927 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
48928 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
48929 }
48930 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
48931 {
48932 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
48933 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
48934 continue;
48935 tree t = OMP_CLAUSE_DECL (c);
48936 only_device_type_or_indirect = false;
48937 if (!handle_omp_declare_target_clause (c, t, device_type, indirect))
48938 continue;
48939 if (VAR_OR_FUNCTION_DECL_P (t)
48940 && DECL_LOCAL_DECL_P (t)
48941 && DECL_LANG_SPECIFIC (t)
48942 && DECL_LOCAL_DECL_ALIAS (t)
48943 && DECL_LOCAL_DECL_ALIAS (t) != error_mark_node)
48944 handle_omp_declare_target_clause (c, DECL_LOCAL_DECL_ALIAS (t),
48945 device_type, indirect);
48946 }
48947 if ((device_type || indirect) && only_device_type_or_indirect)
48948 error_at (OMP_CLAUSE_LOCATION (clauses),
48949 "directive with only %<device_type%> or %<indirect%> clauses");
48950 if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
48951 error_at (OMP_CLAUSE_LOCATION (clauses),
48952 "%<device_type%> clause must specify 'any' when used with "
48953 "an %<indirect%> clause");
48954}
48955
48956/* OpenMP 5.1
48957 # pragma omp begin assumes clauses[optseq] new-line
48958
48959 # pragma omp begin declare target clauses[optseq] new-line */
48960
48961#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK \
48962 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) \
48963 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
48964
48965static void
48966cp_parser_omp_begin (cp_parser *parser, cp_token *pragma_tok)
48967{
48968 const char *p = "";
48969 bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
48970 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
48971 {
48972 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
48973 p = IDENTIFIER_POINTER (id);
48974 }
48975 if (strcmp (s1: p, s2: "declare") == 0)
48976 {
48977 cp_lexer_consume_token (lexer: parser->lexer);
48978 p = "";
48979 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
48980 {
48981 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
48982 p = IDENTIFIER_POINTER (id);
48983 }
48984 if (strcmp (s1: p, s2: "target") == 0)
48985 {
48986 cp_lexer_consume_token (lexer: parser->lexer);
48987 tree clauses
48988 = cp_parser_omp_all_clauses (parser,
48989 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
48990 where: "#pragma omp begin declare target",
48991 pragma_tok);
48992 int device_type = 0;
48993 bool indirect = 0;
48994 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
48995 {
48996 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
48997 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
48998 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
48999 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
49000 }
49001 cp_omp_declare_target_attr a
49002 = { .attr_syntax: in_omp_attribute_pragma, .device_type: device_type, .indirect: indirect };
49003 vec_safe_push (v&: scope_chain->omp_declare_target_attribute, obj: a);
49004 }
49005 else
49006 {
49007 cp_parser_error (parser, gmsgid: "expected %<target%>");
49008 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49009 }
49010 }
49011 else if (strcmp (s1: p, s2: "assumes") == 0)
49012 {
49013 cp_lexer_consume_token (lexer: parser->lexer);
49014 cp_parser_omp_assumption_clauses (parser, pragma_tok, is_assume: false);
49015 cp_omp_begin_assumes_data a = { .attr_syntax: in_omp_attribute_pragma };
49016 vec_safe_push (v&: scope_chain->omp_begin_assumes, obj: a);
49017 }
49018 else
49019 {
49020 cp_parser_error (parser, gmsgid: "expected %<declare target%> or %<assumes%>");
49021 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49022 }
49023}
49024
49025/* OpenMP 4.0:
49026 # pragma omp end declare target new-line
49027
49028 OpenMP 5.1:
49029 # pragma omp end assumes new-line */
49030
49031static void
49032cp_parser_omp_end (cp_parser *parser, cp_token *pragma_tok)
49033{
49034 const char *p = "";
49035 bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
49036 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49037 {
49038 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49039 p = IDENTIFIER_POINTER (id);
49040 }
49041 if (strcmp (s1: p, s2: "declare") == 0)
49042 {
49043 cp_lexer_consume_token (lexer: parser->lexer);
49044 p = "";
49045 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49046 {
49047 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49048 p = IDENTIFIER_POINTER (id);
49049 }
49050 if (strcmp (s1: p, s2: "target") == 0)
49051 cp_lexer_consume_token (lexer: parser->lexer);
49052 else
49053 {
49054 cp_parser_error (parser, gmsgid: "expected %<target%>");
49055 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49056 return;
49057 }
49058 cp_parser_require_pragma_eol (parser, pragma_tok);
49059 if (!vec_safe_length (v: scope_chain->omp_declare_target_attribute))
49060 error_at (pragma_tok->location,
49061 "%<#pragma omp end declare target%> without corresponding "
49062 "%<#pragma omp declare target%> or "
49063 "%<#pragma omp begin declare target%>");
49064 else
49065 {
49066 cp_omp_declare_target_attr
49067 a = scope_chain->omp_declare_target_attribute->pop ();
49068 if (a.attr_syntax != in_omp_attribute_pragma)
49069 {
49070 if (a.attr_syntax)
49071 error_at (pragma_tok->location,
49072 "%qs in attribute syntax terminated "
49073 "with %qs in pragma syntax",
49074 a.device_type >= 0 ? "begin declare target"
49075 : "declare target",
49076 "end declare target");
49077 else
49078 error_at (pragma_tok->location,
49079 "%qs in pragma syntax terminated "
49080 "with %qs in attribute syntax",
49081 a.device_type >= 0 ? "begin declare target"
49082 : "declare target",
49083 "end declare target");
49084 }
49085 }
49086 }
49087 else if (strcmp (s1: p, s2: "assumes") == 0)
49088 {
49089 cp_lexer_consume_token (lexer: parser->lexer);
49090 cp_parser_require_pragma_eol (parser, pragma_tok);
49091 if (!vec_safe_length (v: scope_chain->omp_begin_assumes))
49092 error_at (pragma_tok->location,
49093 "%qs without corresponding %qs",
49094 "#pragma omp end assumes", "#pragma omp begin assumes");
49095 else
49096 {
49097 cp_omp_begin_assumes_data
49098 a = scope_chain->omp_begin_assumes->pop ();
49099 if (a.attr_syntax != in_omp_attribute_pragma)
49100 {
49101 if (a.attr_syntax)
49102 error_at (pragma_tok->location,
49103 "%qs in attribute syntax terminated "
49104 "with %qs in pragma syntax",
49105 "begin assumes", "end assumes");
49106 else
49107 error_at (pragma_tok->location,
49108 "%qs in pragma syntax terminated "
49109 "with %qs in attribute syntax",
49110 "begin assumes", "end assumes");
49111 }
49112 }
49113 }
49114 else
49115 {
49116 cp_parser_error (parser, gmsgid: "expected %<declare%> or %<assumes%>");
49117 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49118 return;
49119 }
49120}
49121
49122/* Helper function of cp_parser_omp_declare_reduction. Parse the combiner
49123 expression and optional initializer clause of
49124 #pragma omp declare reduction. We store the expression(s) as
49125 either 3, 6 or 7 special statements inside of the artificial function's
49126 body. The first two statements are DECL_EXPRs for the artificial
49127 OMP_OUT resp. OMP_IN variables, followed by a statement with the combiner
49128 expression that uses those variables.
49129 If there was any INITIALIZER clause, this is followed by further statements,
49130 the fourth and fifth statements are DECL_EXPRs for the artificial
49131 OMP_PRIV resp. OMP_ORIG variables. If the INITIALIZER clause wasn't the
49132 constructor variant (first token after open paren is not omp_priv),
49133 then the sixth statement is a statement with the function call expression
49134 that uses the OMP_PRIV and optionally OMP_ORIG variable.
49135 Otherwise, the sixth statement is whatever statement cp_finish_decl emits
49136 to initialize the OMP_PRIV artificial variable and there is seventh
49137 statement, a DECL_EXPR of the OMP_PRIV statement again. */
49138
49139static bool
49140cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
49141{
49142 tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
49143 gcc_assert (TYPE_REF_P (type));
49144 type = TREE_TYPE (type);
49145 tree omp_out = build_lang_decl (VAR_DECL, get_identifier ("omp_out"), type);
49146 DECL_ARTIFICIAL (omp_out) = 1;
49147 pushdecl (omp_out);
49148 add_decl_expr (omp_out);
49149 tree omp_in = build_lang_decl (VAR_DECL, get_identifier ("omp_in"), type);
49150 DECL_ARTIFICIAL (omp_in) = 1;
49151 pushdecl (omp_in);
49152 add_decl_expr (omp_in);
49153 tree combiner;
49154 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE, initializer = NULL_TREE;
49155
49156 keep_next_level (true);
49157 tree block = begin_omp_structured_block ();
49158 combiner = cp_parser_expression (parser);
49159 finish_expr_stmt (combiner);
49160 block = finish_omp_structured_block (block);
49161 if (processing_template_decl)
49162 block = build_stmt (input_location, EXPR_STMT, block);
49163 add_stmt (block);
49164
49165 if (!cp_parser_require (parser, type: CPP_CLOSE_PAREN, token_desc: RT_CLOSE_PAREN))
49166 return false;
49167
49168 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
49169 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
49170 cp_lexer_consume_token (lexer: parser->lexer);
49171
49172 const char *p = "";
49173 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49174 {
49175 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49176 p = IDENTIFIER_POINTER (id);
49177 }
49178
49179 if (strcmp (s1: p, s2: "initializer") == 0)
49180 {
49181 cp_lexer_consume_token (lexer: parser->lexer);
49182 matching_parens parens;
49183 if (!parens.require_open (parser))
49184 return false;
49185
49186 p = "";
49187 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49188 {
49189 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49190 p = IDENTIFIER_POINTER (id);
49191 }
49192
49193 omp_priv = build_lang_decl (VAR_DECL, get_identifier ("omp_priv"), type);
49194 DECL_ARTIFICIAL (omp_priv) = 1;
49195 pushdecl (omp_priv);
49196 add_decl_expr (omp_priv);
49197 omp_orig = build_lang_decl (VAR_DECL, get_identifier ("omp_orig"), type);
49198 DECL_ARTIFICIAL (omp_orig) = 1;
49199 pushdecl (omp_orig);
49200 add_decl_expr (omp_orig);
49201
49202 keep_next_level (true);
49203 block = begin_omp_structured_block ();
49204
49205 bool ctor = false;
49206 if (strcmp (s1: p, s2: "omp_priv") == 0)
49207 {
49208 bool is_non_constant_init;
49209 ctor = true;
49210 cp_lexer_consume_token (lexer: parser->lexer);
49211 /* Reject initializer (omp_priv) and initializer (omp_priv ()). */
49212 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_CLOSE_PAREN)
49213 || (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN)
49214 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2)->type
49215 == CPP_CLOSE_PAREN
49216 && cp_lexer_peek_nth_token (lexer: parser->lexer, n: 3)->type
49217 == CPP_CLOSE_PAREN))
49218 {
49219 finish_omp_structured_block (block);
49220 error ("invalid initializer clause");
49221 return false;
49222 }
49223 initializer = cp_parser_initializer (parser,
49224 /*is_direct_init=*/nullptr,
49225 non_constant_p: &is_non_constant_init);
49226 cp_finish_decl (omp_priv, initializer, !is_non_constant_init,
49227 NULL_TREE, LOOKUP_ONLYCONVERTING);
49228 }
49229 else
49230 {
49231 cp_parser_parse_tentatively (parser);
49232 /* Don't create location wrapper nodes here. */
49233 auto_suppress_location_wrappers sentinel;
49234 tree fn_name = cp_parser_id_expression (parser, /*template_p=*/template_keyword_p: false,
49235 /*check_dependency_p=*/true,
49236 /*template_p=*/NULL,
49237 /*declarator_p=*/false,
49238 /*optional_p=*/false);
49239 vec<tree, va_gc> *args;
49240 if (fn_name == error_mark_node
49241 || cp_parser_error_occurred (parser)
49242 || !cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN)
49243 || ((args = cp_parser_parenthesized_expression_list
49244 (parser, is_attribute_list: non_attr, /*cast_p=*/false,
49245 /*allow_expansion_p=*/true,
49246 /*non_constant_p=*/NULL)),
49247 cp_parser_error_occurred (parser)))
49248 {
49249 finish_omp_structured_block (block);
49250 cp_parser_abort_tentative_parse (parser);
49251 cp_parser_error (parser, gmsgid: "expected id-expression (arguments)");
49252 return false;
49253 }
49254 unsigned int i;
49255 tree arg;
49256 FOR_EACH_VEC_SAFE_ELT (args, i, arg)
49257 if (arg == omp_priv
49258 || (TREE_CODE (arg) == ADDR_EXPR
49259 && TREE_OPERAND (arg, 0) == omp_priv))
49260 break;
49261 cp_parser_abort_tentative_parse (parser);
49262 if (arg == NULL_TREE)
49263 error ("one of the initializer call arguments should be %<omp_priv%>"
49264 " or %<&omp_priv%>");
49265 initializer = cp_parser_postfix_expression (parser, address_p: false, cast_p: false, member_access_only_p: false,
49266 decltype_p: false, NULL);
49267 finish_expr_stmt (initializer);
49268 }
49269
49270 block = finish_omp_structured_block (block);
49271 cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL);
49272 if (processing_template_decl)
49273 block = build_stmt (input_location, EXPR_STMT, block);
49274 add_stmt (block);
49275
49276 if (ctor)
49277 add_decl_expr (omp_orig);
49278
49279 if (!parens.require_close (parser))
49280 return false;
49281 }
49282
49283 if (!cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
49284 cp_parser_required_error (parser, token_desc: RT_PRAGMA_EOL, /*keyword=*/false,
49285 UNKNOWN_LOCATION);
49286
49287 return true;
49288}
49289
49290/* OpenMP 4.0
49291 #pragma omp declare reduction (reduction-id : typename-list : expression) \
49292 initializer-clause[opt] new-line
49293
49294 initializer-clause:
49295 initializer (omp_priv initializer)
49296 initializer (function-name (argument-list)) */
49297
49298static void
49299cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
49300 enum pragma_context)
49301{
49302 auto_vec<tree> types;
49303 enum tree_code reduc_code = ERROR_MARK;
49304 tree reduc_id = NULL_TREE, orig_reduc_id = NULL_TREE, type;
49305 unsigned int i;
49306 cp_token *first_token;
49307 cp_token_cache *cp;
49308 int errs;
49309 void *p;
49310
49311 /* Get the high-water mark for the DECLARATOR_OBSTACK. */
49312 p = obstack_alloc (&declarator_obstack, 0);
49313
49314 if (!cp_parser_require (parser, type: CPP_OPEN_PAREN, token_desc: RT_OPEN_PAREN))
49315 goto fail;
49316
49317 switch (cp_lexer_peek_token (lexer: parser->lexer)->type)
49318 {
49319 case CPP_PLUS:
49320 reduc_code = PLUS_EXPR;
49321 break;
49322 case CPP_MULT:
49323 reduc_code = MULT_EXPR;
49324 break;
49325 case CPP_MINUS:
49326 reduc_code = MINUS_EXPR;
49327 break;
49328 case CPP_AND:
49329 reduc_code = BIT_AND_EXPR;
49330 break;
49331 case CPP_XOR:
49332 reduc_code = BIT_XOR_EXPR;
49333 break;
49334 case CPP_OR:
49335 reduc_code = BIT_IOR_EXPR;
49336 break;
49337 case CPP_AND_AND:
49338 reduc_code = TRUTH_ANDIF_EXPR;
49339 break;
49340 case CPP_OR_OR:
49341 reduc_code = TRUTH_ORIF_EXPR;
49342 break;
49343 case CPP_NAME:
49344 reduc_id = orig_reduc_id = cp_parser_identifier (parser);
49345 break;
49346 default:
49347 cp_parser_error (parser, gmsgid: "expected %<+%>, %<*%>, %<-%>, %<&%>, %<^%>, "
49348 "%<|%>, %<&&%>, %<||%> or identifier");
49349 goto fail;
49350 }
49351
49352 if (reduc_code != ERROR_MARK)
49353 cp_lexer_consume_token (lexer: parser->lexer);
49354
49355 reduc_id = omp_reduction_id (reduc_code, reduc_id, NULL_TREE);
49356 if (reduc_id == error_mark_node)
49357 goto fail;
49358
49359 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON))
49360 goto fail;
49361
49362 /* Types may not be defined in declare reduction type list. */
49363 const char *saved_message;
49364 saved_message = parser->type_definition_forbidden_message;
49365 parser->type_definition_forbidden_message
49366 = G_("types may not be defined in declare reduction type list");
49367 bool saved_colon_corrects_to_scope_p;
49368 saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
49369 parser->colon_corrects_to_scope_p = false;
49370 bool saved_colon_doesnt_start_class_def_p;
49371 saved_colon_doesnt_start_class_def_p
49372 = parser->colon_doesnt_start_class_def_p;
49373 parser->colon_doesnt_start_class_def_p = true;
49374
49375 while (true)
49376 {
49377 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
49378 type = cp_parser_type_id (parser);
49379 if (type == error_mark_node)
49380 ;
49381 else if (ARITHMETIC_TYPE_P (type)
49382 && (orig_reduc_id == NULL_TREE
49383 || (TREE_CODE (type) != COMPLEX_TYPE
49384 && (id_equal (id: orig_reduc_id, str: "min")
49385 || id_equal (id: orig_reduc_id, str: "max")))))
49386 error_at (loc, "predeclared arithmetic type %qT in "
49387 "%<#pragma omp declare reduction%>", type);
49388 else if (FUNC_OR_METHOD_TYPE_P (type)
49389 || TREE_CODE (type) == ARRAY_TYPE)
49390 error_at (loc, "function or array type %qT in "
49391 "%<#pragma omp declare reduction%>", type);
49392 else if (TYPE_REF_P (type))
49393 error_at (loc, "reference type %qT in "
49394 "%<#pragma omp declare reduction%>", type);
49395 else if (TYPE_QUALS_NO_ADDR_SPACE (type))
49396 error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
49397 "type %qT in %<#pragma omp declare reduction%>", type);
49398 else
49399 types.safe_push (obj: type);
49400
49401 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA))
49402 cp_lexer_consume_token (lexer: parser->lexer);
49403 else
49404 break;
49405 }
49406
49407 /* Restore the saved message. */
49408 parser->type_definition_forbidden_message = saved_message;
49409 parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
49410 parser->colon_doesnt_start_class_def_p
49411 = saved_colon_doesnt_start_class_def_p;
49412
49413 if (!cp_parser_require (parser, type: CPP_COLON, token_desc: RT_COLON)
49414 || types.is_empty ())
49415 {
49416 fail:
49417 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49418 goto done;
49419 }
49420
49421 first_token = cp_lexer_peek_token (lexer: parser->lexer);
49422 cp = NULL;
49423 errs = errorcount;
49424 FOR_EACH_VEC_ELT (types, i, type)
49425 {
49426 tree fntype
49427 = build_function_type_list (void_type_node,
49428 cp_build_reference_type (type, false),
49429 NULL_TREE);
49430 tree this_reduc_id = reduc_id;
49431 if (!dependent_type_p (type))
49432 this_reduc_id = omp_reduction_id (ERROR_MARK, reduc_id, type);
49433 tree fndecl = build_lang_decl (FUNCTION_DECL, this_reduc_id, fntype);
49434 DECL_SOURCE_LOCATION (fndecl) = pragma_tok->location;
49435 DECL_ARTIFICIAL (fndecl) = 1;
49436 DECL_EXTERNAL (fndecl) = 1;
49437 DECL_DECLARED_INLINE_P (fndecl) = 1;
49438 DECL_IGNORED_P (fndecl) = 1;
49439 DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1;
49440 SET_DECL_ASSEMBLER_NAME (fndecl, get_identifier ("<udr>"));
49441 DECL_ATTRIBUTES (fndecl)
49442 = tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
49443 DECL_ATTRIBUTES (fndecl));
49444 bool block_scope = false;
49445 if (current_function_decl)
49446 {
49447 block_scope = true;
49448 DECL_CONTEXT (fndecl) = current_function_decl;
49449 DECL_LOCAL_DECL_P (fndecl) = true;
49450 }
49451
49452 if (processing_template_decl)
49453 fndecl = push_template_decl (fndecl);
49454
49455 if (block_scope)
49456 {
49457 if (!processing_template_decl)
49458 pushdecl (fndecl);
49459 }
49460 else if (current_class_type)
49461 {
49462 if (cp == NULL)
49463 {
49464 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
49465 cp_lexer_consume_token (lexer: parser->lexer);
49466 cp = cp_token_cache_new (first: first_token,
49467 last: cp_lexer_peek_nth_token (lexer: parser->lexer,
49468 n: 2));
49469 }
49470 DECL_STATIC_FUNCTION_P (fndecl) = 1;
49471 finish_member_declaration (fndecl);
49472 DECL_PENDING_INLINE_INFO (fndecl) = cp;
49473 DECL_PENDING_INLINE_P (fndecl) = 1;
49474 vec_safe_push (unparsed_funs_with_definitions, obj: fndecl);
49475 continue;
49476 }
49477 else
49478 {
49479 DECL_CONTEXT (fndecl) = current_namespace;
49480 tree d = pushdecl (fndecl);
49481 /* We should never meet a matched duplicate decl. */
49482 gcc_checking_assert (d == error_mark_node || d == fndecl);
49483 }
49484
49485 tree block = NULL_TREE;
49486 if (!block_scope)
49487 start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
49488 else
49489 block = begin_omp_structured_block ();
49490 if (cp)
49491 {
49492 cp_parser_push_lexer_for_tokens (parser, cache: cp);
49493 parser->lexer->in_pragma = true;
49494 }
49495
49496 bool ok = cp_parser_omp_declare_reduction_exprs (fndecl, parser);
49497
49498 if (cp)
49499 cp_parser_pop_lexer (parser);
49500 if (!block_scope)
49501 finish_function (/*inline_p=*/false);
49502 else
49503 {
49504 DECL_CONTEXT (fndecl) = current_function_decl;
49505 if (DECL_TEMPLATE_INFO (fndecl))
49506 DECL_CONTEXT (DECL_TI_TEMPLATE (fndecl)) = current_function_decl;
49507 }
49508 if (!ok)
49509 goto fail;
49510
49511 if (block_scope)
49512 {
49513 block = finish_omp_structured_block (block);
49514 if (TREE_CODE (block) == BIND_EXPR)
49515 DECL_SAVED_TREE (fndecl) = BIND_EXPR_BODY (block);
49516 else if (TREE_CODE (block) == STATEMENT_LIST)
49517 DECL_SAVED_TREE (fndecl) = block;
49518 if (processing_template_decl)
49519 add_decl_expr (fndecl);
49520 }
49521
49522 cp_check_omp_declare_reduction (fndecl);
49523 if (cp == NULL && types.length () > 1)
49524 cp = cp_token_cache_new (first: first_token,
49525 last: cp_lexer_peek_nth_token (lexer: parser->lexer, n: 2));
49526 if (errs != errorcount)
49527 break;
49528 }
49529
49530 cp_parser_require_pragma_eol (parser, pragma_tok);
49531
49532 done:
49533 /* Free any declarators allocated. */
49534 obstack_free (&declarator_obstack, p);
49535}
49536
49537/* OpenMP 4.0
49538 #pragma omp declare simd declare-simd-clauses[optseq] new-line
49539 #pragma omp declare reduction (reduction-id : typename-list : expression) \
49540 initializer-clause[opt] new-line
49541 #pragma omp declare target new-line
49542
49543 OpenMP 5.0
49544 #pragma omp declare variant (identifier) match (context-selector) */
49545
49546static bool
49547cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
49548 enum pragma_context context)
49549{
49550 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49551 {
49552 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49553 const char *p = IDENTIFIER_POINTER (id);
49554
49555 if (strcmp (s1: p, s2: "simd") == 0)
49556 {
49557 cp_lexer_consume_token (lexer: parser->lexer);
49558 cp_parser_omp_declare_simd (parser, pragma_tok,
49559 context, variant_p: false);
49560 return true;
49561 }
49562 if (flag_openmp && strcmp (s1: p, s2: "variant") == 0)
49563 {
49564 cp_lexer_consume_token (lexer: parser->lexer);
49565 cp_parser_omp_declare_simd (parser, pragma_tok,
49566 context, variant_p: true);
49567 return true;
49568 }
49569 cp_ensure_no_omp_declare_simd (parser);
49570 if (strcmp (s1: p, s2: "reduction") == 0)
49571 {
49572 cp_lexer_consume_token (lexer: parser->lexer);
49573 cp_parser_omp_declare_reduction (parser, pragma_tok,
49574 context);
49575 return false;
49576 }
49577 if (!flag_openmp) /* flag_openmp_simd */
49578 {
49579 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49580 return false;
49581 }
49582 if (strcmp (s1: p, s2: "target") == 0)
49583 {
49584 cp_lexer_consume_token (lexer: parser->lexer);
49585 cp_parser_omp_declare_target (parser, pragma_tok);
49586 return false;
49587 }
49588 }
49589 cp_parser_error (parser, gmsgid: "expected %<simd%>, %<reduction%>, "
49590 "%<target%> or %<variant%>");
49591 cp_parser_require_pragma_eol (parser, pragma_tok);
49592 return false;
49593}
49594
49595/* OpenMP 5.0
49596 #pragma omp requires clauses[optseq] new-line */
49597
49598static bool
49599cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
49600{
49601 enum omp_requires new_req = (enum omp_requires) 0;
49602
49603 location_t loc = pragma_tok->location;
49604 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
49605 {
49606 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
49607 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
49608 cp_lexer_consume_token (lexer: parser->lexer);
49609
49610 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49611 {
49612 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49613 const char *p = IDENTIFIER_POINTER (id);
49614 location_t cloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
49615 enum omp_requires this_req = (enum omp_requires) 0;
49616
49617 if (!strcmp (s1: p, s2: "unified_address"))
49618 this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
49619 else if (!strcmp (s1: p, s2: "unified_shared_memory"))
49620 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
49621 else if (!strcmp (s1: p, s2: "dynamic_allocators"))
49622 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
49623 else if (!strcmp (s1: p, s2: "reverse_offload"))
49624 this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
49625 else if (!strcmp (s1: p, s2: "atomic_default_mem_order"))
49626 {
49627 cp_lexer_consume_token (lexer: parser->lexer);
49628
49629 matching_parens parens;
49630 if (parens.require_open (parser))
49631 {
49632 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49633 {
49634 id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49635 p = IDENTIFIER_POINTER (id);
49636
49637 if (!strcmp (s1: p, s2: "seq_cst"))
49638 this_req
49639 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
49640 else if (!strcmp (s1: p, s2: "relaxed"))
49641 this_req
49642 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
49643 else if (!strcmp (s1: p, s2: "release"))
49644 this_req
49645 = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE;
49646 else if (!strcmp (s1: p, s2: "acq_rel"))
49647 this_req
49648 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
49649 else if (!strcmp (s1: p, s2: "acquire"))
49650 this_req
49651 = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE;
49652 }
49653 if (this_req == 0)
49654 {
49655 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
49656 "expected %<acq_rel%>, %<acquire%>, "
49657 "%<relaxed%>, %<release%> or %<seq_cst%>");
49658 switch (cp_lexer_peek_token (lexer: parser->lexer)->type)
49659 {
49660 case CPP_EOF:
49661 case CPP_PRAGMA_EOL:
49662 case CPP_CLOSE_PAREN:
49663 break;
49664 default:
49665 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2,
49666 type: CPP_CLOSE_PAREN))
49667 cp_lexer_consume_token (lexer: parser->lexer);
49668 break;
49669 }
49670 }
49671 else
49672 cp_lexer_consume_token (lexer: parser->lexer);
49673
49674 if (!parens.require_close (parser))
49675 cp_parser_skip_to_closing_parenthesis (parser,
49676 /*recovering=*/true,
49677 /*or_comma=*/false,
49678 /*consume_paren=*/
49679 true);
49680
49681 if (this_req == 0)
49682 {
49683 cp_parser_require_pragma_eol (parser, pragma_tok);
49684 return false;
49685 }
49686 }
49687 p = NULL;
49688 }
49689 else
49690 {
49691 error_at (cloc, "expected %<unified_address%>, "
49692 "%<unified_shared_memory%>, "
49693 "%<dynamic_allocators%>, "
49694 "%<reverse_offload%> "
49695 "or %<atomic_default_mem_order%> clause");
49696 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49697 return false;
49698 }
49699 if (p)
49700 cp_lexer_consume_token (lexer: parser->lexer);
49701 if (this_req)
49702 {
49703 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
49704 {
49705 if ((this_req & new_req) != 0)
49706 error_at (cloc, "too many %qs clauses", p);
49707 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
49708 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
49709 error_at (cloc, "%qs clause used lexically after first "
49710 "target construct or offloading API", p);
49711 }
49712 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
49713 {
49714 error_at (cloc, "too many %qs clauses",
49715 "atomic_default_mem_order");
49716 this_req = (enum omp_requires) 0;
49717 }
49718 else if ((omp_requires_mask
49719 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
49720 {
49721 error_at (cloc, "more than one %<atomic_default_mem_order%>"
49722 " clause in a single compilation unit");
49723 this_req
49724 = (enum omp_requires)
49725 (omp_requires_mask
49726 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
49727 }
49728 else if ((omp_requires_mask
49729 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
49730 error_at (cloc, "%<atomic_default_mem_order%> clause used "
49731 "lexically after first %<atomic%> construct "
49732 "without memory order clause");
49733 new_req = (enum omp_requires) (new_req | this_req);
49734 omp_requires_mask
49735 = (enum omp_requires) (omp_requires_mask | this_req);
49736 continue;
49737 }
49738 }
49739 break;
49740 }
49741 cp_parser_require_pragma_eol (parser, pragma_tok);
49742
49743 if (new_req == 0)
49744 error_at (loc, "%<pragma omp requires%> requires at least one clause");
49745 return false;
49746}
49747
49748
49749/* OpenMP 5.1:
49750 #pragma omp nothing new-line */
49751
49752static void
49753cp_parser_omp_nothing (cp_parser *parser, cp_token *pragma_tok)
49754{
49755 cp_parser_require_pragma_eol (parser, pragma_tok);
49756}
49757
49758
49759/* OpenMP 5.1
49760 #pragma omp error clauses[optseq] new-line */
49761
49762static bool
49763cp_parser_omp_error (cp_parser *parser, cp_token *pragma_tok,
49764 enum pragma_context context)
49765{
49766 int at_compilation = -1;
49767 int severity_fatal = -1;
49768 tree message = NULL_TREE;
49769 bool bad = false;
49770 location_t loc = pragma_tok->location;
49771
49772 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
49773 {
49774 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_COMMA)
49775 && cp_lexer_nth_token_is (lexer: parser->lexer, n: 2, type: CPP_NAME))
49776 cp_lexer_consume_token (lexer: parser->lexer);
49777
49778 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_NAME))
49779 break;
49780
49781 const char *p
49782 = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
49783 location_t cloc = cp_lexer_peek_token (lexer: parser->lexer)->location;
49784 static const char *args[] = {
49785 "execution", "compilation", "warning", "fatal"
49786 };
49787 int *v = NULL;
49788 int idx = 0, n = -1;
49789 tree m = NULL_TREE;
49790
49791 if (!strcmp (s1: p, s2: "at"))
49792 v = &at_compilation;
49793 else if (!strcmp (s1: p, s2: "severity"))
49794 {
49795 v = &severity_fatal;
49796 idx += 2;
49797 }
49798 else if (strcmp (s1: p, s2: "message"))
49799 {
49800 error_at (cloc,
49801 "expected %<at%>, %<severity%> or %<message%> clause");
49802 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
49803 return false;
49804 }
49805
49806 cp_lexer_consume_token (lexer: parser->lexer);
49807
49808 matching_parens parens;
49809 if (parens.require_open (parser))
49810 {
49811 if (v == NULL)
49812 {
49813 m = cp_parser_assignment_expression (parser);
49814 if (type_dependent_expression_p (m))
49815 m = build1 (IMPLICIT_CONV_EXPR, const_string_type_node, m);
49816 else
49817 m = perform_implicit_conversion_flags (const_string_type_node, m,
49818 tf_warning_or_error,
49819 LOOKUP_NORMAL);
49820 }
49821 else
49822 {
49823 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49824 {
49825 tree val = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49826 const char *q = IDENTIFIER_POINTER (val);
49827
49828 if (!strcmp (s1: q, s2: args[idx]))
49829 n = 0;
49830 else if (!strcmp (s1: q, s2: args[idx + 1]))
49831 n = 1;
49832 }
49833 if (n == -1)
49834 {
49835 error_at (cp_lexer_peek_token (lexer: parser->lexer)->location,
49836 "expected %qs or %qs", args[idx], args[idx + 1]);
49837 bad = true;
49838 switch (cp_lexer_peek_token (lexer: parser->lexer)->type)
49839 {
49840 case CPP_EOF:
49841 case CPP_PRAGMA_EOL:
49842 case CPP_CLOSE_PAREN:
49843 break;
49844 default:
49845 if (cp_lexer_nth_token_is (lexer: parser->lexer, n: 2,
49846 type: CPP_CLOSE_PAREN))
49847 cp_lexer_consume_token (lexer: parser->lexer);
49848 break;
49849 }
49850 }
49851 else
49852 cp_lexer_consume_token (lexer: parser->lexer);
49853 }
49854
49855 if (!parens.require_close (parser))
49856 cp_parser_skip_to_closing_parenthesis (parser,
49857 /*recovering=*/true,
49858 /*or_comma=*/false,
49859 /*consume_paren=*/
49860 true);
49861
49862 if (v == NULL)
49863 {
49864 if (message)
49865 {
49866 error_at (cloc, "too many %qs clauses", p);
49867 bad = true;
49868 }
49869 else
49870 message = m;
49871 }
49872 else if (n != -1)
49873 {
49874 if (*v != -1)
49875 {
49876 error_at (cloc, "too many %qs clauses", p);
49877 bad = true;
49878 }
49879 else
49880 *v = n;
49881 }
49882 }
49883 else
49884 bad = true;
49885 }
49886 cp_parser_require_pragma_eol (parser, pragma_tok);
49887 if (bad)
49888 return true;
49889
49890 if (at_compilation == -1)
49891 at_compilation = 1;
49892 if (severity_fatal == -1)
49893 severity_fatal = 1;
49894 if (!at_compilation)
49895 {
49896 if (context != pragma_compound)
49897 {
49898 error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
49899 "may only be used in compound statements");
49900 return true;
49901 }
49902 tree fndecl
49903 = builtin_decl_explicit (fncode: severity_fatal ? BUILT_IN_GOMP_ERROR
49904 : BUILT_IN_GOMP_WARNING);
49905 if (!message)
49906 message = build_zero_cst (const_string_type_node);
49907 tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
49908 build_all_ones_cst (size_type_node));
49909 add_stmt (stmt);
49910 return true;
49911 }
49912
49913 if (in_discarded_stmt)
49914 return false;
49915
49916 const char *msg = NULL;
49917 if (message)
49918 {
49919 msg = c_getstr (fold_for_warn (message));
49920 if (msg == NULL)
49921 msg = _("<message unknown at compile time>");
49922 }
49923 if (msg)
49924 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
49925 "%<pragma omp error%> encountered: %s", msg);
49926 else
49927 emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
49928 "%<pragma omp error%> encountered");
49929 return false;
49930}
49931
49932/* OpenMP 4.5:
49933 #pragma omp taskloop taskloop-clause[optseq] new-line
49934 for-loop
49935
49936 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
49937 for-loop */
49938
49939#define OMP_TASKLOOP_CLAUSE_MASK \
49940 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
49941 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
49942 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
49943 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
49944 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
49945 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
49946 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
49947 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
49948 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
49949 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
49950 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
49951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
49952 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \
49953 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \
49954 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
49955 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
49956 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
49957
49958static tree
49959cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok,
49960 char *p_name, omp_clause_mask mask, tree *cclauses,
49961 bool *if_p)
49962{
49963 tree clauses, sb, ret;
49964 unsigned int save;
49965 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
49966
49967 strcat (dest: p_name, src: " taskloop");
49968 mask |= OMP_TASKLOOP_CLAUSE_MASK;
49969 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
49970 clause. */
49971 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
49972 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
49973
49974 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_NAME))
49975 {
49976 tree id = cp_lexer_peek_token (lexer: parser->lexer)->u.value;
49977 const char *p = IDENTIFIER_POINTER (id);
49978
49979 if (strcmp (s1: p, s2: "simd") == 0)
49980 {
49981 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
49982 if (cclauses == NULL)
49983 cclauses = cclauses_buf;
49984
49985 cp_lexer_consume_token (lexer: parser->lexer);
49986 if (!flag_openmp) /* flag_openmp_simd */
49987 return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
49988 cclauses, if_p);
49989 sb = begin_omp_structured_block ();
49990 save = cp_parser_begin_omp_structured_block (parser);
49991 ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
49992 cclauses, if_p);
49993 cp_parser_end_omp_structured_block (parser, save);
49994 tree body = finish_omp_structured_block (sb);
49995 if (ret == NULL)
49996 return ret;
49997 ret = make_node (OMP_TASKLOOP);
49998 TREE_TYPE (ret) = void_type_node;
49999 OMP_FOR_BODY (ret) = body;
50000 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
50001 SET_EXPR_LOCATION (ret, loc);
50002 add_stmt (ret);
50003 return ret;
50004 }
50005 }
50006 if (!flag_openmp) /* flag_openmp_simd */
50007 {
50008 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
50009 return NULL_TREE;
50010 }
50011
50012 clauses = cp_parser_omp_all_clauses (parser, mask, where: p_name, pragma_tok,
50013 finish_p: cclauses == NULL);
50014 if (cclauses)
50015 {
50016 cp_omp_split_clauses (loc, code: OMP_TASKLOOP, mask, clauses, cclauses);
50017 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
50018 }
50019
50020 keep_next_level (true);
50021 sb = begin_omp_structured_block ();
50022 save = cp_parser_begin_omp_structured_block (parser);
50023
50024 ret = cp_parser_omp_for_loop (parser, code: OMP_TASKLOOP, clauses, cclauses,
50025 if_p);
50026
50027 cp_parser_end_omp_structured_block (parser, save);
50028 add_stmt (finish_omp_structured_block (sb));
50029
50030 return ret;
50031}
50032
50033
50034/* OpenACC 2.0:
50035 # pragma acc routine oacc-routine-clause[optseq] new-line
50036 function-definition
50037
50038 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
50039*/
50040
50041#define OACC_ROUTINE_CLAUSE_MASK \
50042 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
50043 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
50044 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
50045 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
50046 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
50047
50048/* Parse the OpenACC routine pragma. This has an optional '( name )'
50049 component, which must resolve to a declared namespace-scope
50050 function. The clauses are either processed directly (for a named
50051 function), or defered until the immediatley following declaration
50052 is parsed. */
50053
50054static void
50055cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
50056 enum pragma_context context)
50057{
50058 gcc_checking_assert (context == pragma_external);
50059 /* The checking for "another pragma following this one" in the "no optional
50060 '( name )'" case makes sure that we dont re-enter. */
50061 gcc_checking_assert (parser->oacc_routine == NULL);
50062
50063 cp_oacc_routine_data data;
50064 data.error_seen = false;
50065 data.fndecl_seen = false;
50066 data.tokens = vNULL;
50067 data.clauses = NULL_TREE;
50068 data.loc = pragma_tok->location;
50069 /* It is safe to take the address of a local variable; it will only be
50070 used while this scope is live. */
50071 parser->oacc_routine = &data;
50072
50073 /* Look for optional '( name )'. */
50074 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_OPEN_PAREN))
50075 {
50076 matching_parens parens;
50077 parens.consume_open (parser); /* '(' */
50078
50079 /* We parse the name as an id-expression. If it resolves to
50080 anything other than a non-overloaded function at namespace
50081 scope, it's an error. */
50082 location_t name_loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
50083 tree name = cp_parser_id_expression (parser,
50084 /*template_keyword_p=*/false,
50085 /*check_dependency_p=*/false,
50086 /*template_p=*/NULL,
50087 /*declarator_p=*/false,
50088 /*optional_p=*/false);
50089 tree decl = (identifier_p (t: name)
50090 ? cp_parser_lookup_name_simple (parser, name, location: name_loc)
50091 : name);
50092 if (name != error_mark_node && decl == error_mark_node)
50093 cp_parser_name_lookup_error (parser, name, decl, desired: NLE_NULL, location: name_loc);
50094
50095 if (decl == error_mark_node
50096 || !parens.require_close (parser))
50097 {
50098 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
50099 parser->oacc_routine = NULL;
50100 return;
50101 }
50102
50103 data.clauses
50104 = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
50105 where: "#pragma acc routine",
50106 pragma_tok: cp_lexer_peek_token (lexer: parser->lexer));
50107 /* The clauses are in reverse order; fix that to make later diagnostic
50108 emission easier. */
50109 data.clauses = nreverse (data.clauses);
50110
50111 if (decl && is_overloaded_fn (decl)
50112 && (TREE_CODE (decl) != FUNCTION_DECL
50113 || DECL_FUNCTION_TEMPLATE_P (decl)))
50114 {
50115 error_at (name_loc,
50116 "%<#pragma acc routine%> names a set of overloads");
50117 parser->oacc_routine = NULL;
50118 return;
50119 }
50120
50121 /* Perhaps we should use the same rule as declarations in different
50122 namespaces? */
50123 if (!DECL_NAMESPACE_SCOPE_P (decl))
50124 {
50125 error_at (name_loc,
50126 "%qD does not refer to a namespace scope function", decl);
50127 parser->oacc_routine = NULL;
50128 return;
50129 }
50130
50131 if (TREE_CODE (decl) != FUNCTION_DECL)
50132 {
50133 error_at (name_loc, "%qD does not refer to a function", decl);
50134 parser->oacc_routine = NULL;
50135 return;
50136 }
50137
50138 cp_finalize_oacc_routine (parser, decl, false);
50139 parser->oacc_routine = NULL;
50140 }
50141 else /* No optional '( name )'. */
50142 {
50143 /* Store away all pragma tokens. */
50144 while (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_PRAGMA_EOL))
50145 cp_lexer_consume_token (lexer: parser->lexer);
50146 cp_parser_require_pragma_eol (parser, pragma_tok);
50147 struct cp_token_cache *cp
50148 = cp_token_cache_new (first: pragma_tok, last: cp_lexer_peek_token (lexer: parser->lexer));
50149 parser->oacc_routine->tokens.safe_push (obj: cp);
50150
50151 /* Emit a helpful diagnostic if there's another pragma following this
50152 one. */
50153 if (cp_lexer_next_token_is (lexer: parser->lexer, type: CPP_PRAGMA))
50154 {
50155 cp_ensure_no_oacc_routine (parser);
50156 data.tokens.release ();
50157 /* ..., and then just keep going. */
50158 return;
50159 }
50160
50161 /* We only have to consider the pragma_external case here. */
50162 cp_parser_declaration (parser, NULL_TREE);
50163 if (parser->oacc_routine
50164 && !parser->oacc_routine->fndecl_seen)
50165 cp_ensure_no_oacc_routine (parser);
50166 else
50167 parser->oacc_routine = NULL;
50168 data.tokens.release ();
50169 }
50170}
50171
50172/* Finalize #pragma acc routine clauses after direct declarator has
50173 been parsed. */
50174
50175static tree
50176cp_parser_late_parsing_oacc_routine (cp_parser *parser, tree attrs)
50177{
50178 struct cp_token_cache *ce;
50179 cp_oacc_routine_data *data = parser->oacc_routine;
50180
50181 if (!data->error_seen && data->fndecl_seen)
50182 {
50183 error_at (data->loc,
50184 "%<#pragma acc routine%> not immediately followed by "
50185 "a single function declaration or definition");
50186 data->error_seen = true;
50187 }
50188 if (data->error_seen)
50189 return attrs;
50190
50191 gcc_checking_assert (data->tokens.length () == 1);
50192 ce = data->tokens[0];
50193
50194 cp_parser_push_lexer_for_tokens (parser, cache: ce);
50195 parser->lexer->in_pragma = true;
50196 gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);
50197
50198 cp_token *pragma_tok = cp_lexer_consume_token (lexer: parser->lexer);
50199 gcc_checking_assert (parser->oacc_routine->clauses == NULL_TREE);
50200 parser->oacc_routine->clauses
50201 = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
50202 where: "#pragma acc routine", pragma_tok);
50203 /* The clauses are in reverse order; fix that to make later diagnostic
50204 emission easier. */
50205 parser->oacc_routine->clauses = nreverse (parser->oacc_routine->clauses);
50206 cp_parser_pop_lexer (parser);
50207 /* Later, cp_finalize_oacc_routine will process the clauses. */
50208 parser->oacc_routine->fndecl_seen = true;
50209
50210 return attrs;
50211}
50212
50213/* Apply any saved OpenACC routine clauses to a just-parsed
50214 declaration. */
50215
50216static void
50217cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn)
50218{
50219 if (UNLIKELY (parser->oacc_routine != NULL))
50220 {
50221 /* Keep going if we're in error reporting mode. */
50222 if (parser->oacc_routine->error_seen
50223 || fndecl == error_mark_node)
50224 return;
50225
50226 if (TREE_CODE (fndecl) != FUNCTION_DECL)
50227 {
50228 if (parser->oacc_routine->fndecl_seen)
50229 {
50230 error_at (parser->oacc_routine->loc,
50231 "%<#pragma acc routine%> not immediately followed by"
50232 " a single function declaration or definition");
50233 parser->oacc_routine = NULL;
50234 return;
50235 }
50236
50237 cp_ensure_no_oacc_routine (parser);
50238 return;
50239 }
50240
50241 int compatible
50242 = oacc_verify_routine_clauses (fndecl, &parser->oacc_routine->clauses,
50243 parser->oacc_routine->loc,
50244 "#pragma acc routine");
50245 if (compatible < 0)
50246 {
50247 parser->oacc_routine = NULL;
50248 return;
50249 }
50250 if (compatible > 0)
50251 {
50252 }
50253 else
50254 {
50255 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
50256 {
50257 error_at (parser->oacc_routine->loc,
50258 TREE_USED (fndecl)
50259 ? G_("%<#pragma acc routine%> must be applied before"
50260 " use")
50261 : G_("%<#pragma acc routine%> must be applied before"
50262 " definition"));
50263 parser->oacc_routine = NULL;
50264 return;
50265 }
50266
50267 /* Set the routine's level of parallelism. */
50268 tree dims = oacc_build_routine_dims (clauses: parser->oacc_routine->clauses);
50269 oacc_replace_fn_attrib (fn: fndecl, dims);
50270
50271 /* Add an "omp declare target" attribute. */
50272 DECL_ATTRIBUTES (fndecl)
50273 = tree_cons (get_identifier ("omp declare target"),
50274 parser->oacc_routine->clauses,
50275 DECL_ATTRIBUTES (fndecl));
50276 }
50277 }
50278}
50279
50280/* Main entry point to OpenMP statement pragmas. */
50281
50282static void
50283cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
50284{
50285 tree stmt;
50286 char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
50287 omp_clause_mask mask (0);
50288
50289 switch (cp_parser_pragma_kind (token: pragma_tok))
50290 {
50291 case PRAGMA_OACC_ATOMIC:
50292 cp_parser_omp_atomic (parser, pragma_tok, openacc: true);
50293 return;
50294 case PRAGMA_OACC_CACHE:
50295 stmt = cp_parser_oacc_cache (parser, pragma_tok);
50296 break;
50297 case PRAGMA_OACC_DATA:
50298 stmt = cp_parser_oacc_data (parser, pragma_tok, if_p);
50299 break;
50300 case PRAGMA_OACC_ENTER_DATA:
50301 stmt = cp_parser_oacc_enter_exit_data (parser, pragma_tok, enter: true);
50302 break;
50303 case PRAGMA_OACC_EXIT_DATA:
50304 stmt = cp_parser_oacc_enter_exit_data (parser, pragma_tok, enter: false);
50305 break;
50306 case PRAGMA_OACC_HOST_DATA:
50307 stmt = cp_parser_oacc_host_data (parser, pragma_tok, if_p);
50308 break;
50309 case PRAGMA_OACC_KERNELS:
50310 case PRAGMA_OACC_PARALLEL:
50311 case PRAGMA_OACC_SERIAL:
50312 strcpy (dest: p_name, src: "#pragma acc");
50313 stmt = cp_parser_oacc_compute (parser, pragma_tok, p_name, if_p);
50314 break;
50315 case PRAGMA_OACC_LOOP:
50316 strcpy (dest: p_name, src: "#pragma acc");
50317 stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask, NULL,
50318 if_p);
50319 break;
50320 case PRAGMA_OACC_UPDATE:
50321 stmt = cp_parser_oacc_update (parser, pragma_tok);
50322 break;
50323 case PRAGMA_OACC_WAIT:
50324 stmt = cp_parser_oacc_wait (parser, pragma_tok);
50325 break;
50326 case PRAGMA_OMP_ALLOCATE:
50327 cp_parser_omp_allocate (parser, pragma_tok);
50328 return;
50329 case PRAGMA_OMP_ATOMIC:
50330 cp_parser_omp_atomic (parser, pragma_tok, openacc: false);
50331 return;
50332 case PRAGMA_OMP_CRITICAL:
50333 stmt = cp_parser_omp_critical (parser, pragma_tok, if_p);
50334 break;
50335 case PRAGMA_OMP_DISTRIBUTE:
50336 strcpy (dest: p_name, src: "#pragma omp");
50337 stmt = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask, NULL,
50338 if_p);
50339 break;
50340 case PRAGMA_OMP_FOR:
50341 strcpy (dest: p_name, src: "#pragma omp");
50342 stmt = cp_parser_omp_for (parser, pragma_tok, p_name, mask, NULL,
50343 if_p);
50344 break;
50345 case PRAGMA_OMP_LOOP:
50346 strcpy (dest: p_name, src: "#pragma omp");
50347 stmt = cp_parser_omp_loop (parser, pragma_tok, p_name, mask, NULL,
50348 if_p);
50349 break;
50350 case PRAGMA_OMP_MASKED:
50351 strcpy (dest: p_name, src: "#pragma omp");
50352 stmt = cp_parser_omp_masked (parser, pragma_tok, p_name, mask, NULL,
50353 if_p);
50354 break;
50355 case PRAGMA_OMP_MASTER:
50356 strcpy (dest: p_name, src: "#pragma omp");
50357 stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
50358 if_p);
50359 break;
50360 case PRAGMA_OMP_PARALLEL:
50361 strcpy (dest: p_name, src: "#pragma omp");
50362 stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask, NULL,
50363 if_p);
50364 break;
50365 case PRAGMA_OMP_SCOPE:
50366 stmt = cp_parser_omp_scope (parser, pragma_tok, if_p);
50367 break;
50368 case PRAGMA_OMP_SECTIONS:
50369 strcpy (dest: p_name, src: "#pragma omp");
50370 stmt = cp_parser_omp_sections (parser, pragma_tok, p_name, mask, NULL);
50371 break;
50372 case PRAGMA_OMP_SIMD:
50373 strcpy (dest: p_name, src: "#pragma omp");
50374 stmt = cp_parser_omp_simd (parser, pragma_tok, p_name, mask, NULL,
50375 if_p);
50376 break;
50377 case PRAGMA_OMP_SINGLE:
50378 stmt = cp_parser_omp_single (parser, pragma_tok, if_p);
50379 break;
50380 case PRAGMA_OMP_TASK:
50381 stmt = cp_parser_omp_task (parser, pragma_tok, if_p);
50382 break;
50383 case PRAGMA_OMP_TASKGROUP:
50384 stmt = cp_parser_omp_taskgroup (parser, pragma_tok, if_p);
50385 break;
50386 case PRAGMA_OMP_TASKLOOP:
50387 strcpy (dest: p_name, src: "#pragma omp");
50388 stmt = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask, NULL,
50389 if_p);
50390 break;
50391 case PRAGMA_OMP_TEAMS:
50392 strcpy (dest: p_name, src: "#pragma omp");
50393 stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL,
50394 if_p);
50395 break;
50396 case PRAGMA_OMP_ASSUME:
50397 cp_parser_omp_assume (parser, pragma_tok, if_p);
50398 return;
50399 default:
50400 gcc_unreachable ();
50401 }
50402
50403 protected_set_expr_location (stmt, pragma_tok->location);
50404}
50405
50406/* Transactional Memory parsing routines. */
50407
50408/* Parse a transaction attribute.
50409
50410 txn-attribute:
50411 attribute
50412 [ [ identifier ] ]
50413
50414 We use this instead of cp_parser_attributes_opt for transactions to avoid
50415 the pedwarn in C++98 mode. */
50416
50417static tree
50418cp_parser_txn_attribute_opt (cp_parser *parser)
50419{
50420 cp_token *token;
50421 tree attr_name, attr = NULL;
50422
50423 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_ATTRIBUTE))
50424 return cp_parser_attributes_opt (parser);
50425
50426 if (cp_lexer_next_token_is_not (lexer: parser->lexer, type: CPP_OPEN_SQUARE))
50427 return NULL_TREE;
50428 cp_lexer_consume_token (lexer: parser->lexer);
50429 if (!cp_parser_require (parser, type: CPP_OPEN_SQUARE, token_desc: RT_OPEN_SQUARE))
50430 goto error1;
50431
50432 token = cp_lexer_peek_token (lexer: parser->lexer);
50433 if (token->type == CPP_NAME || token->type == CPP_KEYWORD)
50434 {
50435 token = cp_lexer_consume_token (lexer: parser->lexer);
50436
50437 attr_name = (token->type == CPP_KEYWORD
50438 /* For keywords, use the canonical spelling,
50439 not the parsed identifier. */
50440 ? ridpointers[(int) token->keyword]
50441 : token->u.value);
50442 attr = build_tree_list (attr_name, NULL_TREE);
50443 }
50444 else
50445 cp_parser_error (parser, gmsgid: "expected identifier");
50446
50447 cp_parser_require (parser, type: CPP_CLOSE_SQUARE, token_desc: RT_CLOSE_SQUARE);
50448 error1:
50449 cp_parser_require (parser, type: CPP_CLOSE_SQUARE, token_desc: RT_CLOSE_SQUARE);
50450 return attr;
50451}
50452
50453/* Parse a __transaction_atomic or __transaction_relaxed statement.
50454
50455 transaction-statement:
50456 __transaction_atomic txn-attribute[opt] txn-noexcept-spec[opt]
50457 compound-statement
50458 __transaction_relaxed txn-noexcept-spec[opt] compound-statement
50459*/
50460
50461static tree
50462cp_parser_transaction (cp_parser *parser, cp_token *token)
50463{
50464 unsigned char old_in = parser->in_transaction;
50465 unsigned char this_in = 1, new_in;
50466 enum rid keyword = token->keyword;
50467 tree stmt, attrs, noex;
50468
50469 cp_lexer_consume_token (lexer: parser->lexer);
50470
50471 if (keyword == RID_TRANSACTION_RELAXED
50472 || keyword == RID_SYNCHRONIZED)
50473 this_in |= TM_STMT_ATTR_RELAXED;
50474 else
50475 {
50476 attrs = cp_parser_txn_attribute_opt (parser);
50477 if (attrs)
50478 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
50479 }
50480
50481 /* Parse a noexcept specification. */
50482 if (keyword == RID_ATOMIC_NOEXCEPT)
50483 noex = boolean_true_node;
50484 else if (keyword == RID_ATOMIC_CANCEL)
50485 {
50486 /* cancel-and-throw is unimplemented. */
50487 sorry ("%<atomic_cancel%>");
50488 noex = NULL_TREE;
50489 }
50490 else
50491 noex = cp_parser_noexcept_specification_opt (parser,
50492 flags: CP_PARSER_FLAGS_NONE,
50493 /*require_constexpr=*/true,
50494 /*consumed_expr=*/NULL,
50495 /*return_cond=*/true);
50496
50497 /* Keep track if we're in the lexical scope of an outer transaction. */
50498 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
50499
50500 stmt = begin_transaction_stmt (token->location, NULL, this_in);
50501
50502 parser->in_transaction = new_in;
50503 cp_parser_compound_statement (parser, NULL, bcs_flags: BCS_TRANSACTION, function_body: false);
50504 parser->in_transaction = old_in;
50505
50506 finish_transaction_stmt (stmt, NULL, this_in, noex);
50507
50508 return stmt;
50509}
50510
50511/* Parse a __transaction_atomic or __transaction_relaxed expression.
50512
50513 transaction-expression:
50514 __transaction_atomic txn-noexcept-spec[opt] ( expression )
50515 __transaction_relaxed txn-noexcept-spec[opt] ( expression )
50516*/
50517
50518static tree
50519cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
50520{
50521 unsigned char old_in = parser->in_transaction;
50522 unsigned char this_in = 1;
50523 cp_token *token;
50524 tree expr, noex;
50525 bool noex_expr;
50526 location_t loc = cp_lexer_peek_token (lexer: parser->lexer)->location;
50527
50528 gcc_assert (keyword == RID_TRANSACTION_ATOMIC
50529 || keyword == RID_TRANSACTION_RELAXED);
50530
50531 if (!flag_tm)
50532 error_at (loc,
50533 keyword == RID_TRANSACTION_RELAXED
50534 ? G_("%<__transaction_relaxed%> without transactional memory "
50535 "support enabled")
50536 : G_("%<__transaction_atomic%> without transactional memory "
50537 "support enabled"));
50538
50539 token = cp_parser_require_keyword (parser, keyword,
50540 token_desc: (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
50541 : RT_TRANSACTION_RELAXED));
50542 gcc_assert (token != NULL);
50543
50544 if (keyword == RID_TRANSACTION_RELAXED)
50545 this_in |= TM_STMT_ATTR_RELAXED;
50546
50547 /* Set this early. This might mean that we allow transaction_cancel in
50548 an expression that we find out later actually has to be a constexpr.
50549 However, we expect that cxx_constant_value will be able to deal with
50550 this; also, if the noexcept has no constexpr, then what we parse next
50551 really is a transaction's body. */
50552 parser->in_transaction = this_in;
50553
50554 /* Parse a noexcept specification. */
50555 noex = cp_parser_noexcept_specification_opt (parser,
50556 flags: CP_PARSER_FLAGS_NONE,
50557 /*require_constexpr=*/false,
50558 consumed_expr: &noex_expr,
50559 /*return_cond=*/true);
50560
50561 if (!noex || !noex_expr
50562 || cp_lexer_peek_token (lexer: parser->lexer)->type == CPP_OPEN_PAREN)
50563 {
50564 matching_parens parens;
50565 parens.require_open (parser);
50566
50567 expr = cp_parser_expression (parser);
50568 expr = finish_parenthesized_expr (expr);
50569
50570 parens.require_close (parser);
50571 }
50572 else
50573 {
50574 /* The only expression that is available got parsed for the noexcept
50575 already. noexcept is true then. */
50576 expr = noex;
50577 noex = boolean_true_node;
50578 }
50579
50580 expr = build_transaction_expr (token->location, expr, this_in, noex);
50581 parser->in_transaction = old_in;
50582
50583 if (cp_parser_non_integral_constant_expression (parser, thing: NIC_TRANSACTION))
50584 return error_mark_node;
50585
50586 return (flag_tm ? expr : error_mark_node);
50587}
50588
50589/* Parse a function-transaction-block.
50590
50591 function-transaction-block:
50592 __transaction_atomic txn-attribute[opt] ctor-initializer[opt]
50593 function-body
50594 __transaction_atomic txn-attribute[opt] function-try-block
50595 __transaction_relaxed ctor-initializer[opt] function-body
50596 __transaction_relaxed function-try-block
50597*/
50598
50599static void
50600cp_parser_function_transaction (cp_parser *parser, enum rid keyword)
50601{
50602 unsigned char old_in = parser->in_transaction;
50603 unsigned char new_in = 1;
50604 tree compound_stmt, stmt, attrs;
50605 cp_token *token;
50606
50607 gcc_assert (keyword == RID_TRANSACTION_ATOMIC
50608 || keyword == RID_TRANSACTION_RELAXED);
50609 token = cp_parser_require_keyword (parser, keyword,
50610 token_desc: (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
50611 : RT_TRANSACTION_RELAXED));
50612 gcc_assert (token != NULL);
50613
50614 if (keyword == RID_TRANSACTION_RELAXED)
50615 new_in |= TM_STMT_ATTR_RELAXED;
50616 else
50617 {
50618 attrs = cp_parser_txn_attribute_opt (parser);
50619 if (attrs)
50620 new_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
50621 }
50622
50623 stmt = begin_transaction_stmt (token->location, &compound_stmt, new_in);
50624
50625 parser->in_transaction = new_in;
50626
50627 if (cp_lexer_next_token_is_keyword (lexer: parser->lexer, keyword: RID_TRY))
50628 cp_parser_function_try_block (parser);
50629 else
50630 cp_parser_ctor_initializer_opt_and_function_body
50631 (parser, /*in_function_try_block=*/false);
50632
50633 parser->in_transaction = old_in;
50634
50635 finish_transaction_stmt (stmt, compound_stmt, new_in, NULL_TREE);
50636}
50637
50638/* Parse a __transaction_cancel statement.
50639
50640 cancel-statement:
50641 __transaction_cancel txn-attribute[opt] ;
50642 __transaction_cancel txn-attribute[opt] throw-expression ;
50643
50644 ??? Cancel and throw is not yet implemented. */
50645
50646static tree
50647cp_parser_transaction_cancel (cp_parser *parser)
50648{
50649 cp_token *token;
50650 bool is_outer = false;
50651 tree stmt, attrs;
50652
50653 token = cp_parser_require_keyword (parser, keyword: RID_TRANSACTION_CANCEL,
50654 token_desc: RT_TRANSACTION_CANCEL);
50655 gcc_assert (token != NULL);
50656
50657 attrs = cp_parser_txn_attribute_opt (parser);
50658 if (attrs)
50659 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
50660
50661 /* ??? Parse cancel-and-throw here. */
50662
50663 cp_parser_require (parser, type: CPP_SEMICOLON, token_desc: RT_SEMICOLON);
50664
50665 if (!flag_tm)
50666 {
50667 error_at (token->location, "%<__transaction_cancel%> without "
50668 "transactional memory support enabled");
50669 return error_mark_node;
50670 }
50671 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
50672 {
50673 error_at (token->location, "%<__transaction_cancel%> within a "
50674 "%<__transaction_relaxed%>");
50675 return error_mark_node;
50676 }
50677 else if (is_outer)
50678 {
50679 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
50680 && !is_tm_may_cancel_outer (current_function_decl))
50681 {
50682 error_at (token->location, "outer %<__transaction_cancel%> not "
50683 "within outer %<__transaction_atomic%>");
50684 error_at (token->location,
50685 " or a %<transaction_may_cancel_outer%> function");
50686 return error_mark_node;
50687 }
50688 }
50689 else if (parser->in_transaction == 0)
50690 {
50691 error_at (token->location, "%<__transaction_cancel%> not within "
50692 "%<__transaction_atomic%>");
50693 return error_mark_node;
50694 }
50695
50696 stmt = build_tm_abort_call (token->location, is_outer);
50697 add_stmt (stmt);
50698
50699 return stmt;
50700}
50701
50702
50703/* Special handling for the first token or line in the file. The first
50704 thing in the file might be #pragma GCC pch_preprocess, which loads a
50705 PCH file, which is a GC collection point. So we need to handle this
50706 first pragma without benefit of an existing lexer structure.
50707
50708 Always returns one token to the caller in *FIRST_TOKEN. This is
50709 either the true first token of the file, or the first token after
50710 the initial pragma. */
50711
50712static void
50713cp_parser_initial_pragma (cp_token *first_token)
50714{
50715 if (cp_parser_pragma_kind (token: first_token) != PRAGMA_GCC_PCH_PREPROCESS)
50716 return;
50717
50718 cp_lexer_get_preprocessor_token (flags: 0, token: first_token);
50719
50720 tree name = NULL;
50721 if (first_token->type == CPP_STRING)
50722 {
50723 name = first_token->u.value;
50724
50725 cp_lexer_get_preprocessor_token (flags: 0, token: first_token);
50726 }
50727
50728 /* Skip to the end of the pragma. */
50729 if (first_token->type != CPP_PRAGMA_EOL)
50730 {
50731 error_at (first_token->location,
50732 "malformed %<#pragma GCC pch_preprocess%>");
50733 do
50734 cp_lexer_get_preprocessor_token (flags: 0, token: first_token);
50735 while (first_token->type != CPP_PRAGMA_EOL);
50736 }
50737
50738 /* Now actually load the PCH file. */
50739 if (name)
50740 c_common_pch_pragma (pfile: parse_in, TREE_STRING_POINTER (name));
50741
50742 /* Read one more token to return to our caller. We have to do this
50743 after reading the PCH file in, since its pointers have to be
50744 live. */
50745 cp_lexer_get_preprocessor_token (flags: 0, token: first_token);
50746}
50747
50748/* Parse a pragma GCC ivdep. */
50749
50750static bool
50751cp_parser_pragma_ivdep (cp_parser *parser, cp_token *pragma_tok)
50752{
50753 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
50754 return true;
50755}
50756
50757/* Parse a pragma GCC unroll. */
50758
50759static tree
50760cp_parser_pragma_unroll (cp_parser *parser, cp_token *pragma_tok)
50761{
50762 location_t location = cp_lexer_peek_token (lexer: parser->lexer)->location;
50763 tree unroll = cp_parser_constant_expression (parser);
50764 unroll = cp_check_pragma_unroll (location, fold_non_dependent_expr (unroll));
50765 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
50766 return unroll;
50767}
50768
50769/* Parse a pragma GCC novector. */
50770
50771static bool
50772cp_parser_pragma_novector (cp_parser *parser, cp_token *pragma_tok)
50773{
50774 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
50775 return true;
50776}
50777
50778/* Normal parsing of a pragma token. Here we can (and must) use the
50779 regular lexer. */
50780
50781static bool
50782cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
50783{
50784 cp_token *pragma_tok;
50785 unsigned int id;
50786 tree stmt;
50787 bool ret = false;
50788
50789 pragma_tok = cp_lexer_consume_token (lexer: parser->lexer);
50790 gcc_assert (pragma_tok->type == CPP_PRAGMA);
50791 parser->lexer->in_pragma = true;
50792
50793 id = cp_parser_pragma_kind (token: pragma_tok);
50794 if (parser->omp_for_parse_state
50795 && parser->omp_for_parse_state->in_intervening_code
50796 && id >= PRAGMA_OMP__START_
50797 && id <= PRAGMA_OMP__LAST_)
50798 {
50799 error_at (pragma_tok->location,
50800 "intervening code must not contain OpenMP directives");
50801 parser->omp_for_parse_state->fail = true;
50802 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
50803 return false;
50804 }
50805 if (id != PRAGMA_OMP_DECLARE && id != PRAGMA_OACC_ROUTINE)
50806 cp_ensure_no_omp_declare_simd (parser);
50807 switch (id)
50808 {
50809 case PRAGMA_GCC_PCH_PREPROCESS:
50810 error_at (pragma_tok->location,
50811 "%<#pragma GCC pch_preprocess%> must be first");
50812 break;
50813
50814 case PRAGMA_OMP_BARRIER:
50815 switch (context)
50816 {
50817 case pragma_compound:
50818 cp_parser_omp_barrier (parser, pragma_tok);
50819 return false;
50820 case pragma_stmt:
50821 error_at (pragma_tok->location, "%<#pragma %s%> may only be "
50822 "used in compound statements", "omp barrier");
50823 ret = true;
50824 break;
50825 default:
50826 goto bad_stmt;
50827 }
50828 break;
50829
50830 case PRAGMA_OMP_DEPOBJ:
50831 switch (context)
50832 {
50833 case pragma_compound:
50834 cp_parser_omp_depobj (parser, pragma_tok);
50835 return false;
50836 case pragma_stmt:
50837 error_at (pragma_tok->location, "%<#pragma %s%> may only be "
50838 "used in compound statements", "omp depobj");
50839 ret = true;
50840 break;
50841 default:
50842 goto bad_stmt;
50843 }
50844 break;
50845
50846 case PRAGMA_OMP_FLUSH:
50847 switch (context)
50848 {
50849 case pragma_compound:
50850 cp_parser_omp_flush (parser, pragma_tok);
50851 return false;
50852 case pragma_stmt:
50853 error_at (pragma_tok->location, "%<#pragma %s%> may only be "
50854 "used in compound statements", "omp flush");
50855 ret = true;
50856 break;
50857 default:
50858 goto bad_stmt;
50859 }
50860 break;
50861
50862 case PRAGMA_OMP_TASKWAIT:
50863 switch (context)
50864 {
50865 case pragma_compound:
50866 cp_parser_omp_taskwait (parser, pragma_tok);
50867 return false;
50868 case pragma_stmt:
50869 error_at (pragma_tok->location,
50870 "%<#pragma %s%> may only be used in compound statements",
50871 "omp taskwait");
50872 ret = true;
50873 break;
50874 default:
50875 goto bad_stmt;
50876 }
50877 break;
50878
50879 case PRAGMA_OMP_TASKYIELD:
50880 switch (context)
50881 {
50882 case pragma_compound:
50883 cp_parser_omp_taskyield (parser, pragma_tok);
50884 return false;
50885 case pragma_stmt:
50886 error_at (pragma_tok->location,
50887 "%<#pragma %s%> may only be used in compound statements",
50888 "omp taskyield");
50889 ret = true;
50890 break;
50891 default:
50892 goto bad_stmt;
50893 }
50894 break;
50895
50896 case PRAGMA_OMP_CANCEL:
50897 switch (context)
50898 {
50899 case pragma_compound:
50900 cp_parser_omp_cancel (parser, pragma_tok);
50901 return false;
50902 case pragma_stmt:
50903 error_at (pragma_tok->location,
50904 "%<#pragma %s%> may only be used in compound statements",
50905 "omp cancel");
50906 ret = true;
50907 break;
50908 default:
50909 goto bad_stmt;
50910 }
50911 break;
50912
50913 case PRAGMA_OMP_CANCELLATION_POINT:
50914 return cp_parser_omp_cancellation_point (parser, pragma_tok, context);
50915
50916 case PRAGMA_OMP_THREADPRIVATE:
50917 cp_parser_omp_threadprivate (parser, pragma_tok);
50918 return false;
50919
50920 case PRAGMA_OMP_DECLARE:
50921 return cp_parser_omp_declare (parser, pragma_tok, context);
50922
50923 case PRAGMA_OACC_DECLARE:
50924 cp_parser_oacc_declare (parser, pragma_tok);
50925 return false;
50926
50927 case PRAGMA_OACC_ENTER_DATA:
50928 if (context == pragma_stmt)
50929 {
50930 error_at (pragma_tok->location,
50931 "%<#pragma %s%> may only be used in compound statements",
50932 "acc enter data");
50933 ret = true;
50934 break;
50935 }
50936 else if (context != pragma_compound)
50937 goto bad_stmt;
50938 cp_parser_omp_construct (parser, pragma_tok, if_p);
50939 return true;
50940
50941 case PRAGMA_OACC_EXIT_DATA:
50942 if (context == pragma_stmt)
50943 {
50944 error_at (pragma_tok->location,
50945 "%<#pragma %s%> may only be used in compound statements",
50946 "acc exit data");
50947 ret = true;
50948 break;
50949 }
50950 else if (context != pragma_compound)
50951 goto bad_stmt;
50952 cp_parser_omp_construct (parser, pragma_tok, if_p);
50953 return true;
50954
50955 case PRAGMA_OACC_ROUTINE:
50956 if (context != pragma_external)
50957 {
50958 error_at (pragma_tok->location,
50959 "%<#pragma acc routine%> must be at file scope");
50960 ret = true;
50961 break;
50962 }
50963 cp_parser_oacc_routine (parser, pragma_tok, context);
50964 return false;
50965
50966 case PRAGMA_OACC_UPDATE:
50967 if (context == pragma_stmt)
50968 {
50969 error_at (pragma_tok->location,
50970 "%<#pragma %s%> may only be used in compound statements",
50971 "acc update");
50972 ret = true;
50973 break;
50974 }
50975 else if (context != pragma_compound)
50976 goto bad_stmt;
50977 cp_parser_omp_construct (parser, pragma_tok, if_p);
50978 return true;
50979
50980 case PRAGMA_OACC_WAIT:
50981 if (context == pragma_stmt)
50982 {
50983 error_at (pragma_tok->location,
50984 "%<#pragma %s%> may only be used in compound statements",
50985 "acc wait");
50986 ret = true;
50987 break;
50988 }
50989 else if (context != pragma_compound)
50990 goto bad_stmt;
50991 cp_parser_omp_construct (parser, pragma_tok, if_p);
50992 return true;
50993 case PRAGMA_OMP_ALLOCATE:
50994 cp_parser_omp_allocate (parser, pragma_tok);
50995 return false;
50996 case PRAGMA_OACC_ATOMIC:
50997 case PRAGMA_OACC_CACHE:
50998 case PRAGMA_OACC_DATA:
50999 case PRAGMA_OACC_HOST_DATA:
51000 case PRAGMA_OACC_KERNELS:
51001 case PRAGMA_OACC_LOOP:
51002 case PRAGMA_OACC_PARALLEL:
51003 case PRAGMA_OACC_SERIAL:
51004 case PRAGMA_OMP_ASSUME:
51005 case PRAGMA_OMP_ATOMIC:
51006 case PRAGMA_OMP_CRITICAL:
51007 case PRAGMA_OMP_DISTRIBUTE:
51008 case PRAGMA_OMP_FOR:
51009 case PRAGMA_OMP_LOOP:
51010 case PRAGMA_OMP_MASKED:
51011 case PRAGMA_OMP_MASTER:
51012 case PRAGMA_OMP_PARALLEL:
51013 case PRAGMA_OMP_SCOPE:
51014 case PRAGMA_OMP_SECTIONS:
51015 case PRAGMA_OMP_SIMD:
51016 case PRAGMA_OMP_SINGLE:
51017 case PRAGMA_OMP_TASK:
51018 case PRAGMA_OMP_TASKGROUP:
51019 case PRAGMA_OMP_TASKLOOP:
51020 case PRAGMA_OMP_TEAMS:
51021 if (context != pragma_stmt && context != pragma_compound)
51022 goto bad_stmt;
51023 stmt = push_omp_privatization_clauses (false);
51024 cp_parser_omp_construct (parser, pragma_tok, if_p);
51025 pop_omp_privatization_clauses (stmt);
51026 return true;
51027
51028 case PRAGMA_OMP_REQUIRES:
51029 if (context != pragma_external)
51030 {
51031 error_at (pragma_tok->location,
51032 "%<#pragma omp requires%> may only be used at file or "
51033 "namespace scope");
51034 ret = true;
51035 break;
51036 }
51037 return cp_parser_omp_requires (parser, pragma_tok);
51038
51039 case PRAGMA_OMP_ASSUMES:
51040 if (context != pragma_external)
51041 {
51042 error_at (pragma_tok->location,
51043 "%<#pragma omp assumes%> may only be used at file or "
51044 "namespace scope");
51045 ret = true;
51046 break;
51047 }
51048 return cp_parser_omp_assumes (parser, pragma_tok);
51049
51050 case PRAGMA_OMP_NOTHING:
51051 cp_parser_omp_nothing (parser, pragma_tok);
51052 return false;
51053
51054 case PRAGMA_OMP_ERROR:
51055 return cp_parser_omp_error (parser, pragma_tok, context);
51056
51057 case PRAGMA_OMP_ORDERED:
51058 if (context != pragma_stmt && context != pragma_compound)
51059 goto bad_stmt;
51060 stmt = push_omp_privatization_clauses (false);
51061 ret = cp_parser_omp_ordered (parser, pragma_tok, context, if_p);
51062 pop_omp_privatization_clauses (stmt);
51063 return ret;
51064
51065 case PRAGMA_OMP_TARGET:
51066 if (context != pragma_stmt && context != pragma_compound)
51067 goto bad_stmt;
51068 stmt = push_omp_privatization_clauses (false);
51069 ret = cp_parser_omp_target (parser, pragma_tok, context, if_p);
51070 pop_omp_privatization_clauses (stmt);
51071 return ret;
51072
51073 case PRAGMA_OMP_BEGIN:
51074 cp_parser_omp_begin (parser, pragma_tok);
51075 return false;
51076
51077 case PRAGMA_OMP_END:
51078 cp_parser_omp_end (parser, pragma_tok);
51079 return false;
51080
51081 case PRAGMA_OMP_SCAN:
51082 error_at (pragma_tok->location,
51083 "%<#pragma omp scan%> may only be used in "
51084 "a loop construct with %<inscan%> %<reduction%> clause");
51085 break;
51086
51087 case PRAGMA_OMP_SECTION:
51088 error_at (pragma_tok->location,
51089 "%<#pragma omp section%> may only be used in "
51090 "%<#pragma omp sections%> construct");
51091 break;
51092
51093 case PRAGMA_IVDEP:
51094 case PRAGMA_UNROLL:
51095 case PRAGMA_NOVECTOR:
51096 {
51097 bool ivdep = false;
51098 tree unroll = NULL_TREE;
51099 bool novector = false;
51100 const char *pragma_str;
51101
51102 switch (id)
51103 {
51104 case PRAGMA_IVDEP:
51105 pragma_str = "ivdep";
51106 break;
51107 case PRAGMA_UNROLL:
51108 pragma_str = "unroll";
51109 break;
51110 case PRAGMA_NOVECTOR:
51111 pragma_str = "novector";
51112 break;
51113 default:
51114 gcc_unreachable ();
51115 }
51116
51117 if (context == pragma_external)
51118 {
51119 error_at (pragma_tok->location,
51120 "%<#pragma GCC %s%> must be inside a function",
51121 pragma_str);
51122 break;
51123 }
51124
51125 cp_token *tok = pragma_tok;
51126 bool has_more = true;
51127 do
51128 {
51129 switch (cp_parser_pragma_kind (token: tok))
51130 {
51131 case PRAGMA_IVDEP:
51132 {
51133 if (tok != pragma_tok)
51134 tok = cp_lexer_consume_token (lexer: parser->lexer);
51135 ivdep = cp_parser_pragma_ivdep (parser, pragma_tok: tok);
51136 break;
51137 }
51138 case PRAGMA_UNROLL:
51139 {
51140 if (tok != pragma_tok)
51141 tok = cp_lexer_consume_token (lexer: parser->lexer);
51142 unroll = cp_parser_pragma_unroll (parser, pragma_tok: tok);
51143 break;
51144 }
51145 case PRAGMA_NOVECTOR:
51146 {
51147 if (tok != pragma_tok)
51148 tok = cp_lexer_consume_token (lexer: parser->lexer);
51149 novector = cp_parser_pragma_novector (parser, pragma_tok: tok);
51150 break;
51151 }
51152 default:
51153 has_more = false;
51154 break;
51155 }
51156 tok = cp_lexer_peek_token (lexer: the_parser->lexer);
51157 has_more = has_more && tok->type == CPP_PRAGMA;
51158 }
51159 while (has_more);
51160
51161 if (tok->type != CPP_KEYWORD
51162 || (tok->keyword != RID_FOR
51163 && tok->keyword != RID_WHILE
51164 && tok->keyword != RID_DO))
51165 {
51166 cp_parser_error (parser, gmsgid: "for, while or do statement expected");
51167 return false;
51168 }
51169 cp_parser_iteration_statement (parser, if_p, ivdep, unroll, novector);
51170 return true;
51171 }
51172
51173 default:
51174 gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
51175 c_invoke_pragma_handler (id);
51176 break;
51177
51178 bad_stmt:
51179 cp_parser_error (parser, gmsgid: "expected declaration specifiers");
51180 break;
51181 }
51182
51183 cp_parser_skip_to_pragma_eol (parser, pragma_tok);
51184 return ret;
51185}
51186
51187/* Helper for pragma_lex in preprocess-only mode; in this mode, we have not
51188 populated the lexer with any tokens (the tokens rather being read by
51189 c-ppoutput.c's machinery), so we need to read enough tokens now to handle
51190 a pragma. */
51191static void
51192maybe_read_tokens_for_pragma_lex ()
51193{
51194 const auto lexer = the_parser->lexer;
51195 if (!lexer->buffer->is_empty ())
51196 return;
51197
51198 /* Read the rest of the tokens comprising the pragma line. */
51199 cp_token *tok;
51200 do
51201 {
51202 tok = vec_safe_push (v&: lexer->buffer, obj: cp_token ());
51203 cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, token: tok);
51204 gcc_assert (tok->type != CPP_EOF);
51205 } while (tok->type != CPP_PRAGMA_EOL);
51206 lexer->next_token = lexer->buffer->address ();
51207 lexer->last_token = lexer->next_token + lexer->buffer->length () - 1;
51208}
51209
51210/* The interface the pragma parsers have to the lexer. */
51211
51212enum cpp_ttype
51213pragma_lex (tree *value, location_t *loc)
51214{
51215 if (flag_preprocess_only)
51216 maybe_read_tokens_for_pragma_lex ();
51217
51218 cp_token *tok = cp_lexer_peek_token (lexer: the_parser->lexer);
51219 enum cpp_ttype ret = tok->type;
51220
51221 *value = tok->u.value;
51222 if (loc)
51223 *loc = tok->location;
51224
51225 if (ret == CPP_PRAGMA_EOL)
51226 ret = CPP_EOF;
51227 else if (ret == CPP_STRING)
51228 *value = cp_parser_string_literal (parser: the_parser, /*translate=*/false,
51229 /*wide_ok=*/false);
51230 else
51231 {
51232 if (ret == CPP_KEYWORD)
51233 ret = CPP_NAME;
51234 cp_lexer_consume_token (lexer: the_parser->lexer);
51235 }
51236
51237 return ret;
51238}
51239
51240void
51241pragma_lex_discard_to_eol ()
51242{
51243 /* We have already read all the tokens, so we just need to discard
51244 them here. */
51245 const auto lexer = the_parser->lexer;
51246 lexer->next_token = lexer->last_token;
51247 lexer->buffer->truncate (size: 0);
51248}
51249
51250
51251/* External interface. */
51252
51253/* Parse one entire translation unit. */
51254
51255void
51256c_parse_file (void)
51257{
51258 static bool already_called = false;
51259
51260 if (already_called)
51261 fatal_error (input_location,
51262 "multi-source compilation not implemented for C++");
51263 already_called = true;
51264
51265 /* cp_lexer_new_main is called before doing any GC allocation
51266 because tokenization might load a PCH file. */
51267 cp_lexer_new_main ();
51268
51269 cp_parser_translation_unit (parser: the_parser);
51270 class_decl_loc_t::diag_mismatched_tags ();
51271
51272 the_parser = NULL;
51273
51274 finish_translation_unit ();
51275}
51276
51277/* Create an identifier for a generic parameter type (a synthesized
51278 template parameter implied by `auto' or a concept identifier). */
51279
51280static GTY(()) int generic_parm_count;
51281static tree
51282make_generic_type_name ()
51283{
51284 char buf[32];
51285 sprintf (s: buf, format: "auto:%d", ++generic_parm_count);
51286 return get_identifier (buf);
51287}
51288
51289/* Add an implicit template type parameter to the CURRENT_TEMPLATE_PARMS
51290 (creating a new template parameter list if necessary). Returns the newly
51291 created template type parm. */
51292
51293static tree
51294synthesize_implicit_template_parm (cp_parser *parser, tree constr)
51295{
51296 /* A requires-clause is not a function and cannot have placeholders. */
51297 if (current_binding_level->requires_expression)
51298 {
51299 error ("placeholder type not allowed in this context");
51300 return error_mark_node;
51301 }
51302
51303 gcc_assert (current_binding_level->kind == sk_function_parms);
51304
51305 /* We are either continuing a function template that already contains implicit
51306 template parameters, creating a new fully-implicit function template, or
51307 extending an existing explicit function template with implicit template
51308 parameters. */
51309
51310 cp_binding_level *const entry_scope = current_binding_level;
51311
51312 bool become_template = false;
51313 cp_binding_level *parent_scope = 0;
51314
51315 if (parser->implicit_template_scope)
51316 {
51317 gcc_assert (parser->implicit_template_parms);
51318
51319 current_binding_level = parser->implicit_template_scope;
51320 }
51321 else
51322 {
51323 /* Roll back to the existing template parameter scope (in the case of
51324 extending an explicit function template) or introduce a new template
51325 parameter scope ahead of the function parameter scope (or class scope
51326 in the case of out-of-line member definitions). The function scope is
51327 added back after template parameter synthesis below. */
51328
51329 cp_binding_level *scope = entry_scope;
51330
51331 while (scope->kind == sk_function_parms)
51332 {
51333 parent_scope = scope;
51334 scope = scope->level_chain;
51335 }
51336 if (current_class_type && !LAMBDA_TYPE_P (current_class_type))
51337 {
51338 /* If not defining a class, then any class scope is a scope level in
51339 an out-of-line member definition. In this case simply wind back
51340 beyond the first such scope to inject the template parameter list.
51341 Otherwise wind back to the class being defined. The latter can
51342 occur in class member friend declarations such as:
51343
51344 class A {
51345 void foo (auto);
51346 };
51347 class B {
51348 friend void A::foo (auto);
51349 };
51350
51351 The template parameter list synthesized for the friend declaration
51352 must be injected in the scope of 'B'. This can also occur in
51353 erroneous cases such as:
51354
51355 struct A {
51356 struct B {
51357 void foo (auto);
51358 };
51359 void B::foo (auto) {}
51360 };
51361
51362 Here the attempted definition of 'B::foo' within 'A' is ill-formed
51363 but, nevertheless, the template parameter list synthesized for the
51364 declarator should be injected into the scope of 'A' as if the
51365 ill-formed template was specified explicitly. */
51366
51367 while (scope->kind == sk_class && !scope->defining_class_p)
51368 {
51369 parent_scope = scope;
51370 scope = scope->level_chain;
51371 }
51372 }
51373
51374 current_binding_level = scope;
51375
51376 if (scope->kind != sk_template_parms
51377 || !function_being_declared_is_template_p (parser))
51378 {
51379 /* Introduce a new template parameter list for implicit template
51380 parameters. */
51381
51382 become_template = true;
51383
51384 parser->implicit_template_scope
51385 = begin_scope (sk_template_parms, NULL);
51386
51387 ++processing_template_decl;
51388
51389 parser->fully_implicit_function_template_p = true;
51390 ++parser->num_template_parameter_lists;
51391 }
51392 else
51393 {
51394 /* Synthesize implicit template parameters at the end of the explicit
51395 template parameter list. */
51396
51397 gcc_assert (current_template_parms);
51398
51399 parser->implicit_template_scope = scope;
51400
51401 tree v = INNERMOST_TEMPLATE_PARMS (current_template_parms);
51402 parser->implicit_template_parms
51403 = TREE_VEC_ELT (v, TREE_VEC_LENGTH (v) - 1);
51404 }
51405 }
51406
51407 /* Synthesize a new template parameter and track the current template
51408 parameter chain with implicit_template_parms. */
51409
51410 tree proto = constr ? DECL_INITIAL (constr) : NULL_TREE;
51411 tree synth_id = make_generic_type_name ();
51412 bool non_type = false;
51413
51414 /* Synthesize the type template parameter. */
51415 gcc_assert(!proto || TREE_CODE (proto) == TYPE_DECL);
51416 tree synth_tmpl_parm = finish_template_type_parm (class_type_node, synth_id);
51417
51418 if (become_template)
51419 current_template_parms = tree_cons (size_int (current_template_depth + 1),
51420 NULL_TREE, current_template_parms);
51421
51422 /* Attach the constraint to the parm before processing. */
51423 tree node = build_tree_list (NULL_TREE, synth_tmpl_parm);
51424 TREE_TYPE (node) = constr;
51425 tree new_parm
51426 = process_template_parm (parser->implicit_template_parms,
51427 input_location,
51428 node,
51429 /*non_type=*/non_type,
51430 /*param_pack=*/false);
51431 // Process_template_parm returns the list of parms, and
51432 // parser->implicit_template_parms holds the final node of the parm
51433 // list. We really want to manipulate the newly appended element.
51434 gcc_checking_assert (!parser->implicit_template_parms
51435 || parser->implicit_template_parms == new_parm);
51436 if (parser->implicit_template_parms)
51437 new_parm = TREE_CHAIN (new_parm);
51438 gcc_checking_assert (!TREE_CHAIN (new_parm));
51439
51440 // Record the last implicit parm node
51441 parser->implicit_template_parms = new_parm;
51442
51443 /* Mark the synthetic declaration "virtual". This is used when
51444 comparing template-heads to determine if whether an abbreviated
51445 function template is equivalent to an explicit template.
51446
51447 Note that DECL_ARTIFICIAL is used elsewhere for template
51448 parameters. */
51449 if (TREE_VALUE (new_parm) != error_mark_node)
51450 DECL_IMPLICIT_TEMPLATE_PARM_P (TREE_VALUE (new_parm)) = true;
51451
51452 tree new_decl = get_local_decls ();
51453 if (non_type)
51454 /* Return the TEMPLATE_PARM_INDEX, not the PARM_DECL. */
51455 new_decl = DECL_INITIAL (new_decl);
51456
51457 /* If creating a fully implicit function template, start the new implicit
51458 template parameter list with this synthesized type, otherwise grow the
51459 current template parameter list. */
51460
51461 if (become_template)
51462 {
51463 parent_scope->level_chain = current_binding_level;
51464
51465 tree new_parms = make_tree_vec (1);
51466 TREE_VEC_ELT (new_parms, 0) = parser->implicit_template_parms;
51467 TREE_VALUE (current_template_parms) = new_parms;
51468 }
51469 else
51470 {
51471 tree& new_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
51472 int new_parm_idx = TREE_VEC_LENGTH (new_parms);
51473 new_parms = grow_tree_vec (v: new_parms, new_parm_idx + 1);
51474 TREE_VEC_ELT (new_parms, new_parm_idx) = parser->implicit_template_parms;
51475 }
51476
51477 /* If the new parameter was constrained, we need to add that to the
51478 constraints in the template parameter list. */
51479 if (tree req = TEMPLATE_PARM_CONSTRAINTS (new_parm))
51480 {
51481 tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
51482 reqs = combine_constraint_expressions (reqs, req);
51483 TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
51484 }
51485
51486 current_binding_level = entry_scope;
51487
51488 return new_decl;
51489}
51490
51491/* Finish the declaration of a fully implicit function template. Such a
51492 template has no explicit template parameter list so has not been through the
51493 normal template head and tail processing. synthesize_implicit_template_parm
51494 tries to do the head; this tries to do the tail. MEMBER_DECL_OPT should be
51495 provided if the declaration is a class member such that its template
51496 declaration can be completed. If MEMBER_DECL_OPT is provided the finished
51497 form is returned. Otherwise NULL_TREE is returned. */
51498
51499static tree
51500finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
51501{
51502 gcc_assert (parser->fully_implicit_function_template_p);
51503
51504 if (member_decl_opt && member_decl_opt != error_mark_node
51505 && DECL_VIRTUAL_P (member_decl_opt))
51506 {
51507 error_at (DECL_SOURCE_LOCATION (member_decl_opt),
51508 "implicit templates may not be %<virtual%>");
51509 DECL_VIRTUAL_P (member_decl_opt) = false;
51510 }
51511
51512 if (member_decl_opt)
51513 member_decl_opt = finish_member_template_decl (member_decl_opt);
51514 end_template_decl ();
51515
51516 parser->fully_implicit_function_template_p = false;
51517 parser->implicit_template_parms = 0;
51518 parser->implicit_template_scope = 0;
51519 --parser->num_template_parameter_lists;
51520
51521 return member_decl_opt;
51522}
51523
51524/* Like finish_fully_implicit_template, but to be used in error
51525 recovery, rearranging scopes so that we restore the state we had
51526 before synthesize_implicit_template_parm inserted the implement
51527 template parms scope. */
51528
51529static void
51530abort_fully_implicit_template (cp_parser *parser)
51531{
51532 cp_binding_level *return_to_scope = current_binding_level;
51533
51534 if (parser->implicit_template_scope
51535 && return_to_scope != parser->implicit_template_scope)
51536 {
51537 cp_binding_level *child = return_to_scope;
51538 for (cp_binding_level *scope = child->level_chain;
51539 scope != parser->implicit_template_scope;
51540 scope = child->level_chain)
51541 child = scope;
51542 child->level_chain = parser->implicit_template_scope->level_chain;
51543 parser->implicit_template_scope->level_chain = return_to_scope;
51544 current_binding_level = parser->implicit_template_scope;
51545 }
51546 else
51547 return_to_scope = return_to_scope->level_chain;
51548
51549 finish_fully_implicit_template (parser, NULL);
51550
51551 gcc_assert (current_binding_level == return_to_scope);
51552}
51553
51554/* Helper function for diagnostics that have complained about things
51555 being used with 'extern "C"' linkage.
51556
51557 Attempt to issue a note showing where the 'extern "C"' linkage began. */
51558
51559void
51560maybe_show_extern_c_location (void)
51561{
51562 if (the_parser->innermost_linkage_specification_location != UNKNOWN_LOCATION)
51563 inform (the_parser->innermost_linkage_specification_location,
51564 "%<extern \"C\"%> linkage started here");
51565}
51566
51567#include "gt-cp-parser.h"
51568

source code of gcc/cp/parser.cc