LCOV - code coverage report
Current view: top level - gcc/cp - parser.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.9 % 21693 19711
Test Date: 2024-04-13 14:00:49 Functions: 85.3 % 662 565
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       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                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #define INCLUDE_MEMORY
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "cp-tree.h"
      26                 :             : #include "c-family/c-common.h"
      27                 :             : #include "timevar.h"
      28                 :             : #include "stringpool.h"
      29                 :             : #include "cgraph.h"
      30                 :             : #include "print-tree.h"
      31                 :             : #include "attribs.h"
      32                 :             : #include "trans-mem.h"
      33                 :             : #include "intl.h"
      34                 :             : #include "decl.h"
      35                 :             : #include "c-family/c-objc.h"
      36                 :             : #include "plugin.h"
      37                 :             : #include "tree-pretty-print.h"
      38                 :             : #include "parser.h"
      39                 :             : #include "gomp-constants.h"
      40                 :             : #include "omp-general.h"
      41                 :             : #include "omp-offload.h"
      42                 :             : #include "c-family/c-indentation.h"
      43                 :             : #include "context.h"
      44                 :             : #include "gcc-rich-location.h"
      45                 :             : #include "tree-iterator.h"
      46                 :             : #include "cp-name-hint.h"
      47                 :             : #include "memmodel.h"
      48                 :             : #include "c-family/known-headers.h"
      49                 :             : #include "contracts.h"
      50                 :             : #include "bitmap.h"
      51                 :             : #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. */
      60                 :             : enum 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. */
     119                 :             : enum 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 */
     131                 :             : enum 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                 :             : 
     192                 :             : class type_id_in_expr_sentinel
     193                 :             : {
     194                 :             :   cp_parser *parser;
     195                 :             :   bool saved;
     196                 :             : public:
     197                 :     2631453 :   type_id_in_expr_sentinel (cp_parser *parser, bool set = true)
     198                 :     2631453 :     : parser (parser),
     199                 :     2631453 :       saved (parser->in_type_id_in_expr_p)
     200                 :     2631453 :   { parser->in_type_id_in_expr_p = set; }
     201                 :     2631453 :   ~type_id_in_expr_sentinel ()
     202                 :     2631453 :   { parser->in_type_id_in_expr_p = saved; }
     203                 :             : };
     204                 :             : 
     205                 :             : /* Prototypes.  */
     206                 :             : 
     207                 :             : static cp_lexer *cp_lexer_new_main
     208                 :             :   (void);
     209                 :             : static cp_lexer *cp_lexer_new_from_tokens
     210                 :             :   (cp_token_cache *tokens);
     211                 :             : static void cp_lexer_destroy
     212                 :             :   (cp_lexer *);
     213                 :             : static int cp_lexer_saving_tokens
     214                 :             :   (const cp_lexer *);
     215                 :             : static cp_token *cp_lexer_token_at
     216                 :             :   (cp_lexer *, cp_token_position);
     217                 :             : static void cp_lexer_get_preprocessor_token
     218                 :             :   (unsigned, cp_token *);
     219                 :             : static inline cp_token *cp_lexer_peek_token
     220                 :             :   (cp_lexer *);
     221                 :             : static cp_token *cp_lexer_peek_nth_token
     222                 :             :   (cp_lexer *, size_t);
     223                 :             : static inline bool cp_lexer_next_token_is
     224                 :             :   (cp_lexer *, enum cpp_ttype);
     225                 :             : static bool cp_lexer_next_token_is_not
     226                 :             :   (cp_lexer *, enum cpp_ttype);
     227                 :             : static bool cp_lexer_next_token_is_keyword
     228                 :             :   (cp_lexer *, enum rid);
     229                 :             : static cp_token *cp_lexer_consume_token
     230                 :             :   (cp_lexer *);
     231                 :             : static void cp_lexer_purge_token
     232                 :             :   (cp_lexer *);
     233                 :             : static void cp_lexer_purge_tokens_after
     234                 :             :   (cp_lexer *, cp_token_position);
     235                 :             : static void cp_lexer_save_tokens
     236                 :             :   (cp_lexer *);
     237                 :             : static void cp_lexer_commit_tokens
     238                 :             :   (cp_lexer *);
     239                 :             : static void cp_lexer_rollback_tokens
     240                 :             :   (cp_lexer *);
     241                 :             : static void cp_lexer_print_token
     242                 :             :   (FILE *, cp_token *);
     243                 :             : static inline bool cp_lexer_debugging_p
     244                 :             :   (cp_lexer *);
     245                 :             : static void cp_lexer_start_debugging
     246                 :             :   (cp_lexer *) ATTRIBUTE_UNUSED;
     247                 :             : static void cp_lexer_stop_debugging
     248                 :             :   (cp_lexer *) ATTRIBUTE_UNUSED;
     249                 :             : static const cp_trait *cp_lexer_peek_trait
     250                 :             :   (cp_lexer *);
     251                 :             : static const cp_trait *cp_lexer_peek_trait_expr
     252                 :             :   (cp_lexer *);
     253                 :             : static const cp_trait *cp_lexer_peek_trait_type
     254                 :             :   (cp_lexer *);
     255                 :             : 
     256                 :             : static cp_token_cache *cp_token_cache_new
     257                 :             :   (cp_token *, cp_token *);
     258                 :             : static tree cp_parser_late_noexcept_specifier
     259                 :             :   (cp_parser *, tree);
     260                 :             : static void noexcept_override_late_checks
     261                 :             :   (tree);
     262                 :             : 
     263                 :             : static void cp_parser_initial_pragma
     264                 :             :   (cp_token *);
     265                 :             : 
     266                 :             : static bool cp_parser_omp_declare_reduction_exprs
     267                 :             :   (tree, cp_parser *);
     268                 :             : static void cp_finalize_oacc_routine
     269                 :             :   (cp_parser *, tree, bool);
     270                 :             : 
     271                 :             : static 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.  */
     282                 :             : static FILE *cp_lexer_debug_stream;
     283                 :             : 
     284                 :             : /* Nonzero if we are parsing an unevaluated operand: an operand to
     285                 :             :    sizeof, typeof, or alignof.  */
     286                 :             : int 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                 :             : 
     294                 :             : static void
     295                 :           0 : cp_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                 :           0 :   unsigned i, nprinted;
     300                 :           0 :   cp_token *token;
     301                 :           0 :   bool do_print;
     302                 :             : 
     303                 :           0 :   fprintf (file, "%u tokens\n", vec_safe_length (buffer));
     304                 :             : 
     305                 :           0 :   if (buffer == NULL)
     306                 :           0 :     return;
     307                 :             : 
     308                 :           0 :   if (num == 0)
     309                 :           0 :     num = buffer->length ();
     310                 :             : 
     311                 :           0 :   if (start_token == NULL)
     312                 :           0 :     start_token = buffer->address ();
     313                 :             : 
     314                 :           0 :   if (start_token > buffer->address ())
     315                 :             :     {
     316                 :           0 :       cp_lexer_print_token (file, &(*buffer)[0]);
     317                 :           0 :       fprintf (file, " ... ");
     318                 :             :     }
     319                 :             : 
     320                 :             :   do_print = false;
     321                 :             :   nprinted = 0;
     322                 :           0 :   for (i = 0; buffer->iterate (i, &token) && nprinted < num; i++)
     323                 :             :     {
     324                 :           0 :       if (token == start_token)
     325                 :             :         do_print = true;
     326                 :             : 
     327                 :           0 :       if (!do_print)
     328                 :           0 :         continue;
     329                 :             : 
     330                 :           0 :       nprinted++;
     331                 :           0 :       if (token == curr_token)
     332                 :           0 :         fprintf (file, "[[");
     333                 :             : 
     334                 :           0 :       cp_lexer_print_token (file, token);
     335                 :             : 
     336                 :           0 :       if (token == curr_token)
     337                 :           0 :         fprintf (file, "]]");
     338                 :             : 
     339                 :           0 :       switch (token->type)
     340                 :             :         {
     341                 :           0 :           case CPP_SEMICOLON:
     342                 :           0 :           case CPP_OPEN_BRACE:
     343                 :           0 :           case CPP_CLOSE_BRACE:
     344                 :           0 :           case CPP_EOF:
     345                 :           0 :             fputc ('\n', file);
     346                 :           0 :             break;
     347                 :             : 
     348                 :           0 :           default:
     349                 :           0 :             fputc (' ', file);
     350                 :             :         }
     351                 :             :     }
     352                 :             : 
     353                 :           0 :   if (i == num && i < buffer->length ())
     354                 :             :     {
     355                 :           0 :       fprintf (file, " ... ");
     356                 :           0 :       cp_lexer_print_token (file, &buffer->last ());
     357                 :             :     }
     358                 :             : 
     359                 :           0 :   fprintf (file, "\n");
     360                 :             : }
     361                 :             : 
     362                 :             : 
     363                 :             : /* Dump all tokens in BUFFER to stderr.  */
     364                 :             : 
     365                 :             : void
     366                 :           0 : cp_lexer_debug_tokens (vec<cp_token, va_gc> *buffer)
     367                 :             : {
     368                 :           0 :   cp_lexer_dump_tokens (stderr, buffer, NULL, 0, NULL);
     369                 :           0 : }
     370                 :             : 
     371                 :             : DEBUG_FUNCTION void
     372                 :           0 : debug (vec<cp_token, va_gc> &ref)
     373                 :             : {
     374                 :           0 :   cp_lexer_dump_tokens (stderr, &ref, NULL, 0, NULL);
     375                 :           0 : }
     376                 :             : 
     377                 :             : DEBUG_FUNCTION void
     378                 :           0 : debug (vec<cp_token, va_gc> *ptr)
     379                 :             : {
     380                 :           0 :   if (ptr)
     381                 :           0 :     debug (*ptr);
     382                 :             :   else
     383                 :           0 :     fprintf (stderr, "<nil>\n");
     384                 :           0 : }
     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                 :             : 
     390                 :             : static void
     391                 :           0 : cp_debug_print_tree_if_set (FILE *file, const char *desc, tree t)
     392                 :             : {
     393                 :           0 :   if (t)
     394                 :             :     {
     395                 :           0 :       fprintf (file, "%s: ", desc);
     396                 :           0 :       print_node_brief (file, "", t, 0);
     397                 :             :     }
     398                 :           0 : }
     399                 :             : 
     400                 :             : 
     401                 :             : /* Dump parser context C to FILE.  */
     402                 :             : 
     403                 :             : static void
     404                 :           0 : cp_debug_print_context (FILE *file, cp_parser_context *c)
     405                 :             : {
     406                 :           0 :   const char *status_s[] = { "OK", "ERROR", "COMMITTED" };
     407                 :           0 :   fprintf (file, "{ status = %s, scope = ", status_s[c->status]);
     408                 :           0 :   print_node_brief (file, "", c->object_type, 0);
     409                 :           0 :   fprintf (file, "}\n");
     410                 :           0 : }
     411                 :             : 
     412                 :             : 
     413                 :             : /* Print the stack of parsing contexts to FILE starting with FIRST.  */
     414                 :             : 
     415                 :             : static void
     416                 :           0 : cp_debug_print_context_stack (FILE *file, cp_parser_context *first)
     417                 :             : {
     418                 :           0 :   unsigned i;
     419                 :           0 :   cp_parser_context *c;
     420                 :             : 
     421                 :           0 :   fprintf (file, "Parsing context stack:\n");
     422                 :           0 :   for (i = 0, c = first; c; c = c->next, i++)
     423                 :             :     {
     424                 :           0 :       fprintf (file, "\t#%u: ", i);
     425                 :           0 :       cp_debug_print_context (file, c);
     426                 :             :     }
     427                 :           0 : }
     428                 :             : 
     429                 :             : 
     430                 :             : /* Print the value of FLAG to FILE.  DESC is a string describing the flag.  */
     431                 :             : 
     432                 :             : static void
     433                 :           0 : cp_debug_print_flag (FILE *file, const char *desc, bool flag)
     434                 :             : {
     435                 :           0 :   if (flag)
     436                 :           0 :     fprintf (file, "%s: true\n", desc);
     437                 :           0 : }
     438                 :             : 
     439                 :             : 
     440                 :             : /* Print an unparsed function entry UF to FILE.  */
     441                 :             : 
     442                 :             : static void
     443                 :           0 : cp_debug_print_unparsed_function (FILE *file, cp_unparsed_functions_entry *uf)
     444                 :             : {
     445                 :           0 :   unsigned i;
     446                 :           0 :   cp_default_arg_entry *default_arg_fn;
     447                 :           0 :   tree fn;
     448                 :             : 
     449                 :           0 :   fprintf (file, "\tFunctions with default args:\n");
     450                 :           0 :   for (i = 0;
     451                 :           0 :        vec_safe_iterate (uf->funs_with_default_args, i, &default_arg_fn);
     452                 :             :        i++)
     453                 :             :     {
     454                 :           0 :       fprintf (file, "\t\tClass type: ");
     455                 :           0 :       print_node_brief (file, "", default_arg_fn->class_type, 0);
     456                 :           0 :       fprintf (file, "\t\tDeclaration: ");
     457                 :           0 :       print_node_brief (file, "", default_arg_fn->decl, 0);
     458                 :           0 :       fprintf (file, "\n");
     459                 :             :     }
     460                 :             : 
     461                 :           0 :   fprintf (file, "\n\tFunctions with definitions that require "
     462                 :             :            "post-processing\n\t\t");
     463                 :           0 :   for (i = 0; vec_safe_iterate (uf->funs_with_definitions, i, &fn); i++)
     464                 :             :     {
     465                 :           0 :       print_node_brief (file, "", fn, 0);
     466                 :           0 :       fprintf (file, " ");
     467                 :             :     }
     468                 :           0 :   fprintf (file, "\n");
     469                 :             : 
     470                 :           0 :   fprintf (file, "\n\tNon-static data members with initializers that require "
     471                 :             :            "post-processing\n\t\t");
     472                 :           0 :   for (i = 0; vec_safe_iterate (uf->nsdmis, i, &fn); i++)
     473                 :             :     {
     474                 :           0 :       print_node_brief (file, "", fn, 0);
     475                 :           0 :       fprintf (file, " ");
     476                 :             :     }
     477                 :           0 :   fprintf (file, "\n");
     478                 :           0 : }
     479                 :             : 
     480                 :             : 
     481                 :             : /* Print the stack of unparsed member functions S to FILE.  */
     482                 :             : 
     483                 :             : static void
     484                 :           0 : cp_debug_print_unparsed_queues (FILE *file,
     485                 :             :                                 vec<cp_unparsed_functions_entry, va_gc> *s)
     486                 :             : {
     487                 :           0 :   unsigned i;
     488                 :           0 :   cp_unparsed_functions_entry *uf;
     489                 :             : 
     490                 :           0 :   fprintf (file, "Unparsed functions\n");
     491                 :           0 :   for (i = 0; vec_safe_iterate (s, i, &uf); i++)
     492                 :             :     {
     493                 :           0 :       fprintf (file, "#%u:\n", i);
     494                 :           0 :       cp_debug_print_unparsed_function (file, uf);
     495                 :             :     }
     496                 :           0 : }
     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                 :             : 
     502                 :             : static void
     503                 :           0 : cp_debug_parser_tokens (FILE *file, cp_parser *parser, int window_size)
     504                 :             : {
     505                 :           0 :   cp_token *next_token, *first_token, *start_token;
     506                 :             : 
     507                 :           0 :   if (file == NULL)
     508                 :           0 :     file = stderr;
     509                 :             : 
     510                 :           0 :   next_token = parser->lexer->next_token;
     511                 :           0 :   first_token = parser->lexer->buffer->address ();
     512                 :           0 :   start_token = (next_token > first_token + window_size / 2)
     513                 :           0 :                 ? next_token - window_size / 2
     514                 :             :                 : first_token;
     515                 :           0 :   cp_lexer_dump_tokens (file, parser->lexer->buffer, start_token, window_size,
     516                 :             :                         next_token);
     517                 :           0 : }
     518                 :             : 
     519                 :             : 
     520                 :             : /* Dump debugging information for the given PARSER.  If FILE is NULL,
     521                 :             :    the output is printed on stderr.  */
     522                 :             : 
     523                 :             : void
     524                 :           0 : cp_debug_parser (FILE *file, cp_parser *parser)
     525                 :             : {
     526                 :           0 :   const size_t window_size = 20;
     527                 :           0 :   cp_token *token;
     528                 :           0 :   expanded_location eloc;
     529                 :             : 
     530                 :           0 :   if (file == NULL)
     531                 :           0 :     file = stderr;
     532                 :             : 
     533                 :           0 :   fprintf (file, "Parser state\n\n");
     534                 :           0 :   fprintf (file, "Number of tokens: %u\n",
     535                 :           0 :            vec_safe_length (parser->lexer->buffer));
     536                 :           0 :   cp_debug_print_tree_if_set (file, "Lookup scope", parser->scope);
     537                 :           0 :   cp_debug_print_tree_if_set (file, "Object scope",
     538                 :             :                                      parser->object_scope);
     539                 :           0 :   cp_debug_print_tree_if_set (file, "Qualifying scope",
     540                 :             :                                      parser->qualifying_scope);
     541                 :           0 :   cp_debug_print_context_stack (file, parser->context);
     542                 :           0 :   cp_debug_print_flag (file, "Allow GNU extensions",
     543                 :           0 :                               parser->allow_gnu_extensions_p);
     544                 :           0 :   cp_debug_print_flag (file, "'>' token is greater-than",
     545                 :           0 :                               parser->greater_than_is_operator_p);
     546                 :           0 :   cp_debug_print_flag (file, "Default args allowed in current "
     547                 :           0 :                               "parameter list", parser->default_arg_ok_p);
     548                 :           0 :   cp_debug_print_flag (file, "Parsing integral constant-expression",
     549                 :           0 :                               parser->integral_constant_expression_p);
     550                 :           0 :   cp_debug_print_flag (file, "Allow non-constant expression in current "
     551                 :             :                               "constant-expression",
     552                 :           0 :                               parser->allow_non_integral_constant_expression_p);
     553                 :           0 :   cp_debug_print_flag (file, "Seen non-constant expression",
     554                 :           0 :                               parser->non_integral_constant_expression_p);
     555                 :           0 :   cp_debug_print_flag (file, "Local names forbidden in current context",
     556                 :           0 :                               (parser->local_variables_forbidden_p
     557                 :             :                                & LOCAL_VARS_FORBIDDEN));
     558                 :           0 :   cp_debug_print_flag (file, "'this' forbidden in current context",
     559                 :           0 :                               (parser->local_variables_forbidden_p
     560                 :             :                                & THIS_FORBIDDEN));
     561                 :           0 :   cp_debug_print_flag (file, "In unbraced linkage specification",
     562                 :           0 :                               parser->in_unbraced_linkage_specification_p);
     563                 :           0 :   cp_debug_print_flag (file, "Parsing a declarator",
     564                 :           0 :                               parser->in_declarator_p);
     565                 :           0 :   cp_debug_print_flag (file, "In template argument list",
     566                 :           0 :                               parser->in_template_argument_list_p);
     567                 :           0 :   cp_debug_print_flag (file, "Parsing an iteration statement",
     568                 :           0 :                               parser->in_statement & IN_ITERATION_STMT);
     569                 :           0 :   cp_debug_print_flag (file, "Parsing a switch statement",
     570                 :           0 :                               parser->in_statement & IN_SWITCH_STMT);
     571                 :           0 :   cp_debug_print_flag (file, "Parsing a structured OpenMP block",
     572                 :           0 :                               parser->in_statement & IN_OMP_BLOCK);
     573                 :           0 :   cp_debug_print_flag (file, "Parsing an OpenMP loop",
     574                 :           0 :                               parser->in_statement & IN_OMP_FOR);
     575                 :           0 :   cp_debug_print_flag (file, "Parsing an if statement",
     576                 :           0 :                               parser->in_statement & IN_IF_STMT);
     577                 :           0 :   cp_debug_print_flag (file, "Parsing a type-id in an expression "
     578                 :           0 :                               "context", parser->in_type_id_in_expr_p);
     579                 :           0 :   cp_debug_print_flag (file, "String expressions should be translated "
     580                 :             :                               "to execution character set",
     581                 :           0 :                               parser->translate_strings_p);
     582                 :           0 :   cp_debug_print_flag (file, "Parsing function body outside of a "
     583                 :           0 :                               "local class", parser->in_function_body);
     584                 :           0 :   cp_debug_print_flag (file, "Auto correct a colon to a scope operator",
     585                 :           0 :                               parser->colon_corrects_to_scope_p);
     586                 :           0 :   cp_debug_print_flag (file, "Colon doesn't start a class definition",
     587                 :           0 :                               parser->colon_doesnt_start_class_def_p);
     588                 :           0 :   cp_debug_print_flag (file, "Parsing an Objective-C++ message context",
     589                 :           0 :                               parser->objective_c_message_context_p);
     590                 :           0 :   if (parser->type_definition_forbidden_message)
     591                 :           0 :     fprintf (file, "Error message for forbidden type definitions: %s %s\n",
     592                 :             :              parser->type_definition_forbidden_message,
     593                 :           0 :              parser->type_definition_forbidden_message_arg
     594                 :             :              ? parser->type_definition_forbidden_message_arg : "<none>");
     595                 :           0 :   cp_debug_print_unparsed_queues (file, parser->unparsed_queues);
     596                 :           0 :   fprintf (file, "Number of class definitions in progress: %u\n",
     597                 :             :            parser->num_classes_being_defined);
     598                 :           0 :   fprintf (file, "Number of template parameter lists for the current "
     599                 :             :            "declaration: %u\n", parser->num_template_parameter_lists);
     600                 :           0 :   cp_debug_parser_tokens (file, parser, window_size);
     601                 :           0 :   token = parser->lexer->next_token;
     602                 :           0 :   fprintf (file, "Next token to parse:\n");
     603                 :           0 :   fprintf (file, "\tToken:  ");
     604                 :           0 :   cp_lexer_print_token (file, token);
     605                 :           0 :   eloc = expand_location (token->location);
     606                 :           0 :   fprintf (file, "\n\tFile:   %s\n", eloc.file);
     607                 :           0 :   fprintf (file, "\tLine:   %d\n", eloc.line);
     608                 :           0 :   fprintf (file, "\tColumn: %d\n", eloc.column);
     609                 :           0 : }
     610                 :             : 
     611                 :             : DEBUG_FUNCTION void
     612                 :           0 : debug (cp_parser &ref)
     613                 :             : {
     614                 :           0 :   cp_debug_parser (stderr, &ref);
     615                 :           0 : }
     616                 :             : 
     617                 :             : DEBUG_FUNCTION void
     618                 :           0 : debug (cp_parser *ptr)
     619                 :             : {
     620                 :           0 :   if (ptr)
     621                 :           0 :     debug (*ptr);
     622                 :             :   else
     623                 :           0 :     fprintf (stderr, "<nil>\n");
     624                 :           0 : }
     625                 :             : 
     626                 :             : /* Allocate memory for a new lexer object and return it.  */
     627                 :             : 
     628                 :             : static cp_lexer *
     629                 :      102649 : cp_lexer_alloc (void)
     630                 :             : {
     631                 :             :   /* Allocate the memory.  */
     632                 :      102649 :   cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> ();
     633                 :             : 
     634                 :             :   /* Initially we are not debugging.  */
     635                 :      102649 :   lexer->debugging_p = false;
     636                 :             : 
     637                 :      102649 :   lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);
     638                 :             : 
     639                 :             :   /* Create the buffer.  */
     640                 :      102649 :   vec_alloc (lexer->buffer, CP_LEXER_BUFFER_SIZE);
     641                 :             : 
     642                 :      102649 :   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.  */
     647                 :             : static inline bool
     648                 :   110708515 : cp_token_is_module_directive (cp_token *token)
     649                 :             : {
     650                 :   110708515 :   return token->keyword == RID__EXPORT
     651                 :   110708515 :     || token->keyword == RID__MODULE
     652                 :   110706867 :     || token->keyword == RID__IMPORT;
     653                 :             : }
     654                 :             : 
     655                 :             : /* Return TOKEN's pragma_kind if it is CPP_PRAGMA, otherwise
     656                 :             :    PRAGMA_NONE.  */
     657                 :             : 
     658                 :             : static enum pragma_kind
     659                 :     4014990 : cp_parser_pragma_kind (cp_token *token)
     660                 :             : {
     661                 :     4014990 :   if (token->type != CPP_PRAGMA)
     662                 :             :     return PRAGMA_NONE;
     663                 :             :   /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
     664                 :     3915121 :   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                 :             : 
     672                 :             : static void
     673                 :     1938001 : cp_lexer_handle_early_pragma (cp_lexer *lexer)
     674                 :             : {
     675                 :     1938001 :   const auto first_token = lexer->buffer->address ();
     676                 :     1938001 :   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                 :     1938001 :   auto begin = last_token;
     681                 :     1938001 :   gcc_assert (begin->type == CPP_PRAGMA_EOL);
     682                 :     7120599 :   while (begin->type != CPP_PRAGMA)
     683                 :             :     {
     684                 :     5185943 :       if (cp_token_is_module_directive (begin))
     685                 :             :         return;
     686                 :     5182598 :       gcc_assert (begin != first_token);
     687                 :     5182598 :       --begin;
     688                 :             :     }
     689                 :     1934656 :   gcc_assert (!lexer->next_token);
     690                 :     1934656 :   gcc_assert (!lexer->last_token);
     691                 :     1934656 :   lexer->next_token = begin;
     692                 :     1934656 :   lexer->last_token = last_token;
     693                 :             : 
     694                 :             :   /* Dispatch it.  */
     695                 :     1934656 :   const unsigned int id
     696                 :     1934656 :     = cp_parser_pragma_kind (cp_lexer_consume_token (lexer));
     697                 :     1934656 :   if (id >= PRAGMA_FIRST_EXTERNAL)
     698                 :     1873620 :     c_invoke_early_pragma_handler (id);
     699                 :             : 
     700                 :             :   /* Reset to normal state.  */
     701                 :     1934656 :   lexer->next_token = lexer->last_token = nullptr;
     702                 :             : }
     703                 :             : 
     704                 :             : /* The parser.  */
     705                 :             : static cp_parser *cp_parser_new (cp_lexer *);
     706                 :             : static 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                 :             : 
     711                 :             : static cp_lexer *
     712                 :       99893 : cp_lexer_new_main (void)
     713                 :             : {
     714                 :       99893 :   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                 :       99893 :   cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, &token);
     720                 :       99855 :   cp_parser_initial_pragma (&token);
     721                 :       99855 :   c_common_no_more_pch ();
     722                 :             : 
     723                 :       99855 :   cp_lexer *lexer = cp_lexer_alloc ();
     724                 :             :   /* Put the first token in the buffer.  */
     725                 :       99855 :   cp_token *tok = lexer->buffer->quick_push (token);
     726                 :             : 
     727                 :       99855 :   uintptr_t filter = 0;
     728                 :       99855 :   if (modules_p ())
     729                 :        3172 :     filter = module_token_cdtor (parse_in, filter);
     730                 :             : 
     731                 :             :   /* Create the parser now, so we can use it to handle early pragmas.  */
     732                 :       99855 :   gcc_assert (!the_parser);
     733                 :       99855 :   the_parser = cp_parser_new (lexer);
     734                 :             : 
     735                 :             :   /* Get the remaining tokens from the preprocessor.  */
     736                 :  7320018858 :   while (tok->type != CPP_EOF)
     737                 :             :     {
     738                 :  7319919005 :       if (filter)
     739                 :             :         /* Process the previous token.  */
     740                 :    36372723 :         module_token_lang (tok->type, tok->keyword, tok->u.value,
     741                 :             :                            tok->location, filter);
     742                 :             : 
     743                 :             :       /* Check for early pragmas that need to be handled now.  */
     744                 :  7319919005 :       if (tok->type == CPP_PRAGMA_EOL)
     745                 :     1938001 :         cp_lexer_handle_early_pragma (lexer);
     746                 :             : 
     747                 :  7319919005 :       tok = vec_safe_push (lexer->buffer, cp_token ());
     748                 :  7319919005 :       cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok);
     749                 :             :     }
     750                 :             : 
     751                 :       99853 :   lexer->next_token = lexer->buffer->address ();
     752                 :       99853 :   lexer->last_token = lexer->next_token
     753                 :       99853 :                       + lexer->buffer->length ()
     754                 :       99853 :                       - 1;
     755                 :             : 
     756                 :       99853 :   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                 :       99069 :       auto range = get_range_from_loc (line_table, tok[-1].location);
     762                 :       99069 :       tok[0].location
     763                 :       99069 :         = linemap_position_for_loc_and_offset (line_table, range.m_finish, 1);
     764                 :             :     }
     765                 :             : 
     766                 :       99853 :   if (filter)
     767                 :        3172 :     module_token_cdtor (parse_in, filter);
     768                 :             : 
     769                 :             :   /* Subsequent preprocessor diagnostics should use compiler
     770                 :             :      diagnostic functions to get the compiler source location.  */
     771                 :       99853 :   override_libcpp_locations = true;
     772                 :             : 
     773                 :       99853 :   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                 :       99853 :   c_reset_target_pragmas ();
     780                 :             : 
     781                 :       99853 :   gcc_assert (!lexer->next_token->purged_p);
     782                 :       99853 :   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 ().  */
     787                 :             : void
     788                 :        1189 : c_init_preprocess ()
     789                 :             : {
     790                 :        1189 :   gcc_assert (!the_parser);
     791                 :        1189 :   the_parser = cp_parser_new (cp_lexer_alloc ());
     792                 :        1189 : }
     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                 :             : 
     797                 :             : static cp_lexer *
     798                 :    70323044 : cp_lexer_new_from_tokens (cp_token_cache *cache)
     799                 :             : {
     800                 :    70323044 :   cp_token *first = cache->first;
     801                 :    70323044 :   cp_token *last = cache->last;
     802                 :    70323044 :   cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> ();
     803                 :             : 
     804                 :             :   /* We do not own the buffer.  */
     805                 :    70323044 :   lexer->buffer = NULL;
     806                 :             : 
     807                 :             :   /* Insert an EOF token.  */
     808                 :    70323044 :   lexer->saved_type = last->type;
     809                 :    70323044 :   lexer->saved_keyword = last->keyword;
     810                 :    70323044 :   last->type = CPP_EOF;
     811                 :    70323044 :   last->keyword = RID_MAX;
     812                 :             : 
     813                 :    70323044 :   lexer->next_token = first;
     814                 :    70323044 :   lexer->last_token = last;
     815                 :             : 
     816                 :    70323044 :   lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);
     817                 :             : 
     818                 :             :   /* Initially we are not debugging.  */
     819                 :    70323044 :   lexer->debugging_p = false;
     820                 :             : 
     821                 :    70323044 :   gcc_assert (!lexer->next_token->purged_p
     822                 :             :               && !lexer->last_token->purged_p);
     823                 :    70323044 :   return lexer;
     824                 :             : }
     825                 :             : 
     826                 :             : /* Frees all resources associated with LEXER.  */
     827                 :             : 
     828                 :             : static void
     829                 :    70424216 : cp_lexer_destroy (cp_lexer *lexer)
     830                 :             : {
     831                 :    70424216 :   if (lexer->buffer)
     832                 :      101172 :     vec_free (lexer->buffer);
     833                 :             :   else
     834                 :             :     {
     835                 :             :       /* Restore the token we overwrite with EOF.  */
     836                 :    70323044 :       lexer->last_token->type = lexer->saved_type;
     837                 :    70323044 :       lexer->last_token->keyword = lexer->saved_keyword;
     838                 :             :     }
     839                 :    70424216 :   lexer->saved_tokens.release ();
     840                 :    70424216 :   ggc_free (lexer);
     841                 :    70424216 : }
     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                 :             : 
     852                 :             : static inline bool
     853                 :             : cp_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                 :             : 
     862                 :             : static inline cp_token_position
     863                 :  1042104086 : cp_lexer_token_position (cp_lexer *lexer, bool previous_p)
     864                 :             : {
     865                 :  1042104086 :   return lexer->next_token - previous_p;
     866                 :             : }
     867                 :             : 
     868                 :             : static inline cp_token *
     869                 :             : cp_lexer_token_at (cp_lexer * /*lexer*/, cp_token_position pos)
     870                 :             : {
     871                 :             :   return pos;
     872                 :             : }
     873                 :             : 
     874                 :             : static inline void
     875                 :     2879260 : cp_lexer_set_token_position (cp_lexer *lexer, cp_token_position pos)
     876                 :             : {
     877                 :     2879260 :   lexer->next_token = cp_lexer_token_at (lexer, pos);
     878                 :     2724231 : }
     879                 :             : 
     880                 :             : static inline cp_token_position
     881                 :  1042090785 : cp_lexer_previous_token_position (cp_lexer *lexer)
     882                 :             : {
     883                 :  1042090785 :   return cp_lexer_token_position (lexer, true);
     884                 :             : }
     885                 :             : 
     886                 :             : static inline cp_token *
     887                 :  1042086823 : cp_lexer_previous_token (cp_lexer *lexer)
     888                 :             : {
     889                 :  1042086823 :   cp_token_position tp = cp_lexer_previous_token_position (lexer);
     890                 :             : 
     891                 :             :   /* Skip past purged tokens.  */
     892                 :  1050207928 :   while (tp->purged_p)
     893                 :             :     {
     894                 :    14999701 :       gcc_assert (tp != vec_safe_address (lexer->buffer));
     895                 :     8121105 :       tp--;
     896                 :             :     }
     897                 :             : 
     898                 :  1042086823 :   return cp_lexer_token_at (lexer, 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                 :             : 
     905                 :             : static cp_token *
     906                 :        4059 : cp_lexer_safe_previous_token (cp_lexer *lexer)
     907                 :             : {
     908                 :        4059 :   if (lexer->buffer
     909                 :        4059 :       && lexer->next_token != lexer->buffer->address ())
     910                 :             :     {
     911                 :        3859 :       cp_token_position tp = cp_lexer_previous_token_position (lexer);
     912                 :             : 
     913                 :             :       /* Skip past purged tokens.  */
     914                 :        4134 :       while (tp->purged_p)
     915                 :             :         {
     916                 :         275 :           if (tp == lexer->buffer->address ())
     917                 :             :             return NULL;
     918                 :         275 :           tp--;
     919                 :             :         }
     920                 :             :       return cp_lexer_token_at (lexer, 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                 :             : 
     929                 :             : static inline location_t
     930                 :   361005219 : make_location (location_t caret, location_t start, cp_lexer *lexer)
     931                 :             : {
     932                 :   361005219 :   cp_token *t = cp_lexer_previous_token (lexer);
     933                 :   361005219 :   return make_location (caret, start, t->location);
     934                 :             : }
     935                 :             : 
     936                 :             : /* Overload for make_location taking tokens instead of locations.  */
     937                 :             : 
     938                 :             : static inline location_t
     939                 :           4 : make_location (cp_token *caret, cp_token *start, cp_token *end)
     940                 :             : {
     941                 :           4 :   return make_location (caret->location, start->location, end->location);
     942                 :             : }
     943                 :             : 
     944                 :             : /* nonzero if we are presently saving tokens.  */
     945                 :             : 
     946                 :             : static inline int
     947                 :   355998894 : cp_lexer_saving_tokens (const cp_lexer* lexer)
     948                 :             : {
     949                 :   711997788 :   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                 :             : 
     960                 :             : static void
     961                 :  7320030811 : cp_lexer_get_preprocessor_token (unsigned flags, cp_token *token)
     962                 :             : {
     963                 :  7320030811 :   static int is_extern_c = 0;
     964                 :             : 
     965                 :             :    /* Get a new token from the preprocessor.  */
     966                 :  7320030811 :   token->type
     967                 :  7320030811 :     = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
     968                 :             :                         flags);
     969                 :  7320030771 :   token->keyword = RID_MAX;
     970                 :  7320030771 :   token->purged_p = false;
     971                 :  7320030771 :   token->error_reported = false;
     972                 :  7320030771 :   token->tree_check_p = false;
     973                 :             :   /* Usually never see a zero, but just in case ... */
     974                 :  7320030771 :   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                 :  7320030771 :   is_extern_c += pending_lang_change;
     980                 :  7320030771 :   pending_lang_change = 0;
     981                 :  7320030771 :   token->implicit_extern_c = is_extern_c > 0;
     982                 :             : 
     983                 :             :   /* Check to see if this token is a keyword.  */
     984                 :  7320030771 :   if (token->type == CPP_NAME)
     985                 :             :     {
     986                 :  3410746942 :       if (IDENTIFIER_KEYWORD_P (token->u.value))
     987                 :             :         {
     988                 :             :           /* Mark this token as a keyword.  */
     989                 :  1199567238 :           token->type = CPP_KEYWORD;
     990                 :             :           /* Record which keyword.  */
     991                 :  1199567238 :           token->keyword = C_RID_CODE (token->u.value);
     992                 :             :         }
     993                 :             :       else
     994                 :             :         {
     995                 :  2211179704 :           if (warn_cxx11_compat
     996                 :     2160025 :               && ((C_RID_CODE (token->u.value) >= RID_FIRST_CXX11
     997                 :     2160025 :                    && C_RID_CODE (token->u.value) <= RID_LAST_CXX11)
     998                 :             :                   /* These are outside the CXX11 range.  */
     999                 :     2160013 :                   || C_RID_CODE (token->u.value) == RID_ALIGNOF
    1000                 :     2160011 :                   || C_RID_CODE (token->u.value) == RID_ALIGNAS
    1001                 :     2160009 :                   || 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                 :          18 :               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                 :          18 :               C_SET_RID_CODE (token->u.value, RID_MAX);
    1012                 :             :             }
    1013                 :  2211179704 :           if (warn_cxx20_compat
    1014                 :    29149097 :               && C_RID_CODE (token->u.value) >= RID_FIRST_CXX20
    1015                 :       27107 :               && 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                 :          51 :               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                 :          51 :               C_SET_RID_CODE (token->u.value, RID_MAX);
    1026                 :             :             }
    1027                 :             : 
    1028                 :  2211179704 :           token->keyword = RID_MAX;
    1029                 :             :         }
    1030                 :             :     }
    1031                 :  3909283829 :   else if (token->type == CPP_AT_NAME)
    1032                 :             :     {
    1033                 :             :       /* This only happens in Objective-C++; it must be a keyword.  */
    1034                 :           0 :       token->type = CPP_KEYWORD;
    1035                 :           0 :       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                 :           0 :         case RID_CLASS:     token->keyword = RID_AT_CLASS; break;
    1046                 :           0 :         case RID_PRIVATE:   token->keyword = RID_AT_PRIVATE; break;
    1047                 :           0 :         case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
    1048                 :           0 :         case RID_PUBLIC:    token->keyword = RID_AT_PUBLIC; break;
    1049                 :           0 :         case RID_THROW:     token->keyword = RID_AT_THROW; break;
    1050                 :           0 :         case RID_TRY:       token->keyword = RID_AT_TRY; break;
    1051                 :           0 :         case RID_CATCH:     token->keyword = RID_AT_CATCH; break;
    1052                 :           0 :         case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
    1053                 :           0 :         default:            token->keyword = C_RID_CODE (token->u.value);
    1054                 :             :         }
    1055                 :             :     }
    1056                 :  7320030771 : }
    1057                 :             : 
    1058                 :             : /* Update the globals input_location and the input file stack from TOKEN.  */
    1059                 :             : static inline void
    1060                 : 12843442542 : cp_lexer_set_source_position_from_token (cp_token *token)
    1061                 :             : {
    1062                 : 12843442542 :   input_location = token->location;
    1063                 :        1683 : }
    1064                 :             : 
    1065                 :             : /* Update the globals input_location and the input file stack from LEXER.  */
    1066                 :             : static inline void
    1067                 :     5972477 : cp_lexer_set_source_position (cp_lexer *lexer)
    1068                 :             : {
    1069                 :     5972477 :   cp_token *token = cp_lexer_peek_token (lexer);
    1070                 :     5972477 :   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                 :             : 
    1076                 :             : static inline cp_token *
    1077                 : 83512139086 : cp_lexer_peek_token (cp_lexer *lexer)
    1078                 :             : {
    1079                 : 83512139086 :   if (cp_lexer_debugging_p (lexer))
    1080                 :             :     {
    1081                 :             :       fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream);
    1082                 :             :       cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token);
    1083                 :             :       putc ('\n', cp_lexer_debug_stream);
    1084                 :             :     }
    1085                 : 83512139724 :   return lexer->next_token;
    1086                 :             : }
    1087                 :             : 
    1088                 :             : /* Return true if the next token has the indicated TYPE.  */
    1089                 :             : 
    1090                 :             : static inline bool
    1091                 : 25241716192 : cp_lexer_next_token_is (cp_lexer* lexer, enum cpp_ttype type)
    1092                 :             : {
    1093                 : 27173736284 :   return cp_lexer_peek_token (lexer)->type == type;
    1094                 :             : }
    1095                 :             : 
    1096                 :             : /* Return true if the next token does not have the indicated TYPE.  */
    1097                 :             : 
    1098                 :             : static inline bool
    1099                 :  5663738526 : cp_lexer_next_token_is_not (cp_lexer* lexer, enum cpp_ttype type)
    1100                 :             : {
    1101                 :  6016456001 :   return !cp_lexer_next_token_is (lexer, type);
    1102                 :             : }
    1103                 :             : 
    1104                 :             : /* Return true if the next token is the indicated KEYWORD.  */
    1105                 :             : 
    1106                 :             : static inline bool
    1107                 :  3266927435 : cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
    1108                 :             : {
    1109                 :  4514564275 :   return cp_lexer_peek_token (lexer)->keyword == keyword;
    1110                 :             : }
    1111                 :             : 
    1112                 :             : static inline bool
    1113                 :  1049056298 : cp_lexer_nth_token_is (cp_lexer* lexer, size_t n, enum cpp_ttype type)
    1114                 :             : {
    1115                 :         311 :   return cp_lexer_peek_nth_token (lexer, n)->type == type;
    1116                 :             : }
    1117                 :             : 
    1118                 :             : static inline bool
    1119                 :   315033404 : cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword)
    1120                 :             : {
    1121                 :   323979005 :   return cp_lexer_peek_nth_token (lexer, n)->keyword == keyword;
    1122                 :             : }
    1123                 :             : 
    1124                 :             : /* Return true if KEYWORD can start a decl-specifier.  */
    1125                 :             : 
    1126                 :             : bool
    1127                 :    17451696 : cp_keyword_starts_decl_specifier_p (enum rid keyword)
    1128                 :             : {
    1129                 :    17451696 :   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                 :    10717458 :     default:
    1183                 :    10717458 :       if (keyword >= RID_FIRST_INT_N
    1184                 :             :           && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
    1185                 :           0 :           && 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                 :             : 
    1195                 :             : static const cp_trait *
    1196                 :  2992581645 : cp_lexer_peek_trait (cp_lexer *lexer)
    1197                 :             : {
    1198                 :  2992581645 :   const cp_token *token1 = cp_lexer_peek_token (lexer);
    1199                 :  2992581645 :   if (token1->type == CPP_NAME && IDENTIFIER_TRAIT_P (token1->u.value))
    1200                 :             :     {
    1201                 :     4604130 :       const cp_trait &trait = cp_traits[IDENTIFIER_CP_INDEX (token1->u.value)];
    1202                 :     4604130 :       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                 :     4604130 :       const cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
    1207                 :     4604130 :       if (is_pack_element && token2->type != CPP_LESS)
    1208                 :             :         return nullptr;
    1209                 :     4591155 :       if (!is_pack_element && token2->type != CPP_OPEN_PAREN)
    1210                 :             :         return nullptr;
    1211                 :             : 
    1212                 :     4604130 :       return &trait;
    1213                 :             :     }
    1214                 :             :   return nullptr;
    1215                 :             : }
    1216                 :             : 
    1217                 :             : /* Similarly, but only if the token is an expression-yielding
    1218                 :             :    built-in trait.  */
    1219                 :             : 
    1220                 :             : static const cp_trait *
    1221                 :   495419904 : cp_lexer_peek_trait_expr (cp_lexer *lexer)
    1222                 :             : {
    1223                 :   495419904 :   const cp_trait *trait = cp_lexer_peek_trait (lexer);
    1224                 :   495419904 :   if (trait && !trait->type)
    1225                 :     1841142 :     return trait;
    1226                 :             : 
    1227                 :             :   return nullptr;
    1228                 :             : }
    1229                 :             : 
    1230                 :             : /* Similarly, but only if the token is a type-yielding
    1231                 :             :    built-in trait.  */
    1232                 :             : 
    1233                 :             : static const cp_trait *
    1234                 :  2497161741 : cp_lexer_peek_trait_type (cp_lexer *lexer)
    1235                 :             : {
    1236                 :  2497161741 :   const cp_trait *trait = cp_lexer_peek_trait (lexer);
    1237                 :  2497161741 :   if (trait && trait->type)
    1238                 :       70326 :     return trait;
    1239                 :             : 
    1240                 :             :   return nullptr;
    1241                 :             : }
    1242                 :             : 
    1243                 :             : /* Return true if the next token is a keyword for a decl-specifier.  */
    1244                 :             : 
    1245                 :             : static bool
    1246                 :    17008938 : cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
    1247                 :             : {
    1248                 :    17008938 :   cp_token *token;
    1249                 :             : 
    1250                 :    17008938 :   if (cp_lexer_peek_trait_type (lexer))
    1251                 :             :     return true;
    1252                 :             : 
    1253                 :    17008938 :   token = cp_lexer_peek_token (lexer);
    1254                 :    17008938 :   return cp_keyword_starts_decl_specifier_p (token->keyword);
    1255                 :             : }
    1256                 :             : 
    1257                 :             : /* Returns TRUE iff the token T begins a decltype type.  */
    1258                 :             : 
    1259                 :             : static bool
    1260                 :  4930796049 : token_is_decltype (cp_token *t)
    1261                 :             : {
    1262                 :  4930796049 :   return (t->keyword == RID_DECLTYPE
    1263                 :  4930706663 :           || t->type == CPP_DECLTYPE);
    1264                 :             : }
    1265                 :             : 
    1266                 :             : /* Returns TRUE iff the next token begins a decltype type.  */
    1267                 :             : 
    1268                 :             : static bool
    1269                 :   411769281 : cp_lexer_next_token_is_decltype (cp_lexer *lexer)
    1270                 :             : {
    1271                 :   411769281 :   cp_token *t = cp_lexer_peek_token (lexer);
    1272                 :           0 :   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                 :             : 
    1278                 :             : static tree
    1279                 :   418316101 : saved_checks_value (struct tree_check *check_value)
    1280                 :             : {
    1281                 :             :   /* Perform any access checks that were deferred.  */
    1282                 :   418316101 :   vec<deferred_access_check, va_gc> *checks;
    1283                 :   418316101 :   deferred_access_check *chk;
    1284                 :   418316101 :   checks = check_value->checks;
    1285                 :   418316101 :   if (checks)
    1286                 :             :     {
    1287                 :             :       int i;
    1288                 :    13038793 :       FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
    1289                 :     7011712 :         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                 :   418316101 :   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                 :             : 
    1303                 :             : static cp_token *
    1304                 : 19020028807 : cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
    1305                 :             : {
    1306                 : 19020028807 :   cp_token *token;
    1307                 :             : 
    1308                 :             :   /* N is 1-based, not zero-based.  */
    1309                 : 19020028807 :   gcc_assert (n > 0);
    1310                 :             : 
    1311                 : 19020028807 :   if (cp_lexer_debugging_p (lexer))
    1312                 :             :     fprintf (cp_lexer_debug_stream,
    1313                 :             :              "cp_lexer: peeking ahead " HOST_SIZE_T_PRINT_DEC " at token: ",
    1314                 :             :              (fmt_size_t) n);
    1315                 :             : 
    1316                 : 19020028807 :   --n;
    1317                 : 19020028807 :   token = lexer->next_token;
    1318                 : 32693017021 :   while (n && token->type != CPP_EOF)
    1319                 :             :     {
    1320                 : 13672988214 :       ++token;
    1321                 : 13672988214 :       if (!token->purged_p)
    1322                 : 12509345721 :         --n;
    1323                 :             :     }
    1324                 :             : 
    1325                 : 19020028807 :   if (cp_lexer_debugging_p (lexer))
    1326                 :             :     {
    1327                 :             :       cp_lexer_print_token (cp_lexer_debug_stream, token);
    1328                 :             :       putc ('\n', cp_lexer_debug_stream);
    1329                 :             :     }
    1330                 :             : 
    1331                 : 19020028807 :   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                 :             : 
    1337                 :             : static cp_token *
    1338                 : 12696498713 : cp_lexer_consume_token (cp_lexer* lexer)
    1339                 :             : {
    1340                 : 12696498713 :   cp_token *token = lexer->next_token;
    1341                 :             : 
    1342                 : 14569454116 :   do
    1343                 :             :     {
    1344                 : 14569454116 :       gcc_assert (token->type != CPP_EOF);
    1345                 : 14569454116 :       lexer->next_token++;
    1346                 :             :     }
    1347                 : 14569454116 :   while (lexer->next_token->purged_p);
    1348                 :             : 
    1349                 : 12696498713 :   cp_lexer_set_source_position_from_token (token);
    1350                 :             : 
    1351                 :             :   /* Provide debugging output.  */
    1352                 : 12696498713 :   if (cp_lexer_debugging_p (lexer))
    1353                 :             :     {
    1354                 :             :       fputs ("cp_lexer: consuming token: ", cp_lexer_debug_stream);
    1355                 :             :       cp_lexer_print_token (cp_lexer_debug_stream, token);
    1356                 :             :       putc ('\n', cp_lexer_debug_stream);
    1357                 :             :     }
    1358                 :             : 
    1359                 : 12696498713 :   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                 :             : 
    1366                 :             : static void
    1367                 :          48 : cp_lexer_purge_token (cp_lexer *lexer)
    1368                 :             : {
    1369                 :          48 :   cp_token *tok = lexer->next_token;
    1370                 :             : 
    1371                 :          48 :   gcc_assert (tok->type != CPP_EOF);
    1372                 :          48 :   tok->purged_p = true;
    1373                 :          48 :   tok->location = UNKNOWN_LOCATION;
    1374                 :          48 :   tok->u.value = NULL_TREE;
    1375                 :          48 :   tok->keyword = RID_MAX;
    1376                 :             : 
    1377                 :          48 :   do
    1378                 :          48 :     tok++;
    1379                 :          48 :   while (tok->purged_p);
    1380                 :          48 :   lexer->next_token = tok;
    1381                 :          48 : }
    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                 :             : 
    1387                 :             : static void
    1388                 :   310251223 : cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
    1389                 :             : {
    1390                 :   310251223 :   cp_token *peek = lexer->next_token;
    1391                 :             : 
    1392                 :   310251223 :   gcc_assert (tok < peek);
    1393                 :             : 
    1394                 :  1622062013 :   for (tok++; tok != peek; tok++)
    1395                 :             :     {
    1396                 :  1311810790 :       tok->purged_p = true;
    1397                 :  1311810790 :       tok->location = UNKNOWN_LOCATION;
    1398                 :  1311810790 :       tok->u.value = NULL_TREE;
    1399                 :  1311810790 :       tok->keyword = RID_MAX;
    1400                 :             :     }
    1401                 :   310251223 : }
    1402                 :             : 
    1403                 :             : /* Begin saving tokens.  All tokens consumed after this point will be
    1404                 :             :    preserved.  */
    1405                 :             : 
    1406                 :             : static void
    1407                 : 13474704685 : cp_lexer_save_tokens (cp_lexer* lexer)
    1408                 :             : {
    1409                 :             :   /* Provide debugging output.  */
    1410                 : 13474704685 :   if (cp_lexer_debugging_p (lexer))
    1411                 :             :     fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n");
    1412                 :             : 
    1413                 :           0 :   lexer->saved_tokens.safe_push (lexer->next_token);
    1414                 :           0 : }
    1415                 :             : 
    1416                 :             : /* Commit to the portion of the token stream most recently saved.  */
    1417                 :             : 
    1418                 :             : static void
    1419                 :  3797624281 : cp_lexer_commit_tokens (cp_lexer* lexer)
    1420                 :             : {
    1421                 :             :   /* Provide debugging output.  */
    1422                 :  3797624281 :   if (cp_lexer_debugging_p (lexer))
    1423                 :             :     fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n");
    1424                 :             : 
    1425                 :           0 :   lexer->saved_tokens.pop ();
    1426                 :  3638678547 : }
    1427                 :             : 
    1428                 :             : /* Return all tokens saved since the last call to cp_lexer_save_tokens
    1429                 :             :    to the token stream.  Stop saving tokens.  */
    1430                 :             : 
    1431                 :             : static void
    1432                 :  9677080359 : cp_lexer_rollback_tokens (cp_lexer* lexer)
    1433                 :             : {
    1434                 :             :   /* Provide debugging output.  */
    1435                 :  9677080359 :   if (cp_lexer_debugging_p (lexer))
    1436                 :             :     fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n");
    1437                 :             : 
    1438                 :           0 :   lexer->next_token = lexer->saved_tokens.pop ();
    1439                 :           6 : }
    1440                 :             : 
    1441                 :             : /* Determines what saved_token_sentinel does when going out of scope.  */
    1442                 :             : 
    1443                 :             : enum 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                 :             : 
    1459                 :             : struct saved_token_sentinel
    1460                 :             : {
    1461                 :             :   cp_lexer *lexer;
    1462                 :             :   unsigned len;
    1463                 :             :   saved_token_sentinel_mode mode;
    1464                 :   276706392 :   saved_token_sentinel (cp_lexer *_lexer,
    1465                 :             :                         saved_token_sentinel_mode _mode = STS_COMMIT)
    1466                 :   276706392 :     : lexer (_lexer), mode (_mode)
    1467                 :             :   {
    1468                 :   276706392 :     len = lexer->saved_tokens.length ();
    1469                 :   276706392 :     cp_lexer_save_tokens (lexer);
    1470                 :   276706392 :   }
    1471                 :      314476 :   void rollback ()
    1472                 :             :   {
    1473                 :      314476 :     cp_lexer_rollback_tokens (lexer);
    1474                 :      314476 :     cp_lexer_set_source_position_from_token
    1475                 :      314476 :       (cp_lexer_previous_token (lexer));
    1476                 :      314476 :     mode = STS_DONOTHING;
    1477                 :      314476 :   }
    1478                 :   276706367 :   ~saved_token_sentinel ()
    1479                 :             :   {
    1480                 :   276706367 :     if (mode == STS_COMMIT)
    1481                 :   276391879 :       cp_lexer_commit_tokens (lexer);
    1482                 :      314488 :     else if (mode == STS_ROLLBACK)
    1483                 :      107863 :       rollback ();
    1484                 :             : 
    1485                 :   553412734 :     gcc_assert (lexer->saved_tokens.length () == len);
    1486                 :   276706367 :   }
    1487                 :             : };
    1488                 :             : 
    1489                 :             : /* Print a representation of the TOKEN on the STREAM.  */
    1490                 :             : 
    1491                 :             : static void
    1492                 :           0 : cp_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                 :           0 :   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                 :           0 :   switch (token->type)
    1511                 :             :     {
    1512                 :           0 :     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                 :           0 :       if (!identifier_p (token->u.value))
    1516                 :             :         break;
    1517                 :             :       /* fall through */
    1518                 :           0 :     case CPP_NAME:
    1519                 :           0 :       fputs (IDENTIFIER_POINTER (token->u.value), stream);
    1520                 :           0 :       break;
    1521                 :             : 
    1522                 :           0 :     case CPP_STRING:
    1523                 :           0 :     case CPP_STRING16:
    1524                 :           0 :     case CPP_STRING32:
    1525                 :           0 :     case CPP_WSTRING:
    1526                 :           0 :     case CPP_UTF8STRING:
    1527                 :           0 :       fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
    1528                 :           0 :       break;
    1529                 :             : 
    1530                 :           0 :     case CPP_NUMBER:
    1531                 :           0 :       print_generic_expr (stream, token->u.value);
    1532                 :           0 :       break;
    1533                 :             : 
    1534                 :           0 :     default:
    1535                 :             :       /* If we have a name for the token, print it out.  Otherwise, we
    1536                 :             :          simply give the numeric code.  */
    1537                 :           0 :       if (token->type < ARRAY_SIZE(token_names))
    1538                 :           0 :         fputs (token_names[token->type], stream);
    1539                 :             :       else
    1540                 :           0 :         fprintf (stream, "[%d]", token->type);
    1541                 :             :       break;
    1542                 :             :     }
    1543                 :           0 : }
    1544                 :             : 
    1545                 :             : DEBUG_FUNCTION void
    1546                 :           0 : debug (cp_token &ref)
    1547                 :             : {
    1548                 :           0 :   cp_lexer_print_token (stderr, &ref);
    1549                 :           0 :   fprintf (stderr, "\n");
    1550                 :           0 : }
    1551                 :             : 
    1552                 :             : DEBUG_FUNCTION void
    1553                 :           0 : debug (cp_token *ptr)
    1554                 :             : {
    1555                 :           0 :   if (ptr)
    1556                 :           0 :     debug (*ptr);
    1557                 :             :   else
    1558                 :           0 :     fprintf (stderr, "<nil>\n");
    1559                 :           0 : }
    1560                 :             : 
    1561                 :             : 
    1562                 :             : /* Start emitting debugging information.  */
    1563                 :             : 
    1564                 :             : static void
    1565                 :           0 : cp_lexer_start_debugging (cp_lexer* lexer)
    1566                 :             : {
    1567                 :           0 :   if (!LEXER_DEBUGGING_ENABLED_P)
    1568                 :           0 :     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                 :             : 
    1577                 :             : static void
    1578                 :           0 : cp_lexer_stop_debugging (cp_lexer* lexer)
    1579                 :             : {
    1580                 :           0 :   if (!LEXER_DEBUGGING_ENABLED_P)
    1581                 :           0 :     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                 :             : 
    1590                 :             : static cp_token_cache *
    1591                 :    70325725 : cp_token_cache_new (cp_token *first, cp_token *last)
    1592                 :             : {
    1593                 :           0 :   cp_token_cache *cache = ggc_alloc<cp_token_cache> ();
    1594                 :    70325725 :   cache->first = first;
    1595                 :    70325725 :   cache->last = last;
    1596                 :    70325725 :   return cache;
    1597                 :             : }
    1598                 :             : 
    1599                 :             : /* Diagnose if #pragma omp declare simd isn't followed immediately
    1600                 :             :    by function declaration or definition.  */
    1601                 :             : 
    1602                 :             : static inline void
    1603                 :    30975390 : cp_ensure_no_omp_declare_simd (cp_parser *parser)
    1604                 :             : {
    1605                 :    30975390 :   if (parser->omp_declare_simd && !parser->omp_declare_simd->error_seen)
    1606                 :             :     {
    1607                 :         102 :       error ("%<#pragma omp declare %s%> not immediately followed by "
    1608                 :             :              "function declaration or definition",
    1609                 :         102 :              parser->omp_declare_simd->variant_p ? "variant" : "simd");
    1610                 :         102 :       parser->omp_declare_simd = NULL;
    1611                 :             :     }
    1612                 :    30975390 : }
    1613                 :             : 
    1614                 :             : /* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
    1615                 :             :    and put that into "omp declare simd" attribute.  */
    1616                 :             : 
    1617                 :             : static inline void
    1618                 :   255414868 : cp_finalize_omp_declare_simd (cp_parser *parser, tree fndecl)
    1619                 :             : {
    1620                 :   255414868 :   if (UNLIKELY (parser->omp_declare_simd != NULL))
    1621                 :             :     {
    1622                 :        2397 :       if (fndecl == error_mark_node)
    1623                 :             :         {
    1624                 :           0 :           parser->omp_declare_simd = NULL;
    1625                 :           0 :           return;
    1626                 :             :         }
    1627                 :        2397 :       if (TREE_CODE (fndecl) != FUNCTION_DECL)
    1628                 :             :         {
    1629                 :          42 :           cp_ensure_no_omp_declare_simd (parser);
    1630                 :          42 :           return;
    1631                 :             :         }
    1632                 :             :     }
    1633                 :             : }
    1634                 :             : 
    1635                 :             : /* Similarly, but for use in declaration parsing functions
    1636                 :             :    which call cp_parser_handle_directive_omp_attributes.  */
    1637                 :             : 
    1638                 :             : static inline void
    1639                 :   531414889 : cp_finalize_omp_declare_simd (cp_parser *parser, cp_omp_declare_simd_data *data)
    1640                 :             : {
    1641                 :   531414889 :   if (parser->omp_declare_simd != data)
    1642                 :             :     return;
    1643                 :             : 
    1644                 :         177 :   if (!parser->omp_declare_simd->error_seen
    1645                 :         177 :       && !parser->omp_declare_simd->fndecl_seen)
    1646                 :           3 :     error_at (parser->omp_declare_simd->loc,
    1647                 :             :               "%<declare %s%> directive not immediately followed by "
    1648                 :             :               "function declaration or definition",
    1649                 :           3 :               parser->omp_declare_simd->variant_p ? "variant" : "simd");
    1650                 :         177 :   parser->omp_declare_simd = NULL;
    1651                 :             : }
    1652                 :             : 
    1653                 :             : /* Diagnose if #pragma acc routine isn't followed immediately by function
    1654                 :             :    declaration or definition.  */
    1655                 :             : 
    1656                 :             : static inline void
    1657                 :    29044118 : cp_ensure_no_oacc_routine (cp_parser *parser)
    1658                 :             : {
    1659                 :    29044118 :   if (parser->oacc_routine && !parser->oacc_routine->error_seen)
    1660                 :             :     {
    1661                 :          88 :       error_at (parser->oacc_routine->loc,
    1662                 :             :                 "%<#pragma acc routine%> not immediately followed by "
    1663                 :             :                 "function declaration or definition");
    1664                 :          88 :       parser->oacc_routine = NULL;
    1665                 :             :     }
    1666                 :    29044118 : }
    1667                 :             : 
    1668                 :             : /* Decl-specifiers.  */
    1669                 :             : 
    1670                 :             : /* Set *DECL_SPECS to represent an empty decl-specifier-seq.  */
    1671                 :             : 
    1672                 :             : static void
    1673                 :  1054573274 : clear_decl_specs (cp_decl_specifier_seq *decl_specs)
    1674                 :             : {
    1675                 :  1054573274 :   memset (decl_specs, 0, sizeof (cp_decl_specifier_seq));
    1676                 :       99853 : }
    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                 :             : 
    1685                 :             : static 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);
    1688                 :             : static cp_declarator *make_array_declarator
    1689                 :             :   (cp_declarator *, tree);
    1690                 :             : static cp_declarator *make_pointer_declarator
    1691                 :             :   (cp_cv_quals, cp_declarator *, tree);
    1692                 :             : static cp_declarator *make_reference_declarator
    1693                 :             :   (cp_cv_quals, cp_declarator *, bool, tree);
    1694                 :             : static cp_declarator *make_ptrmem_declarator
    1695                 :             :   (cp_cv_quals, tree, cp_declarator *, tree);
    1696                 :             : 
    1697                 :             : /* An erroneous declarator.  */
    1698                 :             : static cp_declarator *cp_error_declarator;
    1699                 :             : 
    1700                 :             : /* The obstack on which declarators and related data structures are
    1701                 :             :    allocated.  */
    1702                 :             : static struct obstack declarator_obstack;
    1703                 :             : 
    1704                 :             : /* Alloc BYTES from the declarator memory pool.  */
    1705                 :             : 
    1706                 :             : static inline void *
    1707                 :  1078311011 : alloc_declarator (size_t bytes)
    1708                 :             : {
    1709                 :  1078311011 :   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                 :             : 
    1715                 :             : static cp_declarator *
    1716                 :   820415516 : make_declarator (cp_declarator_kind kind)
    1717                 :             : {
    1718                 :   820415516 :   cp_declarator *declarator;
    1719                 :             : 
    1720                 :   820415516 :   declarator = (cp_declarator *) alloc_declarator (sizeof (cp_declarator));
    1721                 :   820415516 :   declarator->kind = kind;
    1722                 :   820415516 :   declarator->parenthesized = UNKNOWN_LOCATION;
    1723                 :   820415516 :   declarator->attributes = NULL_TREE;
    1724                 :   820415516 :   declarator->std_attributes = NULL_TREE;
    1725                 :   820415516 :   declarator->declarator = NULL;
    1726                 :   820415516 :   declarator->parameter_pack_p = false;
    1727                 :   820415516 :   declarator->id_loc = UNKNOWN_LOCATION;
    1728                 :   820415516 :   declarator->init_loc = UNKNOWN_LOCATION;
    1729                 :             : 
    1730                 :   820415516 :   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                 :             : 
    1739                 :             : static cp_declarator *
    1740                 :   490293608 : make_id_declarator (tree qualifying_scope, tree unqualified_name,
    1741                 :             :                     special_function_kind sfk, location_t id_location)
    1742                 :             : {
    1743                 :   490293608 :   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                 :   490293608 :   if (qualifying_scope && TYPE_P (qualifying_scope))
    1756                 :     9002440 :     qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
    1757                 :             : 
    1758                 :   490293608 :   gcc_assert (identifier_p (unqualified_name)
    1759                 :             :               || TREE_CODE (unqualified_name) == BIT_NOT_EXPR
    1760                 :             :               || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR);
    1761                 :             : 
    1762                 :   490293608 :   declarator = make_declarator (cdk_id);
    1763                 :   490293608 :   declarator->u.id.qualifying_scope = qualifying_scope;
    1764                 :   490293608 :   declarator->u.id.unqualified_name = unqualified_name;
    1765                 :   490293608 :   declarator->u.id.sfk = sfk;
    1766                 :   490293608 :   declarator->id_loc = id_location;
    1767                 :             : 
    1768                 :   490293608 :   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                 :             : 
    1776                 :             : cp_declarator *
    1777                 :    57609444 : make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
    1778                 :             :                          tree attributes)
    1779                 :             : {
    1780                 :    57609444 :   cp_declarator *declarator;
    1781                 :             : 
    1782                 :    57609444 :   declarator = make_declarator (cdk_pointer);
    1783                 :    57609444 :   declarator->declarator = target;
    1784                 :    57609444 :   declarator->u.pointer.qualifiers = cv_qualifiers;
    1785                 :    57609444 :   declarator->u.pointer.class_type = NULL_TREE;
    1786                 :    57609444 :   if (target)
    1787                 :             :     {
    1788                 :    48919024 :       declarator->id_loc = target->id_loc;
    1789                 :    48919024 :       declarator->parameter_pack_p = target->parameter_pack_p;
    1790                 :    48919024 :       target->parameter_pack_p = false;
    1791                 :             :     }
    1792                 :             :   else
    1793                 :     8690420 :     declarator->parameter_pack_p = false;
    1794                 :             : 
    1795                 :    57609444 :   declarator->std_attributes = attributes;
    1796                 :             : 
    1797                 :    57609444 :   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                 :             : 
    1804                 :             : cp_declarator *
    1805                 :   107838211 : make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
    1806                 :             :                            bool rvalue_ref, tree attributes)
    1807                 :             : {
    1808                 :   107838211 :   cp_declarator *declarator;
    1809                 :             : 
    1810                 :   107838211 :   declarator = make_declarator (cdk_reference);
    1811                 :   107838211 :   declarator->declarator = target;
    1812                 :   107838211 :   declarator->u.reference.qualifiers = cv_qualifiers;
    1813                 :   107838211 :   declarator->u.reference.rvalue_ref = rvalue_ref;
    1814                 :   107838211 :   if (target)
    1815                 :             :     {
    1816                 :    84558982 :       declarator->id_loc = target->id_loc;
    1817                 :    84558982 :       declarator->parameter_pack_p = target->parameter_pack_p;
    1818                 :    84558982 :       target->parameter_pack_p = false;
    1819                 :             :     }
    1820                 :             :   else
    1821                 :    23279229 :     declarator->parameter_pack_p = false;
    1822                 :             : 
    1823                 :   107838211 :   declarator->std_attributes = attributes;
    1824                 :             : 
    1825                 :   107838211 :   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                 :             : 
    1832                 :             : cp_declarator *
    1833                 :     1111598 : make_ptrmem_declarator (cp_cv_quals cv_qualifiers, tree class_type,
    1834                 :             :                         cp_declarator *pointee,
    1835                 :             :                         tree attributes)
    1836                 :             : {
    1837                 :     1111598 :   cp_declarator *declarator;
    1838                 :             : 
    1839                 :     1111598 :   declarator = make_declarator (cdk_ptrmem);
    1840                 :     1111598 :   declarator->declarator = pointee;
    1841                 :     1111598 :   declarator->u.pointer.qualifiers = cv_qualifiers;
    1842                 :     1111598 :   declarator->u.pointer.class_type = class_type;
    1843                 :             : 
    1844                 :     1111598 :   if (pointee)
    1845                 :             :     {
    1846                 :      357303 :       declarator->parameter_pack_p = pointee->parameter_pack_p;
    1847                 :      357303 :       pointee->parameter_pack_p = false;
    1848                 :             :     }
    1849                 :             :   else
    1850                 :      754295 :     declarator->parameter_pack_p = false;
    1851                 :             : 
    1852                 :     1111598 :   declarator->std_attributes = attributes;
    1853                 :             : 
    1854                 :     1111598 :   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                 :             : 
    1863                 :             : cp_declarator *
    1864                 :   160194925 : make_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                 :   160194925 :   cp_declarator *declarator;
    1877                 :             : 
    1878                 :   160194925 :   declarator = make_declarator (cdk_function);
    1879                 :   160194925 :   declarator->declarator = target;
    1880                 :   160194925 :   declarator->u.function.parameters = parms;
    1881                 :   160194925 :   declarator->u.function.qualifiers = cv_qualifiers;
    1882                 :   160194925 :   declarator->u.function.virt_specifiers = virt_specifiers;
    1883                 :   160194925 :   declarator->u.function.ref_qualifier = ref_qualifier;
    1884                 :   160194925 :   declarator->u.function.tx_qualifier = tx_qualifier;
    1885                 :   160194925 :   declarator->u.function.exception_specification = exception_specification;
    1886                 :   160194925 :   declarator->u.function.late_return_type = late_return_type;
    1887                 :   160194925 :   declarator->u.function.requires_clause = requires_clause;
    1888                 :   160194925 :   declarator->u.function.parens_loc = parens_loc;
    1889                 :   160194925 :   if (target)
    1890                 :             :     {
    1891                 :   159722112 :       declarator->id_loc = target->id_loc;
    1892                 :   159722112 :       declarator->parameter_pack_p = target->parameter_pack_p;
    1893                 :   159722112 :       target->parameter_pack_p = false;
    1894                 :             :     }
    1895                 :             :   else
    1896                 :      472813 :     declarator->parameter_pack_p = false;
    1897                 :             : 
    1898                 :   160194925 :   declarator->std_attributes = std_attrs;
    1899                 :             : 
    1900                 :   160194925 :   return declarator;
    1901                 :             : }
    1902                 :             : 
    1903                 :             : /* Make a declarator for an array of BOUNDS elements, each of which is
    1904                 :             :    defined by ELEMENT.  */
    1905                 :             : 
    1906                 :             : cp_declarator *
    1907                 :     3212091 : make_array_declarator (cp_declarator *element, tree bounds)
    1908                 :             : {
    1909                 :     3212091 :   cp_declarator *declarator;
    1910                 :             : 
    1911                 :     3212091 :   declarator = make_declarator (cdk_array);
    1912                 :     3212091 :   declarator->declarator = element;
    1913                 :     3212091 :   declarator->u.array.bounds = bounds;
    1914                 :     3212091 :   if (element)
    1915                 :             :     {
    1916                 :     2627993 :       declarator->id_loc = element->id_loc;
    1917                 :     2627993 :       declarator->parameter_pack_p = element->parameter_pack_p;
    1918                 :     2627993 :       element->parameter_pack_p = false;
    1919                 :             :     }
    1920                 :             :   else
    1921                 :      584098 :     declarator->parameter_pack_p = false;
    1922                 :             : 
    1923                 :     3212091 :   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.  */
    1928                 :             : static bool
    1929                 :     1351796 : declarator_can_be_parameter_pack (cp_declarator *declarator)
    1930                 :             : {
    1931                 :     1351796 :   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                 :     1483003 :   while (declarator && !found)
    1941                 :             :     {
    1942                 :      131207 :       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                 :      131204 :         default:
    1954                 :      131204 :           declarator = declarator->declarator;
    1955                 :      131204 :           break;
    1956                 :             :         }
    1957                 :             :     }
    1958                 :             : 
    1959                 :             :   return !found;
    1960                 :             : }
    1961                 :             : 
    1962                 :             : cp_parameter_declarator *no_parameters;
    1963                 :             : 
    1964                 :             : /* Create a parameter declarator with the indicated DECL_SPECIFIERS,
    1965                 :             :    DECLARATOR and DEFAULT_ARGUMENT.  */
    1966                 :             : 
    1967                 :             : cp_parameter_declarator *
    1968                 :   257895495 : make_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                 :   257895495 :   cp_parameter_declarator *parameter;
    1975                 :             : 
    1976                 :   257895495 :   parameter = ((cp_parameter_declarator *)
    1977                 :   257895495 :                alloc_declarator (sizeof (cp_parameter_declarator)));
    1978                 :   257895495 :   parameter->next = NULL;
    1979                 :   257895495 :   if (decl_specifiers)
    1980                 :   257795642 :     parameter->decl_specifiers = *decl_specifiers;
    1981                 :             :   else
    1982                 :       99853 :     clear_decl_specs (&parameter->decl_specifiers);
    1983                 :   257895495 :   parameter->declarator = declarator;
    1984                 :   257895495 :   parameter->default_argument = default_argument;
    1985                 :   257895495 :   parameter->template_parameter_pack_p = template_parameter_pack_p;
    1986                 :   257895495 :   parameter->loc = loc;
    1987                 :             : 
    1988                 :   257895495 :   return parameter;
    1989                 :             : }
    1990                 :             : 
    1991                 :             : /* Returns true iff DECLARATOR  is a declaration for a function.  */
    1992                 :             : 
    1993                 :             : static bool
    1994                 :   393059223 : function_declarator_p (const cp_declarator *declarator)
    1995                 :             : {
    1996                 :   442740705 :   while (declarator)
    1997                 :             :     {
    1998                 :   442740705 :       if (declarator->kind == cdk_function
    1999                 :   175262365 :           && declarator->declarator->kind == cdk_id)
    2000                 :             :         return true;
    2001                 :   267702855 :       if (declarator->kind == cdk_id
    2002                 :    49681482 :           || declarator->kind == cdk_decomp
    2003                 :    49681482 :           || declarator->kind == cdk_error)
    2004                 :             :         return false;
    2005                 :    49681482 :       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                 :             : 
    2068                 :             : enum
    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.  */
    2099                 :             : typedef int cp_parser_flags;
    2100                 :             : 
    2101                 :             : /* The different kinds of declarators we want to parse.  */
    2102                 :             : 
    2103                 :             : enum 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                 :             : 
    2117                 :             : enum 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                 :             : 
    2138                 :             : struct 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                 :             : 
    2148                 :  8745552816 : struct 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.  */
    2169                 :             : typedef 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                 :             :   */
    2193                 :             : struct 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                 :             : 
    2222                 :             : static cp_parser_context *cp_parser_context_new
    2223                 :             :   (cp_parser_context *);
    2224                 :             : 
    2225                 :             : /* Class variables.  */
    2226                 :             : 
    2227                 :             : static 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                 :             : 
    2233                 :             : static const cp_parser_binary_operations_map_node binops[] = {
    2234                 :             :   { CPP_DEREF_STAR, MEMBER_REF, PREC_PM_EXPRESSION },
    2235                 :             :   { CPP_DOT_STAR, DOTSTAR_EXPR, PREC_PM_EXPRESSION },
    2236                 :             : 
    2237                 :             :   { CPP_MULT, MULT_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
    2238                 :             :   { CPP_DIV, TRUNC_DIV_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
    2239                 :             :   { CPP_MOD, TRUNC_MOD_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
    2240                 :             : 
    2241                 :             :   { CPP_PLUS, PLUS_EXPR, PREC_ADDITIVE_EXPRESSION },
    2242                 :             :   { CPP_MINUS, MINUS_EXPR, PREC_ADDITIVE_EXPRESSION },
    2243                 :             : 
    2244                 :             :   { CPP_LSHIFT, LSHIFT_EXPR, PREC_SHIFT_EXPRESSION },
    2245                 :             :   { CPP_RSHIFT, RSHIFT_EXPR, PREC_SHIFT_EXPRESSION },
    2246                 :             : 
    2247                 :             :   { CPP_SPACESHIP, SPACESHIP_EXPR, PREC_SPACESHIP_EXPRESSION },
    2248                 :             : 
    2249                 :             :   { CPP_LESS, LT_EXPR, PREC_RELATIONAL_EXPRESSION },
    2250                 :             :   { CPP_GREATER, GT_EXPR, PREC_RELATIONAL_EXPRESSION },
    2251                 :             :   { CPP_LESS_EQ, LE_EXPR, PREC_RELATIONAL_EXPRESSION },
    2252                 :             :   { CPP_GREATER_EQ, GE_EXPR, PREC_RELATIONAL_EXPRESSION },
    2253                 :             : 
    2254                 :             :   { CPP_EQ_EQ, EQ_EXPR, PREC_EQUALITY_EXPRESSION },
    2255                 :             :   { CPP_NOT_EQ, NE_EXPR, PREC_EQUALITY_EXPRESSION },
    2256                 :             : 
    2257                 :             :   { CPP_AND, BIT_AND_EXPR, PREC_AND_EXPRESSION },
    2258                 :             : 
    2259                 :             :   { CPP_XOR, BIT_XOR_EXPR, PREC_EXCLUSIVE_OR_EXPRESSION },
    2260                 :             : 
    2261                 :             :   { CPP_OR, BIT_IOR_EXPR, PREC_INCLUSIVE_OR_EXPRESSION },
    2262                 :             : 
    2263                 :             :   { CPP_AND_AND, TRUTH_ANDIF_EXPR, PREC_LOGICAL_AND_EXPRESSION },
    2264                 :             : 
    2265                 :             :   { CPP_OR_OR, TRUTH_ORIF_EXPR, 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.  */
    2271                 :             : static 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                 :             : 
    2278                 :             : static cp_parser_context *
    2279                 : 13090246693 : cp_parser_context_new (cp_parser_context* next)
    2280                 :             : {
    2281                 : 13090246693 :   cp_parser_context *context;
    2282                 :             : 
    2283                 :             :   /* Allocate the storage.  */
    2284                 : 13090246693 :   if (cp_parser_context_free_list != NULL)
    2285                 :             :     {
    2286                 :             :       /* Pull the first entry from the free list.  */
    2287                 : 13086992906 :       context = cp_parser_context_free_list;
    2288                 : 13086992906 :       cp_parser_context_free_list = context->next;
    2289                 : 13086992906 :       memset (context, 0, sizeof (*context));
    2290                 :             :     }
    2291                 :             :   else
    2292                 :     3253787 :     context = ggc_cleared_alloc<cp_parser_context> ();
    2293                 :             : 
    2294                 :             :   /* No errors have occurred yet in this context.  */
    2295                 : 13090246693 :   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                 : 13090246693 :   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                 : 13090145649 :       context->object_type = next->object_type;
    2303                 :             :       /* Thread the stack.  */
    2304                 : 13090145649 :       context->next = next;
    2305                 :             :     }
    2306                 :             : 
    2307                 : 13090246693 :   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                 :             : 
    2323                 :             : static void
    2324                 :    86127206 : push_unparsed_function_queues (cp_parser *parser)
    2325                 :             : {
    2326                 :    86127206 :   cp_unparsed_functions_entry e
    2327                 :    86127206 :       = { NULL, make_tree_vector (), NULL, NULL, NULL };
    2328                 :    86127206 :   vec_safe_push (parser->unparsed_queues, e);
    2329                 :    86127206 : }
    2330                 :             : 
    2331                 :             : static void
    2332                 :    86026162 : pop_unparsed_function_queues (cp_parser *parser)
    2333                 :             : {
    2334                 :    86026162 :   release_tree_vector (unparsed_funs_with_definitions);
    2335                 :    86026162 :   parser->unparsed_queues->pop ();
    2336                 :    86026162 : }
    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                 :             : 
    2354                 :             : static tree finish_userdef_string_literal
    2355                 :             :   (tree);
    2356                 :             : 
    2357                 :             : /* Basic concepts [gram.basic]  */
    2358                 :             : 
    2359                 :             : static void cp_parser_translation_unit (cp_parser *);
    2360                 :             : 
    2361                 :             : /* Expressions [gram.expr]  */
    2362                 :             : 
    2363                 :             : static cp_expr cp_parser_primary_expression
    2364                 :             :   (cp_parser *, bool, bool, bool, cp_id_kind *);
    2365                 :             : static cp_expr cp_parser_id_expression
    2366                 :             :   (cp_parser *, bool, bool, bool *, bool, bool);
    2367                 :             : static cp_expr cp_parser_unqualified_id
    2368                 :             :   (cp_parser *, bool, bool, bool, bool);
    2369                 :             : static tree cp_parser_nested_name_specifier_opt
    2370                 :             :   (cp_parser *, bool, bool, bool, bool, bool = false);
    2371                 :             : static tree cp_parser_nested_name_specifier
    2372                 :             :   (cp_parser *, bool, bool, bool, bool);
    2373                 :             : static tree cp_parser_qualifying_entity
    2374                 :             :   (cp_parser *, bool, bool, bool, bool, bool);
    2375                 :             : static cp_expr cp_parser_postfix_expression
    2376                 :             :   (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
    2377                 :             : static tree cp_parser_postfix_open_square_expression
    2378                 :             :   (cp_parser *, tree, bool, bool);
    2379                 :             : static tree cp_parser_postfix_dot_deref_expression
    2380                 :             :   (cp_parser *, enum cpp_ttype, cp_expr, bool, cp_id_kind *, location_t);
    2381                 :             : static 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.  */
    2385                 :             : enum { non_attr = 0, normal_attr = 1, id_attr = 2, assume_attr = 3,
    2386                 :             :        uneval_string_attr = 4 };
    2387                 :             : static void cp_parser_pseudo_destructor_name
    2388                 :             :   (cp_parser *, tree, tree *, tree *);
    2389                 :             : static cp_expr cp_parser_unary_expression
    2390                 :             :   (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
    2391                 :             : static enum tree_code cp_parser_unary_operator
    2392                 :             :   (cp_token *);
    2393                 :             : static tree cp_parser_has_attribute_expression
    2394                 :             :   (cp_parser *);
    2395                 :             : static tree cp_parser_new_expression
    2396                 :             :   (cp_parser *);
    2397                 :             : static vec<tree, va_gc> *cp_parser_new_placement
    2398                 :             :   (cp_parser *);
    2399                 :             : static tree cp_parser_new_type_id
    2400                 :             :   (cp_parser *, tree *);
    2401                 :             : static cp_declarator *cp_parser_new_declarator_opt
    2402                 :             :   (cp_parser *);
    2403                 :             : static cp_declarator *cp_parser_direct_new_declarator
    2404                 :             :   (cp_parser *);
    2405                 :             : static vec<tree, va_gc> *cp_parser_new_initializer
    2406                 :             :   (cp_parser *);
    2407                 :             : static tree cp_parser_delete_expression
    2408                 :             :   (cp_parser *);
    2409                 :             : static cp_expr cp_parser_cast_expression
    2410                 :             :   (cp_parser *, bool, bool, bool, cp_id_kind *);
    2411                 :             : static cp_expr cp_parser_binary_expression
    2412                 :             :   (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
    2413                 :             : static tree cp_parser_question_colon_clause
    2414                 :             :   (cp_parser *, cp_expr);
    2415                 :             : static cp_expr cp_parser_conditional_expression (cp_parser *);
    2416                 :             : static cp_expr cp_parser_assignment_expression
    2417                 :             :   (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
    2418                 :             : static enum tree_code cp_parser_assignment_operator_opt
    2419                 :             :   (cp_parser *);
    2420                 :             : static cp_expr cp_parser_expression
    2421                 :             :   (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
    2422                 :             : static cp_expr cp_parser_constant_expression
    2423                 :             :   (cp_parser *, int = 0, bool * = NULL, bool = false);
    2424                 :             : static cp_expr cp_parser_builtin_offsetof
    2425                 :             :   (cp_parser *);
    2426                 :             : static cp_expr cp_parser_lambda_expression
    2427                 :             :   (cp_parser *);
    2428                 :             : static void cp_parser_lambda_introducer
    2429                 :             :   (cp_parser *, tree);
    2430                 :             : static bool cp_parser_lambda_declarator_opt
    2431                 :             :   (cp_parser *, tree);
    2432                 :             : static void cp_parser_lambda_body
    2433                 :             :   (cp_parser *, tree);
    2434                 :             : 
    2435                 :             : /* Statements [gram.stmt.stmt]  */
    2436                 :             : 
    2437                 :             : static void cp_parser_statement
    2438                 :             :   (cp_parser *, tree, bool, bool *, vec<tree> * = NULL, location_t * = NULL);
    2439                 :             : static void cp_parser_label_for_labeled_statement
    2440                 :             : (cp_parser *, tree);
    2441                 :             : static tree cp_parser_expression_statement
    2442                 :             :   (cp_parser *, tree);
    2443                 :             : static tree cp_parser_compound_statement
    2444                 :             :   (cp_parser *, tree, int, bool);
    2445                 :             : static void cp_parser_statement_seq_opt
    2446                 :             :   (cp_parser *, tree);
    2447                 :             : static tree cp_parser_selection_statement
    2448                 :             :   (cp_parser *, bool *, vec<tree> *);
    2449                 :             : static tree cp_parser_condition
    2450                 :             :   (cp_parser *);
    2451                 :             : static tree cp_parser_iteration_statement
    2452                 :             :   (cp_parser *, bool *, bool, tree, bool);
    2453                 :             : static bool cp_parser_init_statement
    2454                 :             :   (cp_parser *, tree *decl);
    2455                 :             : static tree cp_parser_for
    2456                 :             :   (cp_parser *, bool, tree, bool);
    2457                 :             : static tree cp_parser_c_for
    2458                 :             :   (cp_parser *, tree, tree, bool, tree, bool);
    2459                 :             : static tree cp_parser_range_for
    2460                 :             :   (cp_parser *, tree, tree, tree, bool, tree, bool, bool);
    2461                 :             : static void do_range_for_auto_deduction
    2462                 :             :   (tree, tree, cp_decomp *);
    2463                 :             : static tree cp_parser_perform_range_for_lookup
    2464                 :             :   (tree, tree *, tree *);
    2465                 :             : static tree cp_parser_range_for_member_function
    2466                 :             :   (tree, tree);
    2467                 :             : static tree cp_parser_jump_statement
    2468                 :             :   (cp_parser *);
    2469                 :             : static void cp_parser_declaration_statement
    2470                 :             :   (cp_parser *);
    2471                 :             : 
    2472                 :             : static tree cp_parser_implicitly_scoped_statement
    2473                 :             :   (cp_parser *, bool *, const token_indent_info &, vec<tree> * = NULL);
    2474                 :             : static void cp_parser_already_scoped_statement
    2475                 :             :   (cp_parser *, bool *, const token_indent_info &);
    2476                 :             : 
    2477                 :             : /* State of module-declaration parsing.  */
    2478                 :             : enum 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                 :             : 
    2494                 :             : static module_parse cp_parser_module_declaration
    2495                 :             :   (cp_parser *parser, module_parse, bool exporting);
    2496                 :             : static void cp_parser_import_declaration
    2497                 :             :   (cp_parser *parser, module_parse, bool exporting);
    2498                 :             : 
    2499                 :             : /* Declarations [gram.dcl.dcl] */
    2500                 :             : 
    2501                 :             : static void cp_parser_declaration_seq_opt
    2502                 :             :   (cp_parser *);
    2503                 :             : static void cp_parser_declaration
    2504                 :             :   (cp_parser *, tree);
    2505                 :             : static void cp_parser_toplevel_declaration
    2506                 :             :   (cp_parser *);
    2507                 :             : static void cp_parser_block_declaration
    2508                 :             :   (cp_parser *, bool);
    2509                 :             : static void cp_parser_simple_declaration
    2510                 :             :   (cp_parser *, bool, tree *);
    2511                 :             : static void cp_parser_decl_specifier_seq
    2512                 :             :   (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, int *);
    2513                 :             : static tree cp_parser_storage_class_specifier_opt
    2514                 :             :   (cp_parser *);
    2515                 :             : static tree cp_parser_function_specifier_opt
    2516                 :             :   (cp_parser *, cp_decl_specifier_seq *);
    2517                 :             : static tree cp_parser_type_specifier
    2518                 :             :   (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, bool,
    2519                 :             :    int *, bool *);
    2520                 :             : static tree cp_parser_simple_type_specifier
    2521                 :             :   (cp_parser *, cp_decl_specifier_seq *, cp_parser_flags);
    2522                 :             : static tree cp_parser_placeholder_type_specifier
    2523                 :             :   (cp_parser *, location_t, tree, bool);
    2524                 :             : static tree cp_parser_type_name
    2525                 :             :   (cp_parser *, bool);
    2526                 :             : static tree cp_parser_nonclass_name
    2527                 :             :   (cp_parser* parser);
    2528                 :             : static tree cp_parser_elaborated_type_specifier
    2529                 :             :   (cp_parser *, bool, bool);
    2530                 :             : static tree cp_parser_enum_specifier
    2531                 :             :   (cp_parser *);
    2532                 :             : static void cp_parser_enumerator_list
    2533                 :             :   (cp_parser *, tree);
    2534                 :             : static void cp_parser_enumerator_definition
    2535                 :             :   (cp_parser *, tree);
    2536                 :             : static tree cp_parser_namespace_name
    2537                 :             :   (cp_parser *);
    2538                 :             : static void cp_parser_namespace_definition
    2539                 :             :   (cp_parser *);
    2540                 :             : static void cp_parser_namespace_body
    2541                 :             :   (cp_parser *);
    2542                 :             : static tree cp_parser_qualified_namespace_specifier
    2543                 :             :   (cp_parser *);
    2544                 :             : static void cp_parser_namespace_alias_definition
    2545                 :             :   (cp_parser *);
    2546                 :             : static bool cp_parser_using_declaration
    2547                 :             :   (cp_parser *, bool);
    2548                 :             : static void cp_parser_using_directive
    2549                 :             :   (cp_parser *);
    2550                 :             : static void cp_parser_using_enum
    2551                 :             :   (cp_parser *);
    2552                 :             : static tree cp_parser_alias_declaration
    2553                 :             :   (cp_parser *);
    2554                 :             : static void cp_parser_asm_definition
    2555                 :             :   (cp_parser *);
    2556                 :             : static void cp_parser_linkage_specification
    2557                 :             :   (cp_parser *, tree);
    2558                 :             : static void cp_parser_static_assert
    2559                 :             :   (cp_parser *, bool);
    2560                 :             : static tree cp_parser_decltype
    2561                 :             :   (cp_parser *);
    2562                 :             : static tree cp_parser_decomposition_declaration
    2563                 :             :   (cp_parser *, cp_decl_specifier_seq *, tree *, location_t *);
    2564                 :             : 
    2565                 :             : /* Declarators [gram.dcl.decl] */
    2566                 :             : 
    2567                 :             : static 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 *);
    2571                 :             : static cp_declarator *cp_parser_declarator
    2572                 :             :   (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *,
    2573                 :             :    bool, bool, bool);
    2574                 :             : static cp_declarator *cp_parser_direct_declarator
    2575                 :             :   (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool,
    2576                 :             :    bool);
    2577                 :             : static enum tree_code cp_parser_ptr_operator
    2578                 :             :   (cp_parser *, tree *, cp_cv_quals *, tree *);
    2579                 :             : static cp_cv_quals cp_parser_cv_qualifier_seq_opt
    2580                 :             :   (cp_parser *);
    2581                 :             : static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
    2582                 :             :   (cp_parser *);
    2583                 :             : static cp_ref_qualifier cp_parser_ref_qualifier_opt
    2584                 :             :   (cp_parser *);
    2585                 :             : static tree cp_parser_tx_qualifier_opt
    2586                 :             :   (cp_parser *);
    2587                 :             : static tree cp_parser_late_return_type_opt
    2588                 :             :   (cp_parser *, cp_declarator *, tree &);
    2589                 :             : static tree cp_parser_declarator_id
    2590                 :             :   (cp_parser *, bool);
    2591                 :             : static tree cp_parser_type_id
    2592                 :             :   (cp_parser *, cp_parser_flags = CP_PARSER_FLAGS_NONE, location_t * = NULL);
    2593                 :             : static tree cp_parser_template_type_arg
    2594                 :             :   (cp_parser *);
    2595                 :             : static tree cp_parser_trailing_type_id (cp_parser *);
    2596                 :             : static tree cp_parser_type_id_1
    2597                 :             :   (cp_parser *, cp_parser_flags, bool, bool, location_t *);
    2598                 :             : static void cp_parser_type_specifier_seq
    2599                 :             :   (cp_parser *, cp_parser_flags, bool, bool, cp_decl_specifier_seq *);
    2600                 :             : static tree cp_parser_parameter_declaration_clause
    2601                 :             :   (cp_parser *, cp_parser_flags);
    2602                 :             : static tree cp_parser_parameter_declaration_list
    2603                 :             :   (cp_parser *, cp_parser_flags, auto_vec<tree> *);
    2604                 :             : static cp_parameter_declarator *cp_parser_parameter_declaration
    2605                 :             :   (cp_parser *, cp_parser_flags, bool, bool *);
    2606                 :             : static tree cp_parser_default_argument
    2607                 :             :   (cp_parser *, bool);
    2608                 :             : static void cp_parser_function_body
    2609                 :             :   (cp_parser *, bool);
    2610                 :             : static tree cp_parser_initializer
    2611                 :             :   (cp_parser *, bool * = nullptr, bool * = nullptr, bool = false);
    2612                 :             : static cp_expr cp_parser_initializer_clause
    2613                 :             :   (cp_parser *, bool * = nullptr);
    2614                 :             : static cp_expr cp_parser_braced_list
    2615                 :             :   (cp_parser*, bool * = nullptr);
    2616                 :             : static vec<constructor_elt, va_gc> *cp_parser_initializer_list
    2617                 :             :   (cp_parser *, bool *, bool *);
    2618                 :             : 
    2619                 :             : static void cp_parser_ctor_initializer_opt_and_function_body
    2620                 :             :   (cp_parser *, bool);
    2621                 :             : 
    2622                 :             : static tree cp_parser_late_parsing_omp_declare_simd
    2623                 :             :   (cp_parser *, tree);
    2624                 :             : 
    2625                 :             : static tree cp_parser_late_parsing_oacc_routine
    2626                 :             :   (cp_parser *, tree);
    2627                 :             : 
    2628                 :             : static tree synthesize_implicit_template_parm
    2629                 :             :   (cp_parser *, tree);
    2630                 :             : static tree finish_fully_implicit_template
    2631                 :             :   (cp_parser *, tree);
    2632                 :             : static void abort_fully_implicit_template
    2633                 :             :   (cp_parser *);
    2634                 :             : 
    2635                 :             : /* Classes [gram.class] */
    2636                 :             : 
    2637                 :             : static tree cp_parser_class_name
    2638                 :             :   (cp_parser *, bool, bool, enum tag_types, bool, bool, bool, bool = false);
    2639                 :             : static tree cp_parser_class_specifier
    2640                 :             :   (cp_parser *);
    2641                 :             : static tree cp_parser_class_head
    2642                 :             :   (cp_parser *, bool *);
    2643                 :             : static enum tag_types cp_parser_class_key
    2644                 :             :   (cp_parser *);
    2645                 :             : static void cp_parser_type_parameter_key
    2646                 :             :   (cp_parser* parser);
    2647                 :             : static void cp_parser_member_specification_opt
    2648                 :             :   (cp_parser *);
    2649                 :             : static void cp_parser_member_declaration
    2650                 :             :   (cp_parser *);
    2651                 :             : static tree cp_parser_pure_specifier
    2652                 :             :   (cp_parser *);
    2653                 :             : static tree cp_parser_constant_initializer
    2654                 :             :   (cp_parser *);
    2655                 :             : 
    2656                 :             : /* Derived classes [gram.class.derived] */
    2657                 :             : 
    2658                 :             : static tree cp_parser_base_clause
    2659                 :             :   (cp_parser *);
    2660                 :             : static tree cp_parser_base_specifier
    2661                 :             :   (cp_parser *);
    2662                 :             : 
    2663                 :             : /* Special member functions [gram.special] */
    2664                 :             : 
    2665                 :             : static tree cp_parser_conversion_function_id
    2666                 :             :   (cp_parser *);
    2667                 :             : static tree cp_parser_conversion_type_id
    2668                 :             :   (cp_parser *);
    2669                 :             : static cp_declarator *cp_parser_conversion_declarator_opt
    2670                 :             :   (cp_parser *);
    2671                 :             : static void cp_parser_ctor_initializer_opt
    2672                 :             :   (cp_parser *);
    2673                 :             : static void cp_parser_mem_initializer_list
    2674                 :             :   (cp_parser *);
    2675                 :             : static tree cp_parser_mem_initializer
    2676                 :             :   (cp_parser *);
    2677                 :             : static tree cp_parser_mem_initializer_id
    2678                 :             :   (cp_parser *);
    2679                 :             : 
    2680                 :             : /* Overloading [gram.over] */
    2681                 :             : 
    2682                 :             : static cp_expr cp_parser_operator_function_id
    2683                 :             :   (cp_parser *);
    2684                 :             : static cp_expr cp_parser_operator
    2685                 :             :   (cp_parser *, location_t);
    2686                 :             : 
    2687                 :             : /* Templates [gram.temp] */
    2688                 :             : 
    2689                 :             : static void cp_parser_template_declaration
    2690                 :             :   (cp_parser *, bool);
    2691                 :             : static tree cp_parser_template_parameter_list
    2692                 :             :   (cp_parser *);
    2693                 :             : static tree cp_parser_template_parameter
    2694                 :             :   (cp_parser *, bool *, bool *);
    2695                 :             : static tree cp_parser_type_parameter
    2696                 :             :   (cp_parser *, bool *);
    2697                 :             : static tree cp_parser_template_id
    2698                 :             :   (cp_parser *, bool, bool, enum tag_types, bool);
    2699                 :             : static tree cp_parser_template_id_expr
    2700                 :             :   (cp_parser *, bool, bool, bool);
    2701                 :             : static tree cp_parser_template_name
    2702                 :             :   (cp_parser *, bool, bool, bool, enum tag_types, bool *);
    2703                 :             : static tree cp_parser_template_argument_list
    2704                 :             :   (cp_parser *);
    2705                 :             : static tree cp_parser_template_argument
    2706                 :             :   (cp_parser *);
    2707                 :             : static void cp_parser_explicit_instantiation
    2708                 :             :   (cp_parser *);
    2709                 :             : static void cp_parser_explicit_specialization
    2710                 :             :   (cp_parser *);
    2711                 :             : 
    2712                 :             : /* Exception handling [gram.except] */
    2713                 :             : 
    2714                 :             : static tree cp_parser_try_block
    2715                 :             :   (cp_parser *);
    2716                 :             : static void cp_parser_function_try_block
    2717                 :             :   (cp_parser *);
    2718                 :             : static void cp_parser_handler_seq
    2719                 :             :   (cp_parser *);
    2720                 :             : static void cp_parser_handler
    2721                 :             :   (cp_parser *);
    2722                 :             : static tree cp_parser_exception_declaration
    2723                 :             :   (cp_parser *);
    2724                 :             : static tree cp_parser_throw_expression
    2725                 :             :   (cp_parser *);
    2726                 :             : static tree cp_parser_exception_specification_opt
    2727                 :             :   (cp_parser *, cp_parser_flags);
    2728                 :             : static tree cp_parser_type_id_list
    2729                 :             :   (cp_parser *);
    2730                 :             : static tree cp_parser_noexcept_specification_opt
    2731                 :             :   (cp_parser *, cp_parser_flags, bool, bool *, bool);
    2732                 :             : 
    2733                 :             : /* GNU Extensions */
    2734                 :             : 
    2735                 :             : static tree cp_parser_asm_specification_opt
    2736                 :             :   (cp_parser *);
    2737                 :             : static tree cp_parser_asm_operand_list
    2738                 :             :   (cp_parser *);
    2739                 :             : static tree cp_parser_asm_clobber_list
    2740                 :             :   (cp_parser *);
    2741                 :             : static tree cp_parser_asm_label_list
    2742                 :             :   (cp_parser *);
    2743                 :             : static bool cp_next_tokens_can_be_attribute_p
    2744                 :             :   (cp_parser *);
    2745                 :             : static bool cp_next_tokens_can_be_gnu_attribute_p
    2746                 :             :   (cp_parser *);
    2747                 :             : static bool cp_next_tokens_can_be_std_attribute_p
    2748                 :             :   (cp_parser *);
    2749                 :             : static bool cp_nth_tokens_can_be_std_attribute_p
    2750                 :             :   (cp_parser *, size_t);
    2751                 :             : static bool cp_nth_tokens_can_be_gnu_attribute_p
    2752                 :             :   (cp_parser *, size_t);
    2753                 :             : static bool cp_nth_tokens_can_be_attribute_p
    2754                 :             :   (cp_parser *, size_t);
    2755                 :             : static tree cp_parser_attributes_opt
    2756                 :             :   (cp_parser *);
    2757                 :             : static tree cp_parser_gnu_attributes_opt
    2758                 :             :   (cp_parser *);
    2759                 :             : static tree cp_parser_gnu_attribute_list
    2760                 :             :   (cp_parser *, bool = false);
    2761                 :             : static tree cp_parser_std_attribute
    2762                 :             :   (cp_parser *, tree);
    2763                 :             : static tree cp_parser_std_attribute_spec
    2764                 :             :   (cp_parser *);
    2765                 :             : static tree cp_parser_std_attribute_spec_seq
    2766                 :             :   (cp_parser *);
    2767                 :             : static size_t cp_parser_skip_std_attribute_spec_seq
    2768                 :             :   (cp_parser *, size_t);
    2769                 :             : static size_t cp_parser_skip_attributes_opt
    2770                 :             :   (cp_parser *, size_t);
    2771                 :             : static bool cp_parser_extension_opt
    2772                 :             :   (cp_parser *, int *);
    2773                 :             : static void cp_parser_label_declaration
    2774                 :             :   (cp_parser *);
    2775                 :             : 
    2776                 :             : /* Concept Extensions */
    2777                 :             : 
    2778                 :             : static tree cp_parser_concept_definition
    2779                 :             :   (cp_parser *);
    2780                 :             : static tree cp_parser_constraint_expression
    2781                 :             :   (cp_parser *);
    2782                 :             : static tree cp_parser_requires_clause_opt
    2783                 :             :   (cp_parser *, bool);
    2784                 :             : static tree cp_parser_requires_expression
    2785                 :             :   (cp_parser *);
    2786                 :             : static tree cp_parser_requirement_parameter_list
    2787                 :             :   (cp_parser *);
    2788                 :             : static tree cp_parser_requirement_body
    2789                 :             :   (cp_parser *);
    2790                 :             : static tree cp_parser_requirement_seq
    2791                 :             :   (cp_parser *);
    2792                 :             : static tree cp_parser_requirement
    2793                 :             :   (cp_parser *);
    2794                 :             : static tree cp_parser_simple_requirement
    2795                 :             :   (cp_parser *);
    2796                 :             : static tree cp_parser_compound_requirement
    2797                 :             :   (cp_parser *);
    2798                 :             : static tree cp_parser_type_requirement
    2799                 :             :   (cp_parser *);
    2800                 :             : static tree cp_parser_nested_requirement
    2801                 :             :   (cp_parser *);
    2802                 :             : 
    2803                 :             : /* Transactional Memory Extensions */
    2804                 :             : 
    2805                 :             : static tree cp_parser_transaction
    2806                 :             :   (cp_parser *, cp_token *);
    2807                 :             : static tree cp_parser_transaction_expression
    2808                 :             :   (cp_parser *, enum rid);
    2809                 :             : static void cp_parser_function_transaction
    2810                 :             :   (cp_parser *, enum rid);
    2811                 :             : static tree cp_parser_transaction_cancel
    2812                 :             :   (cp_parser *);
    2813                 :             : 
    2814                 :             : /* Coroutine extensions.  */
    2815                 :             : 
    2816                 :             : static tree cp_parser_yield_expression
    2817                 :             :   (cp_parser *);
    2818                 :             : 
    2819                 :             : /* Contracts */
    2820                 :             : 
    2821                 :             : static void cp_parser_late_contract_condition
    2822                 :             :   (cp_parser *, tree, tree);
    2823                 :             : 
    2824                 :             : enum pragma_context {
    2825                 :             :   pragma_external,
    2826                 :             :   pragma_member,
    2827                 :             :   pragma_objc_icode,
    2828                 :             :   pragma_stmt,
    2829                 :             :   pragma_compound
    2830                 :             : };
    2831                 :             : static bool cp_parser_pragma
    2832                 :             :   (cp_parser *, enum pragma_context, bool *);
    2833                 :             : 
    2834                 :             : /* Objective-C++ Productions */
    2835                 :             : 
    2836                 :             : static tree cp_parser_objc_message_receiver
    2837                 :             :   (cp_parser *);
    2838                 :             : static tree cp_parser_objc_message_args
    2839                 :             :   (cp_parser *);
    2840                 :             : static tree cp_parser_objc_message_expression
    2841                 :             :   (cp_parser *);
    2842                 :             : static cp_expr cp_parser_objc_encode_expression
    2843                 :             :   (cp_parser *);
    2844                 :             : static tree cp_parser_objc_defs_expression
    2845                 :             :   (cp_parser *);
    2846                 :             : static tree cp_parser_objc_protocol_expression
    2847                 :             :   (cp_parser *);
    2848                 :             : static tree cp_parser_objc_selector_expression
    2849                 :             :   (cp_parser *);
    2850                 :             : static cp_expr cp_parser_objc_expression
    2851                 :             :   (cp_parser *);
    2852                 :             : static bool cp_parser_objc_selector_p
    2853                 :             :   (enum cpp_ttype);
    2854                 :             : static tree cp_parser_objc_selector
    2855                 :             :   (cp_parser *);
    2856                 :             : static tree cp_parser_objc_protocol_refs_opt
    2857                 :             :   (cp_parser *);
    2858                 :             : static void cp_parser_objc_declaration
    2859                 :             :   (cp_parser *, tree);
    2860                 :             : static tree cp_parser_objc_statement
    2861                 :             :   (cp_parser *);
    2862                 :             : static bool cp_parser_objc_valid_prefix_attributes
    2863                 :             :   (cp_parser *, tree *);
    2864                 :             : static void cp_parser_objc_at_property_declaration
    2865                 :             :   (cp_parser *) ;
    2866                 :             : static void cp_parser_objc_at_synthesize_declaration
    2867                 :             :   (cp_parser *) ;
    2868                 :             : static void cp_parser_objc_at_dynamic_declaration
    2869                 :             :   (cp_parser *) ;
    2870                 :             : static tree cp_parser_objc_struct_declaration
    2871                 :             :   (cp_parser *) ;
    2872                 :             : 
    2873                 :             : /* Utility Routines */
    2874                 :             : 
    2875                 :             : static cp_expr cp_parser_lookup_name
    2876                 :             :   (cp_parser *, tree, enum tag_types, int, bool, bool, tree *, location_t);
    2877                 :             : static tree cp_parser_lookup_name_simple
    2878                 :             :   (cp_parser *, tree, location_t);
    2879                 :             : static tree cp_parser_maybe_treat_template_as_class
    2880                 :             :   (tree, bool);
    2881                 :             : static bool cp_parser_check_declarator_template_parameters
    2882                 :             :   (cp_parser *, cp_declarator *, location_t);
    2883                 :             : static bool cp_parser_check_template_parameters
    2884                 :             :   (cp_parser *, unsigned, bool, location_t, cp_declarator *);
    2885                 :             : static cp_expr cp_parser_simple_cast_expression
    2886                 :             :   (cp_parser *);
    2887                 :             : static tree cp_parser_global_scope_opt
    2888                 :             :   (cp_parser *, bool);
    2889                 :             : static bool cp_parser_constructor_declarator_p
    2890                 :             :   (cp_parser *, cp_parser_flags, bool);
    2891                 :             : static tree cp_parser_function_definition_from_specifiers_and_declarator
    2892                 :             :   (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *);
    2893                 :             : static tree cp_parser_function_definition_after_declarator
    2894                 :             :   (cp_parser *, bool);
    2895                 :             : static bool cp_parser_template_declaration_after_export
    2896                 :             :   (cp_parser *, bool);
    2897                 :             : static void cp_parser_perform_template_parameter_access_checks
    2898                 :             :   (vec<deferred_access_check, va_gc> *);
    2899                 :             : static tree cp_parser_single_declaration
    2900                 :             :   (cp_parser *, vec<deferred_access_check, va_gc> *, bool, bool, bool *);
    2901                 :             : static cp_expr cp_parser_functional_cast
    2902                 :             :   (cp_parser *, tree);
    2903                 :             : static tree cp_parser_save_member_function_body
    2904                 :             :   (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree);
    2905                 :             : static tree cp_parser_save_nsdmi
    2906                 :             :   (cp_parser *);
    2907                 :             : static tree cp_parser_enclosed_template_argument_list
    2908                 :             :   (cp_parser *);
    2909                 :             : static void cp_parser_save_default_args
    2910                 :             :   (cp_parser *, tree);
    2911                 :             : static void cp_parser_late_parsing_for_member
    2912                 :             :   (cp_parser *, tree);
    2913                 :             : static tree cp_parser_late_parse_one_default_arg
    2914                 :             :   (cp_parser *, tree, tree, tree);
    2915                 :             : static void cp_parser_late_parsing_nsdmi
    2916                 :             :   (cp_parser *, tree);
    2917                 :             : static void cp_parser_late_parsing_default_args
    2918                 :             :   (cp_parser *, tree);
    2919                 :             : static tree cp_parser_sizeof_operand
    2920                 :             :   (cp_parser *, enum rid);
    2921                 :             : static cp_expr cp_parser_trait
    2922                 :             :   (cp_parser *, const cp_trait *);
    2923                 :             : static bool cp_parser_declares_only_class_p
    2924                 :             :   (cp_parser *);
    2925                 :             : static void cp_parser_set_storage_class
    2926                 :             :   (cp_parser *, cp_decl_specifier_seq *, enum rid, cp_token *);
    2927                 :             : static void cp_parser_set_decl_spec_type
    2928                 :             :   (cp_decl_specifier_seq *, tree, cp_token *, bool);
    2929                 :             : static void set_and_check_decl_spec_loc
    2930                 :             :   (cp_decl_specifier_seq *decl_specs,
    2931                 :             :    cp_decl_spec ds, cp_token *);
    2932                 :             : static bool cp_parser_friend_p
    2933                 :             :   (const cp_decl_specifier_seq *);
    2934                 :             : static void cp_parser_required_error
    2935                 :             :   (cp_parser *, required_token, bool, location_t);
    2936                 :             : static cp_token *cp_parser_require
    2937                 :             :   (cp_parser *, enum cpp_ttype, required_token, location_t = UNKNOWN_LOCATION);
    2938                 :             : static cp_token *cp_parser_require_keyword
    2939                 :             :   (cp_parser *, enum rid, required_token);
    2940                 :             : static bool cp_parser_token_starts_function_definition_p
    2941                 :             :   (cp_token *);
    2942                 :             : static bool cp_parser_next_token_starts_class_definition_p
    2943                 :             :   (cp_parser *);
    2944                 :             : static bool cp_parser_next_token_ends_template_argument_p
    2945                 :             :   (cp_parser *);
    2946                 :             : static bool cp_parser_nth_token_starts_template_argument_list_p
    2947                 :             :   (cp_parser *, size_t);
    2948                 :             : static enum tag_types cp_parser_token_is_class_key
    2949                 :             :   (cp_token *);
    2950                 :             : static enum tag_types cp_parser_token_is_type_parameter_key
    2951                 :             :   (cp_token *);
    2952                 :             : static void cp_parser_maybe_warn_enum_key (cp_parser *, location_t, tree, rid);
    2953                 :             : static void cp_parser_check_class_key
    2954                 :             : (cp_parser *, location_t, enum tag_types, tree type, bool, bool);
    2955                 :             : static void cp_parser_check_access_in_redeclaration
    2956                 :             :   (tree type, location_t location);
    2957                 :             : static bool cp_parser_optional_template_keyword
    2958                 :             :   (cp_parser *);
    2959                 :             : static void cp_parser_pre_parsed_nested_name_specifier
    2960                 :             :   (cp_parser *);
    2961                 :             : static bool cp_parser_cache_group
    2962                 :             :   (cp_parser *, enum cpp_ttype, unsigned);
    2963                 :             : static tree cp_parser_cache_defarg
    2964                 :             :   (cp_parser *parser, bool nsdmi);
    2965                 :             : static void cp_parser_parse_tentatively
    2966                 :             :   (cp_parser *);
    2967                 :             : static void cp_parser_commit_to_tentative_parse
    2968                 :             :   (cp_parser *);
    2969                 :             : static void cp_parser_commit_to_topmost_tentative_parse
    2970                 :             :   (cp_parser *);
    2971                 :             : static void cp_parser_abort_tentative_parse
    2972                 :             :   (cp_parser *);
    2973                 :             : static bool cp_parser_parse_definitely
    2974                 :             :   (cp_parser *);
    2975                 :             : static inline bool cp_parser_parsing_tentatively
    2976                 :             :   (cp_parser *);
    2977                 :             : static bool cp_parser_uncommitted_to_tentative_parse_p
    2978                 :             :   (cp_parser *);
    2979                 :             : static void cp_parser_error
    2980                 :             :   (cp_parser *, const char *);
    2981                 :             : static void cp_parser_name_lookup_error
    2982                 :             :   (cp_parser *, tree, tree, name_lookup_error, location_t);
    2983                 :             : static bool cp_parser_simulate_error
    2984                 :             :   (cp_parser *);
    2985                 :             : static bool cp_parser_check_type_definition
    2986                 :             :   (cp_parser *);
    2987                 :             : static void cp_parser_check_for_definition_in_return_type
    2988                 :             :   (cp_declarator *, tree, location_t type_location);
    2989                 :             : static void cp_parser_check_for_invalid_template_id
    2990                 :             :   (cp_parser *, tree, enum tag_types, location_t location);
    2991                 :             : static bool cp_parser_non_integral_constant_expression
    2992                 :             :   (cp_parser *, non_integral_constant);
    2993                 :             : static void cp_parser_diagnose_invalid_type_name
    2994                 :             :   (cp_parser *, tree, location_t);
    2995                 :             : static bool cp_parser_parse_and_diagnose_invalid_type_name
    2996                 :             :   (cp_parser *);
    2997                 :             : static int cp_parser_skip_to_closing_parenthesis
    2998                 :             :   (cp_parser *, bool, bool, bool);
    2999                 :             : static void cp_parser_skip_to_end_of_statement
    3000                 :             :   (cp_parser *);
    3001                 :             : static void cp_parser_consume_semicolon_at_end_of_statement
    3002                 :             :   (cp_parser *);
    3003                 :             : static void cp_parser_skip_to_end_of_block_or_statement
    3004                 :             :   (cp_parser *);
    3005                 :             : static bool cp_parser_skip_to_closing_brace
    3006                 :             :   (cp_parser *);
    3007                 :             : static bool cp_parser_skip_entire_template_parameter_list
    3008                 :             :   (cp_parser *);
    3009                 :             : static void cp_parser_require_end_of_template_parameter_list
    3010                 :             :   (cp_parser *);
    3011                 :             : static bool cp_parser_skip_to_end_of_template_parameter_list
    3012                 :             :   (cp_parser *);
    3013                 :             : static void cp_parser_skip_to_pragma_eol
    3014                 :             :   (cp_parser*, cp_token *);
    3015                 :             : static bool cp_parser_error_occurred
    3016                 :             :   (cp_parser *);
    3017                 :             : static bool cp_parser_allow_gnu_extensions_p
    3018                 :             :   (cp_parser *);
    3019                 :             : static bool cp_parser_is_pure_string_literal
    3020                 :             :   (cp_token *);
    3021                 :             : static bool cp_parser_is_string_literal
    3022                 :             :   (cp_token *);
    3023                 :             : static bool cp_parser_is_keyword
    3024                 :             :   (cp_token *, enum rid);
    3025                 :             : static tree cp_parser_make_typename_type
    3026                 :             :   (cp_parser *, tree, location_t location);
    3027                 :             : static cp_declarator * cp_parser_make_indirect_declarator
    3028                 :             :   (enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
    3029                 :             : static bool cp_parser_compound_literal_p
    3030                 :             :   (cp_parser *);
    3031                 :             : static bool cp_parser_array_designator_p
    3032                 :             :   (cp_parser *);
    3033                 :             : static bool cp_parser_init_statement_p
    3034                 :             :   (cp_parser *);
    3035                 :             : static bool cp_parser_skip_up_to_closing_square_bracket
    3036                 :             :   (cp_parser *);
    3037                 :             : static bool cp_parser_skip_to_closing_square_bracket
    3038                 :             :   (cp_parser *);
    3039                 :             : static size_t cp_parser_skip_balanced_tokens (cp_parser *, size_t);
    3040                 :             : static 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.
    3046                 :    89945434 : cp_unevaluated::cp_unevaluated ()
    3047                 :             : {
    3048                 :    89945434 :   ++cp_unevaluated_operand;
    3049                 :    89945434 :   ++c_inhibit_evaluation_warnings;
    3050                 :    89945434 : }
    3051                 :             : 
    3052                 :    89943634 : cp_unevaluated::~cp_unevaluated ()
    3053                 :             : {
    3054                 :    89943634 :   --c_inhibit_evaluation_warnings;
    3055                 :    89943634 :   --cp_unevaluated_operand;
    3056                 :    89943634 : }
    3057                 :             : 
    3058                 :             : // -------------------------------------------------------------------------- //
    3059                 :             : // Tentative Parsing
    3060                 :             : 
    3061                 :             : /* Returns nonzero if we are parsing tentatively.  */
    3062                 :             : 
    3063                 :             : static inline bool
    3064                 : 36703483504 : cp_parser_parsing_tentatively (cp_parser* parser)
    3065                 :             : {
    3066                 : 36703483504 :   return parser->context->next != NULL;
    3067                 :             : }
    3068                 :             : 
    3069                 :             : /* Returns nonzero if TOKEN is a string literal.  */
    3070                 :             : 
    3071                 :             : static bool
    3072                 :    74950590 : cp_parser_is_pure_string_literal (cp_token* token)
    3073                 :             : {
    3074                 :    50243546 :   return (token->type == CPP_STRING ||
    3075                 :    50242852 :           token->type == CPP_STRING16 ||
    3076                 :    50242141 :           token->type == CPP_STRING32 ||
    3077                 :   125077597 :           token->type == CPP_WSTRING ||
    3078                 :    74950590 :           token->type == CPP_UTF8STRING);
    3079                 :             : }
    3080                 :             : 
    3081                 :             : /* Returns nonzero if TOKEN is a string literal
    3082                 :             :    of a user-defined string literal.  */
    3083                 :             : 
    3084                 :             : static bool
    3085                 :    36685529 : cp_parser_is_string_literal (cp_token* token)
    3086                 :             : {
    3087                 :    53006496 :   return (cp_parser_is_pure_string_literal (token) ||
    3088                 :    16320967 :           token->type == CPP_STRING_USERDEF ||
    3089                 :    15794083 :           token->type == CPP_STRING16_USERDEF ||
    3090                 :    15793973 :           token->type == CPP_STRING32_USERDEF ||
    3091                 :    52479429 :           token->type == CPP_WSTRING_USERDEF ||
    3092                 :    36685529 :           token->type == CPP_UTF8STRING_USERDEF);
    3093                 :             : }
    3094                 :             : 
    3095                 :             : /* Returns nonzero if TOKEN is the indicated KEYWORD.  */
    3096                 :             : 
    3097                 :             : static bool
    3098                 :   526295586 : cp_parser_is_keyword (cp_token* token, enum rid keyword)
    3099                 :             : {
    3100                 :   526295586 :   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                 :             : 
    3114                 :             : static bool
    3115                 :         133 : cp_lexer_peek_conflict_marker (cp_lexer *lexer, enum cpp_ttype tok1_kind,
    3116                 :             :                                location_t *out_loc)
    3117                 :             : {
    3118                 :         133 :   cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
    3119                 :         133 :   if (token2->type != tok1_kind)
    3120                 :             :     return false;
    3121                 :         113 :   cp_token *token3 = cp_lexer_peek_nth_token (lexer, 3);
    3122                 :         113 :   if (token3->type != tok1_kind)
    3123                 :             :     return false;
    3124                 :         101 :   cp_token *token4 = cp_lexer_peek_nth_token (lexer, 4);
    3125                 :         101 :   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                 :          73 :   location_t start_loc = cp_lexer_peek_token (lexer)->location;
    3130                 :          73 :   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                 :          61 :   location_t finish_loc = get_finish (token4->location);
    3138                 :          61 :   *out_loc = make_location (start_loc, start_loc, finish_loc);
    3139                 :             : 
    3140                 :          61 :   return true;
    3141                 :             : }
    3142                 :             : 
    3143                 :             : /* Get a description of the matching symbol to TOKEN_DESC e.g. "(" for
    3144                 :             :    RT_CLOSE_PAREN.  */
    3145                 :             : 
    3146                 :             : static const char *
    3147                 :         214 : get_matching_symbol (required_token token_desc)
    3148                 :             : {
    3149                 :         214 :   switch (token_desc)
    3150                 :             :     {
    3151                 :           0 :     default:
    3152                 :           0 :       gcc_unreachable ();
    3153                 :             :       return "";
    3154                 :             :     case RT_CLOSE_BRACE:
    3155                 :             :       return "{";
    3156                 :          62 :     case RT_CLOSE_PAREN:
    3157                 :          62 :       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                 :             : 
    3164                 :             : static enum cpp_ttype
    3165                 :        2961 : get_required_cpp_ttype (required_token token_desc)
    3166                 :             : {
    3167                 :           0 :   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                 :             : 
    3213                 :             : static void
    3214                 :        7422 : cp_parser_error_1 (cp_parser* parser, const char* gmsgid,
    3215                 :             :                    required_token missing_token_desc,
    3216                 :             :                    location_t matching_location)
    3217                 :             : {
    3218                 :        7422 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
    3219                 :             :   /* This diagnostic makes more sense if it is tagged to the line
    3220                 :             :      of the token we just peeked at.  */
    3221                 :        7422 :   cp_lexer_set_source_position_from_token (token);
    3222                 :             : 
    3223                 :        7422 :   if (token->type == CPP_PRAGMA)
    3224                 :             :     {
    3225                 :          19 :       error_at (token->location,
    3226                 :             :                 "%<#pragma%> is not allowed here");
    3227                 :          19 :       cp_parser_skip_to_pragma_eol (parser, token);
    3228                 :          99 :       return;
    3229                 :             :     }
    3230                 :             : 
    3231                 :             :   /* If this is actually a conflict marker, report it as such.  */
    3232                 :        7403 :   if (token->type == CPP_LSHIFT
    3233                 :        7403 :       || token->type == CPP_RSHIFT
    3234                 :        7317 :       || token->type == CPP_EQ_EQ)
    3235                 :             :     {
    3236                 :         133 :       location_t loc;
    3237                 :         133 :       if (cp_lexer_peek_conflict_marker (parser->lexer, token->type, &loc))
    3238                 :             :         {
    3239                 :          61 :           error_at (loc, "version control conflict marker in file");
    3240                 :          61 :           expanded_location token_exploc = expand_location (token->location);
    3241                 :             :           /* Consume tokens until the end of the source line.  */
    3242                 :         625 :           for (;;)
    3243                 :             :             {
    3244                 :         343 :               cp_lexer_consume_token (parser->lexer);
    3245                 :         343 :               cp_token *next = cp_lexer_peek_token (parser->lexer);
    3246                 :         343 :               if (next->type == CPP_EOF)
    3247                 :             :                 break;
    3248                 :         335 :               if (next->location == UNKNOWN_LOCATION
    3249                 :         335 :                   || loc == UNKNOWN_LOCATION)
    3250                 :             :                 break;
    3251                 :             : 
    3252                 :         335 :               expanded_location next_exploc = expand_location (next->location);
    3253                 :         335 :               if (next_exploc.file != token_exploc.file)
    3254                 :             :                 break;
    3255                 :         335 :               if (next_exploc.line != token_exploc.line)
    3256                 :             :                 break;
    3257                 :         282 :             }
    3258                 :          61 :           return;
    3259                 :             :         }
    3260                 :             :     }
    3261                 :             : 
    3262                 :        7342 :   auto_diagnostic_group d;
    3263                 :        7342 :   gcc_rich_location richloc (input_location);
    3264                 :             : 
    3265                 :        7342 :   bool added_matching_location = false;
    3266                 :             : 
    3267                 :        7342 :   if (missing_token_desc != RT_NONE)
    3268                 :        3127 :     if (cp_token *prev_token = cp_lexer_safe_previous_token (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                 :        2961 :         enum cpp_ttype ttype = get_required_cpp_ttype (missing_token_desc);
    3274                 :        2961 :         location_t prev_token_loc = prev_token->location;
    3275                 :        2961 :         maybe_suggest_missing_token_insertion (&richloc, 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                 :        2961 :         if (matching_location != UNKNOWN_LOCATION)
    3282                 :        1185 :           added_matching_location
    3283                 :        1185 :             = richloc.add_location_if_nearby (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                 :        7342 :   name_hint h;
    3292                 :        7342 :   if (token->type == CPP_NAME)
    3293                 :         932 :     if (cp_token *prev_token = cp_lexer_safe_previous_token (parser->lexer))
    3294                 :         898 :       if (cp_parser_is_string_literal (prev_token))
    3295                 :             :         {
    3296                 :          19 :           tree name = token->u.value;
    3297                 :          19 :           const char *token_name = IDENTIFIER_POINTER (name);
    3298                 :          19 :           const char *header_hint
    3299                 :          19 :             = get_cp_stdlib_header_for_string_macro_name (token_name);
    3300                 :          19 :           if (header_hint != NULL)
    3301                 :          32 :             h = name_hint (NULL, new suggest_missing_header (token->location,
    3302                 :             :                                                              token_name,
    3303                 :          16 :                                                              header_hint));
    3304                 :             :         }
    3305                 :             : 
    3306                 :             :   /* Actually emit the error.  */
    3307                 :        7342 :   c_parse_error (gmsgid,
    3308                 :             :                  /* Because c_parser_error does not understand
    3309                 :             :                     CPP_KEYWORD, keywords are treated like
    3310                 :             :                     identifiers.  */
    3311                 :        7342 :                  (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
    3312                 :        7342 :                  token->u.value, token->flags, &richloc);
    3313                 :             : 
    3314                 :        7342 :   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                 :        3127 :       if (matching_location != UNKNOWN_LOCATION
    3319                 :        3127 :           && !added_matching_location)
    3320                 :         214 :         inform (matching_location, "to match this %qs",
    3321                 :             :                 get_matching_symbol (missing_token_desc));
    3322                 :             :     }
    3323                 :        7342 : }
    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                 :             : 
    3331                 :             : static void
    3332                 :  6566352353 : cp_parser_error (cp_parser* parser, const char* gmsgid)
    3333                 :             : {
    3334                 : 13132704706 :   if (!cp_parser_simulate_error (parser))
    3335                 :        4287 :     cp_parser_error_1 (parser, gmsgid, RT_NONE, UNKNOWN_LOCATION);
    3336                 :  6566352353 : }
    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                 :             : 
    3343                 :             : static void
    3344                 :         342 : cp_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                 :         342 :   if (decl == error_mark_node)
    3353                 :             :     {
    3354                 :         291 :       if (parser->scope && parser->scope != global_namespace)
    3355                 :          38 :         error_at (location, "%<%E::%E%> has not been declared",
    3356                 :             :                   parser->scope, name);
    3357                 :         253 :       else if (parser->scope == global_namespace)
    3358                 :           0 :         error_at (location, "%<::%E%> has not been declared", name);
    3359                 :         253 :       else if (parser->object_scope
    3360                 :         253 :                && !CLASS_TYPE_P (parser->object_scope))
    3361                 :           0 :         error_at (location, "request for member %qE in non-class type %qT",
    3362                 :             :                   name, parser->object_scope);
    3363                 :         253 :       else if (parser->object_scope)
    3364                 :           0 :         error_at (location, "%<%T::%E%> has not been declared",
    3365                 :             :                   parser->object_scope, name);
    3366                 :             :       else
    3367                 :         253 :         error_at (location, "%qE has not been declared", name);
    3368                 :             :     }
    3369                 :          51 :   else if (parser->scope && parser->scope != global_namespace)
    3370                 :             :     {
    3371                 :          21 :       switch (desired)
    3372                 :             :         {
    3373                 :          21 :           case NLE_TYPE:
    3374                 :          21 :             error_at (location, "%<%E::%E%> is not a type",
    3375                 :             :                                 parser->scope, name);
    3376                 :          21 :             break;
    3377                 :           0 :           case NLE_CXX98:
    3378                 :           0 :             error_at (location, "%<%E::%E%> is not a class or namespace",
    3379                 :             :                                 parser->scope, name);
    3380                 :           0 :             break;
    3381                 :           0 :           case NLE_NOT_CXX98:
    3382                 :           0 :             error_at (location,
    3383                 :             :                       "%<%E::%E%> is not a class, namespace, or enumeration",
    3384                 :             :                       parser->scope, name);
    3385                 :           0 :             break;
    3386                 :           0 :           default:
    3387                 :           0 :             gcc_unreachable ();
    3388                 :             : 
    3389                 :             :         }
    3390                 :             :     }
    3391                 :          30 :   else if (parser->scope == global_namespace)
    3392                 :             :     {
    3393                 :           0 :       switch (desired)
    3394                 :             :         {
    3395                 :           0 :           case NLE_TYPE:
    3396                 :           0 :             error_at (location, "%<::%E%> is not a type", name);
    3397                 :           0 :             break;
    3398                 :           0 :           case NLE_CXX98:
    3399                 :           0 :             error_at (location, "%<::%E%> is not a class or namespace", name);
    3400                 :           0 :             break;
    3401                 :           0 :           case NLE_NOT_CXX98:
    3402                 :           0 :             error_at (location,
    3403                 :             :                       "%<::%E%> is not a class, namespace, or enumeration",
    3404                 :             :                       name);
    3405                 :           0 :             break;
    3406                 :           0 :           default:
    3407                 :           0 :             gcc_unreachable ();
    3408                 :             :         }
    3409                 :             :     }
    3410                 :             :   else
    3411                 :             :     {
    3412                 :          30 :       switch (desired)
    3413                 :             :         {
    3414                 :          13 :           case NLE_TYPE:
    3415                 :          13 :             error_at (location, "%qE is not a type", name);
    3416                 :          13 :             break;
    3417                 :           5 :           case NLE_CXX98:
    3418                 :           5 :             error_at (location, "%qE is not a class or namespace", name);
    3419                 :           5 :             break;
    3420                 :          12 :           case NLE_NOT_CXX98:
    3421                 :          12 :             error_at (location,
    3422                 :             :                       "%qE is not a class, namespace, or enumeration", name);
    3423                 :          12 :             break;
    3424                 :           0 :           default:
    3425                 :           0 :             gcc_unreachable ();
    3426                 :             :         }
    3427                 :             :     }
    3428                 :         342 : }
    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                 :             : 
    3434                 :             : static bool
    3435                 : 11507820560 : cp_parser_simulate_error (cp_parser* parser)
    3436                 :             : {
    3437                 :        4287 :   if (cp_parser_uncommitted_to_tentative_parse_p (parser))
    3438                 :             :     {
    3439                 : 11507809346 :       parser->context->status = CP_PARSER_STATUS_KIND_ERROR;
    3440                 :  8559604330 :       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                 :             : 
    3449                 :             : static bool
    3450                 :    25019527 : cp_parser_check_type_definition (cp_parser* parser)
    3451                 :             : {
    3452                 :             :   /* If types are forbidden here, issue a message.  */
    3453                 :           0 :   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                 :          24 :       error (parser->type_definition_forbidden_message,
    3458                 :             :              parser->type_definition_forbidden_message_arg);
    3459                 :         145 :       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                 :             : 
    3470                 :             : static void
    3471                 :      756608 : cp_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                 :      756608 :   while (declarator
    3478                 :      757166 :          && (declarator->kind == cdk_pointer
    3479                 :             :              || declarator->kind == cdk_reference
    3480                 :      757166 :              || declarator->kind == cdk_ptrmem))
    3481                 :         558 :     declarator = declarator->declarator;
    3482                 :      756608 :   if (declarator
    3483                 :      756608 :       && declarator->kind == cdk_function)
    3484                 :             :     {
    3485                 :          32 :       error_at (type_location,
    3486                 :             :                 "new types may not be defined in a return type");
    3487                 :          32 :       inform (type_location,
    3488                 :             :               "(perhaps a semicolon is missing after the definition of %qT)",
    3489                 :             :               type);
    3490                 :             :     }
    3491                 :      756608 : }
    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                 :             : 
    3499                 :             : static void
    3500                 :   885933660 : cp_parser_check_for_invalid_template_id (cp_parser* parser,
    3501                 :             :                                          tree type,
    3502                 :             :                                          enum tag_types tag_type,
    3503                 :             :                                          location_t location)
    3504                 :             : {
    3505                 :   885933660 :   cp_token_position start = 0;
    3506                 :             : 
    3507                 :   885933660 :   if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
    3508                 :             :     {
    3509                 :         127 :       if (TREE_CODE (type) == TYPE_DECL)
    3510                 :          73 :         type = TREE_TYPE (type);
    3511                 :         127 :       if (TYPE_P (type) && !template_placeholder_p (type))
    3512                 :          81 :         error_at (location, "%qT is not a template", type);
    3513                 :          46 :       else if (identifier_p (type))
    3514                 :             :         {
    3515                 :          46 :           if (tag_type != none_type)
    3516                 :          46 :             error_at (location, "%qE is not a class template", type);
    3517                 :             :           else
    3518                 :           0 :             error_at (location, "%qE is not a template", type);
    3519                 :             :         }
    3520                 :             :       else
    3521                 :           0 :         error_at (location, "invalid template-id");
    3522                 :             :       /* Remember the location of the invalid "<".  */
    3523                 :         335 :       if (cp_parser_uncommitted_to_tentative_parse_p (parser))
    3524                 :          81 :         start = cp_lexer_token_position (parser->lexer, true);
    3525                 :             :       /* Consume the "<".  */
    3526                 :         127 :       cp_lexer_consume_token (parser->lexer);
    3527                 :             :       /* Parse the template arguments.  */
    3528                 :         127 :       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                 :         127 :       if (start)
    3532                 :          81 :         cp_lexer_purge_tokens_after (parser->lexer, start);
    3533                 :             :     }
    3534                 :   885933660 : }
    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                 :             : 
    3541                 :             : static bool
    3542                 :   418353934 : cp_parser_non_integral_constant_expression (cp_parser  *parser,
    3543                 :             :                                             non_integral_constant thing)
    3544                 :             : {
    3545                 :   418353934 :   parser->non_integral_constant_expression_p = true;
    3546                 :   418353934 :   if (parser->integral_constant_expression_p)
    3547                 :             :     {
    3548                 :    77509573 :       if (!parser->allow_non_integral_constant_expression_p)
    3549                 :             :         {
    3550                 :          63 :           const char *msg = NULL;
    3551                 :          63 :           switch (thing)
    3552                 :             :             {
    3553                 :          10 :               case NIC_FLOAT:
    3554                 :          10 :                 pedwarn (input_location, OPT_Wpedantic,
    3555                 :             :                          "ISO C++ forbids using a floating-point literal "
    3556                 :             :                          "in a constant-expression");
    3557                 :          10 :                 return true;
    3558                 :          18 :               case NIC_CAST:
    3559                 :          18 :                 error ("a cast to a type other than an integral or "
    3560                 :             :                        "enumeration type cannot appear in a "
    3561                 :             :                        "constant-expression");
    3562                 :          18 :                 return true;
    3563                 :           1 :               case NIC_TYPEID:
    3564                 :           1 :                 error ("%<typeid%> operator "
    3565                 :             :                        "cannot appear in a constant-expression");
    3566                 :           1 :                 return true;
    3567                 :           0 :               case NIC_NCC:
    3568                 :           0 :                 error ("non-constant compound literals "
    3569                 :             :                        "cannot appear in a constant-expression");
    3570                 :           0 :                 return true;
    3571                 :           4 :               case NIC_FUNC_CALL:
    3572                 :           4 :                 error ("a function call "
    3573                 :             :                        "cannot appear in a constant-expression");
    3574                 :           4 :                 return true;
    3575                 :           0 :               case NIC_INC:
    3576                 :           0 :                 error ("an increment "
    3577                 :             :                        "cannot appear in a constant-expression");
    3578                 :           0 :                 return true;
    3579                 :           0 :               case NIC_DEC:
    3580                 :           0 :                 error ("an decrement "
    3581                 :             :                        "cannot appear in a constant-expression");
    3582                 :           0 :                 return true;
    3583                 :           5 :               case NIC_ARRAY_REF:
    3584                 :           5 :                 error ("an array reference "
    3585                 :             :                        "cannot appear in a constant-expression");
    3586                 :           5 :                 return true;
    3587                 :           2 :               case NIC_ADDR_LABEL:
    3588                 :           2 :                 error ("the address of a label "
    3589                 :             :                        "cannot appear in a constant-expression");
    3590                 :           2 :                 return true;
    3591                 :           0 :               case NIC_OVERLOADED:
    3592                 :           0 :                 error ("calls to overloaded operators "
    3593                 :             :                        "cannot appear in a constant-expression");
    3594                 :           0 :                 return true;
    3595                 :           1 :               case NIC_ASSIGNMENT:
    3596                 :           1 :                 error ("an assignment cannot appear in a constant-expression");
    3597                 :           1 :                 return true;
    3598                 :           2 :               case NIC_COMMA:
    3599                 :           2 :                 error ("a comma operator "
    3600                 :             :                        "cannot appear in a constant-expression");
    3601                 :           2 :                 return true;
    3602                 :           1 :               case NIC_CONSTRUCTOR:
    3603                 :           1 :                 error ("a call to a constructor "
    3604                 :             :                        "cannot appear in a constant-expression");
    3605                 :           1 :                 return true;
    3606                 :           0 :               case NIC_TRANSACTION:
    3607                 :           0 :                 error ("a transaction expression "
    3608                 :             :                        "cannot appear in a constant-expression");
    3609                 :           0 :                 return true;
    3610                 :             :               case NIC_THIS:
    3611                 :             :                 msg = "this";
    3612                 :             :                 break;
    3613                 :           1 :               case NIC_FUNC_NAME:
    3614                 :           1 :                 msg = "__FUNCTION__";
    3615                 :           1 :                 break;
    3616                 :           1 :               case NIC_PRETTY_FUNC:
    3617                 :           1 :                 msg = "__PRETTY_FUNCTION__";
    3618                 :           1 :                 break;
    3619                 :           1 :               case NIC_C99_FUNC:
    3620                 :           1 :                 msg = "__func__";
    3621                 :           1 :                 break;
    3622                 :           0 :               case NIC_VA_ARG:
    3623                 :           0 :                 msg = "va_arg";
    3624                 :           0 :                 break;
    3625                 :           1 :               case NIC_ARROW:
    3626                 :           1 :                 msg = "->";
    3627                 :           1 :                 break;
    3628                 :           1 :               case NIC_POINT:
    3629                 :           1 :                 msg = ".";
    3630                 :           1 :                 break;
    3631                 :           4 :               case NIC_STAR:
    3632                 :           4 :                 msg = "*";
    3633                 :           4 :                 break;
    3634                 :          10 :               case NIC_ADDR:
    3635                 :          10 :                 msg = "&";
    3636                 :          10 :                 break;
    3637                 :           0 :               case NIC_PREINCREMENT:
    3638                 :           0 :                 msg = "++";
    3639                 :           0 :                 break;
    3640                 :           0 :               case NIC_PREDECREMENT:
    3641                 :           0 :                 msg = "--";
    3642                 :           0 :                 break;
    3643                 :           0 :               case NIC_NEW:
    3644                 :           0 :                 msg = "new";
    3645                 :           0 :                 break;
    3646                 :           0 :               case NIC_DEL:
    3647                 :           0 :                 msg = "delete";
    3648                 :           0 :                 break;
    3649                 :           0 :               default:
    3650                 :           0 :                 gcc_unreachable ();
    3651                 :             :             }
    3652                 :          19 :           if (msg)
    3653                 :          19 :             error ("%qs cannot appear in a constant-expression", msg);
    3654                 :          19 :           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                 :             : 
    3665                 :             : static void
    3666                 :         915 : cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
    3667                 :             :                                       location_t location)
    3668                 :             : {
    3669                 :         915 :   tree decl, ambiguous_decls;
    3670                 :         915 :   cp_parser_commit_to_tentative_parse (parser);
    3671                 :             :   /* Try to lookup the identifier.  */
    3672                 :         915 :   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                 :         915 :   if (ambiguous_decls)
    3678                 :             :     /* If the lookup was ambiguous, an error will already have
    3679                 :             :        been issued.  */
    3680                 :          24 :     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                 :         891 :   if (DECL_TYPE_TEMPLATE_P (decl))
    3684                 :             :     {
    3685                 :          47 :       auto_diagnostic_group d;
    3686                 :          47 :       error_at (location,
    3687                 :             :                 "invalid use of template-name %qE without an argument list",
    3688                 :             :                 decl);
    3689                 :          47 :       if (DECL_CLASS_TEMPLATE_P (decl) && cxx_dialect < cxx17)
    3690                 :          35 :         inform (location, "class template argument deduction is only available "
    3691                 :             :                 "with %<-std=c++17%> or %<-std=gnu++17%>");
    3692                 :          47 :       inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
    3693                 :          47 :     }
    3694                 :         844 :   else if (TREE_CODE (id) == BIT_NOT_EXPR)
    3695                 :           4 :     error_at (location, "invalid use of destructor %qD as a type", id);
    3696                 :         840 :   else if (TREE_CODE (decl) == TYPE_DECL)
    3697                 :             :     /* Something like 'unsigned A a;'  */
    3698                 :           0 :     error_at (location, "invalid combination of multiple type-specifiers");
    3699                 :         840 :   else if (!parser->scope)
    3700                 :             :     {
    3701                 :             :       /* Issue an error message.  */
    3702                 :         493 :       auto_diagnostic_group d;
    3703                 :         493 :       name_hint hint;
    3704                 :         493 :       if (TREE_CODE (id) == IDENTIFIER_NODE)
    3705                 :         493 :         hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_TYPENAME, location);
    3706                 :         493 :       if (const char *suggestion = hint.suggestion ())
    3707                 :             :         {
    3708                 :          76 :           gcc_rich_location richloc (location);
    3709                 :          76 :           richloc.add_fixit_replace (suggestion);
    3710                 :          76 :           error_at (&richloc,
    3711                 :             :                     "%qE does not name a type; did you mean %qs?",
    3712                 :             :                     id, suggestion);
    3713                 :          76 :         }
    3714                 :             :       else
    3715                 :         417 :         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                 :         493 :       if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_CONSTEXPR])
    3724                 :           4 :         inform (location, "C++11 %<constexpr%> only available with "
    3725                 :             :                 "%<-std=c++11%> or %<-std=gnu++11%>");
    3726                 :         489 :       else if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_NOEXCEPT])
    3727                 :           1 :         inform (location, "C++11 %<noexcept%> only available with "
    3728                 :             :                 "%<-std=c++11%> or %<-std=gnu++11%>");
    3729                 :         488 :       else if (TREE_CODE (id) == IDENTIFIER_NODE
    3730                 :         488 :                && (id_equal (id, "module") || id_equal (id, "import")))
    3731                 :             :         {
    3732                 :          17 :           if (modules_p ())
    3733                 :          15 :             inform (location, "%qE is not recognized as a module control-line",
    3734                 :             :                     id);
    3735                 :           2 :           else if (cxx_dialect < cxx20)
    3736                 :           1 :             inform (location, "C++20 %qE only available with %<-fmodules-ts%>",
    3737                 :             :                     id);
    3738                 :             :           else
    3739                 :           1 :             inform (location, "C++20 %qE only available with %<-fmodules-ts%>"
    3740                 :             :                     ", which is not yet enabled with %<-std=c++20%>", id);
    3741                 :             :         }
    3742                 :         471 :       else if (cxx_dialect < cxx11
    3743                 :         118 :                && TREE_CODE (id) == IDENTIFIER_NODE
    3744                 :         589 :                && id_equal (id, "thread_local"))
    3745                 :           0 :         inform (location, "C++11 %<thread_local%> only available with "
    3746                 :             :                 "%<-std=c++11%> or %<-std=gnu++11%>");
    3747                 :         471 :       else if (cxx_dialect < cxx20 && id == ridpointers[(int)RID_CONSTINIT])
    3748                 :           4 :         inform (location, "C++20 %<constinit%> only available with "
    3749                 :             :                 "%<-std=c++20%> or %<-std=gnu++20%>");
    3750                 :         467 :       else if (!flag_concepts && id == ridpointers[(int)RID_CONCEPT])
    3751                 :           9 :         inform (location, "%<concept%> only available with %<-std=c++20%> or "
    3752                 :             :                 "%<-fconcepts%>");
    3753                 :         458 :       else if (!flag_concepts && id == ridpointers[(int)RID_REQUIRES])
    3754                 :           3 :         inform (location, "%<requires%> only available with %<-std=c++20%> or "
    3755                 :             :                 "%<-fconcepts%>");
    3756                 :          66 :       else if (processing_template_decl && current_class_type
    3757                 :         502 :                && TYPE_BINFO (current_class_type))
    3758                 :             :         {
    3759                 :          47 :           for (tree b = TREE_CHAIN (TYPE_BINFO (current_class_type));
    3760                 :          55 :                b; b = TREE_CHAIN (b))
    3761                 :             :             {
    3762                 :          28 :               tree base_type = BINFO_TYPE (b);
    3763                 :          28 :               if (CLASS_TYPE_P (base_type)
    3764                 :          56 :                   && 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                 :          28 :                   base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
    3770                 :          28 :                   for (tree field = TYPE_FIELDS (base_type);
    3771                 :          84 :                        field; field = DECL_CHAIN (field))
    3772                 :          76 :                     if (TREE_CODE (field) == TYPE_DECL
    3773                 :          76 :                         && DECL_NAME (field) == id)
    3774                 :             :                       {
    3775                 :          40 :                         inform (location,
    3776                 :             :                                 "(perhaps %<typename %T::%E%> was intended)",
    3777                 :          20 :                                 BINFO_TYPE (b), id);
    3778                 :          20 :                         goto found;
    3779                 :             :                       }
    3780                 :             :                 }
    3781                 :             :             }
    3782                 :         493 :         found:;
    3783                 :             :         }
    3784                 :         493 :     }
    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                 :         347 :   else if (parser->scope != error_mark_node)
    3788                 :             :     {
    3789                 :         312 :       if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
    3790                 :             :         {
    3791                 :         127 :           auto_diagnostic_group d;
    3792                 :         127 :           name_hint hint;
    3793                 :         127 :           if (decl == error_mark_node)
    3794                 :         208 :             hint = suggest_alternative_in_explicit_scope (location, id,
    3795                 :         104 :                                                           parser->scope);
    3796                 :         127 :           const char *suggestion = hint.suggestion ();
    3797                 :         127 :           gcc_rich_location richloc (location_of (id));
    3798                 :         127 :           if (suggestion)
    3799                 :           5 :             richloc.add_fixit_replace (suggestion);
    3800                 :         127 :           if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
    3801                 :             :             {
    3802                 :          61 :               if (suggestion)
    3803                 :           0 :                 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                 :          61 :                 error_at (&richloc,
    3809                 :             :                           "%qE in namespace %qE does not name a template type",
    3810                 :             :                           id, parser->scope);
    3811                 :             :             }
    3812                 :          66 :           else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
    3813                 :             :             {
    3814                 :           0 :               if (suggestion)
    3815                 :           0 :                 error_at (&richloc,
    3816                 :             :                           "%qE in namespace %qE does not name a template"
    3817                 :             :                           " type; did you mean %qs?",
    3818                 :           0 :                           TREE_OPERAND (id, 0), parser->scope, suggestion);
    3819                 :             :               else
    3820                 :           0 :                 error_at (&richloc,
    3821                 :             :                           "%qE in namespace %qE does not name a template"
    3822                 :             :                           " type",
    3823                 :           0 :                           TREE_OPERAND (id, 0), parser->scope);
    3824                 :             :             }
    3825                 :             :           else
    3826                 :             :             {
    3827                 :          66 :               if (suggestion)
    3828                 :           5 :                 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                 :          61 :                 error_at (&richloc,
    3834                 :             :                           "%qE in namespace %qE does not name a type",
    3835                 :             :                           id, parser->scope);
    3836                 :             :             }
    3837                 :         127 :           if (DECL_P (decl))
    3838                 :          19 :             inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
    3839                 :         127 :         }
    3840                 :         141 :       else if (CLASS_TYPE_P (parser->scope)
    3841                 :         326 :                && constructor_name_p (id, parser->scope))
    3842                 :             :         {
    3843                 :             :           /* A<T>::A<T>() */
    3844                 :          20 :           auto_diagnostic_group d;
    3845                 :          20 :           error_at (location, "%<%T::%E%> names the constructor, not"
    3846                 :             :                     " the type", parser->scope, id);
    3847                 :          20 :           if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
    3848                 :          16 :             error_at (location, "and %qT has no template constructors",
    3849                 :             :                       parser->scope);
    3850                 :          20 :         }
    3851                 :         165 :       else if (TYPE_P (parser->scope)
    3852                 :         165 :                && dependent_scope_p (parser->scope))
    3853                 :             :         {
    3854                 :          81 :           gcc_rich_location richloc (location);
    3855                 :          81 :           richloc.add_fixit_insert_before ("typename ");
    3856                 :          81 :           if (TREE_CODE (parser->scope) == TYPENAME_TYPE)
    3857                 :           9 :             error_at (&richloc,
    3858                 :             :                       "need %<typename%> before %<%T::%D::%E%> because "
    3859                 :             :                       "%<%T::%D%> is a dependent scope",
    3860                 :           9 :                       TYPE_CONTEXT (parser->scope),
    3861                 :           9 :                       TYPENAME_TYPE_FULLNAME (parser->scope),
    3862                 :             :                       id,
    3863                 :           9 :                       TYPE_CONTEXT (parser->scope),
    3864                 :           9 :                       TYPENAME_TYPE_FULLNAME (parser->scope));
    3865                 :             :           else
    3866                 :          72 :             error_at (&richloc, "need %<typename%> before %<%T::%E%> because "
    3867                 :             :                       "%qT is a dependent scope",
    3868                 :             :                       parser->scope, id, parser->scope);
    3869                 :          81 :         }
    3870                 :          84 :       else if (TYPE_P (parser->scope))
    3871                 :             :         {
    3872                 :          84 :           auto_diagnostic_group d;
    3873                 :          84 :           if (!COMPLETE_TYPE_P (parser->scope))
    3874                 :          24 :             cxx_incomplete_type_error (location_of (id), NULL_TREE,
    3875                 :             :                                        parser->scope);
    3876                 :          60 :           else if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
    3877                 :          11 :             error_at (location_of (id),
    3878                 :             :                       "%qE in %q#T does not name a template type",
    3879                 :             :                       id, parser->scope);
    3880                 :          49 :           else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
    3881                 :           0 :             error_at (location_of (id),
    3882                 :             :                       "%qE in %q#T does not name a template type",
    3883                 :           0 :                       TREE_OPERAND (id, 0), parser->scope);
    3884                 :             :           else
    3885                 :          49 :             error_at (location_of (id),
    3886                 :             :                       "%qE in %q#T does not name a type",
    3887                 :             :                       id, parser->scope);
    3888                 :          84 :           if (DECL_P (decl))
    3889                 :           4 :             inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
    3890                 :          84 :         }
    3891                 :             :       else
    3892                 :           0 :         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                 :             : 
    3906                 :             : static bool
    3907                 :    24217184 : cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
    3908                 :             : {
    3909                 :    24217184 :   tree id;
    3910                 :    24217184 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
    3911                 :             : 
    3912                 :             :   /* Avoid duplicate error about ambiguous lookup.  */
    3913                 :    24217184 :   if (token->type == CPP_NESTED_NAME_SPECIFIER)
    3914                 :             :     {
    3915                 :      917912 :       cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2);
    3916                 :      917912 :       if (next->type == CPP_NAME && next->error_reported)
    3917                 :           0 :         goto out;
    3918                 :             :     }
    3919                 :             : 
    3920                 :    24217184 :   cp_parser_parse_tentatively (parser);
    3921                 :    24217184 :   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                 :    24217184 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
    3930                 :    24217184 :       || TREE_CODE (id) == TYPE_DECL)
    3931                 :             :     {
    3932                 :    24215629 :       cp_parser_abort_tentative_parse (parser);
    3933                 :    24215629 :       return false;
    3934                 :             :     }
    3935                 :        1555 :   if (!cp_parser_parse_definitely (parser))
    3936                 :             :     return false;
    3937                 :             : 
    3938                 :             :   /* Emit a diagnostic for the invalid type.  */
    3939                 :         811 :   cp_parser_diagnose_invalid_type_name (parser, id, token->location);
    3940                 :         811 :  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                 :         811 :   if (!parser->in_declarator_p)
    3945                 :         669 :     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                 :             : 
    3954                 :             : static int
    3955                 :   109709232 : cp_parser_skip_to_closing_parenthesis_1 (cp_parser *parser,
    3956                 :             :                                          bool recovering,
    3957                 :             :                                          cpp_ttype or_ttype,
    3958                 :             :                                          bool consume_paren)
    3959                 :             : {
    3960                 :   109709232 :   unsigned paren_depth = 0;
    3961                 :   109709232 :   unsigned brace_depth = 0;
    3962                 :   109709232 :   unsigned square_depth = 0;
    3963                 :   109709232 :   unsigned condop_depth = 0;
    3964                 :             : 
    3965                 :   219418464 :   if (recovering && or_ttype == CPP_EOF
    3966                 :   219418464 :       && cp_parser_uncommitted_to_tentative_parse_p (parser))
    3967                 :             :     return 0;
    3968                 :             : 
    3969                 :  1027326781 :   while (true)
    3970                 :             :     {
    3971                 :  1027326781 :       cp_token * token = cp_lexer_peek_token (parser->lexer);
    3972                 :             : 
    3973                 :             :       /* Have we found what we're looking for before the closing paren?  */
    3974                 :  1027326781 :       if (token->type == or_ttype && or_ttype != CPP_EOF
    3975                 :     5286463 :           && !brace_depth && !paren_depth && !square_depth && !condop_depth)
    3976                 :             :         return -1;
    3977                 :             : 
    3978                 :  1022083502 :       switch (token->type)
    3979                 :             :         {
    3980                 :         288 :         case CPP_PRAGMA_EOL:
    3981                 :         288 :           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                 :     5081807 :         case CPP_OPEN_SQUARE:
    3990                 :     5081807 :           ++square_depth;
    3991                 :     5081807 :           break;
    3992                 :     5081870 :         case CPP_CLOSE_SQUARE:
    3993                 :     5081870 :           if (!square_depth--)
    3994                 :             :             return 0;
    3995                 :             :           break;
    3996                 :             : 
    3997                 :     6338357 :         case CPP_SEMICOLON:
    3998                 :             :           /* This matches the processing in skip_to_end_of_statement.  */
    3999                 :     6338357 :           if (!brace_depth)
    4000                 :             :             return 0;
    4001                 :             :           break;
    4002                 :             : 
    4003                 :      448903 :         case CPP_OPEN_BRACE:
    4004                 :      448903 :           ++brace_depth;
    4005                 :      448903 :           break;
    4006                 :      448947 :         case CPP_CLOSE_BRACE:
    4007                 :      448947 :           if (!brace_depth--)
    4008                 :             :             return 0;
    4009                 :             :           break;
    4010                 :             : 
    4011                 :   129304692 :         case CPP_OPEN_PAREN:
    4012                 :   129304692 :           if (!brace_depth)
    4013                 :   128279189 :             ++paren_depth;
    4014                 :             :           break;
    4015                 :             : 
    4016                 :   228538789 :         case CPP_CLOSE_PAREN:
    4017                 :   228538789 :           if (!brace_depth && !paren_depth--)
    4018                 :             :             {
    4019                 :    99234097 :               if (consume_paren)
    4020                 :    61622193 :                 cp_lexer_consume_token (parser->lexer);
    4021                 :    99234097 :               return 1;
    4022                 :             :             }
    4023                 :             :           break;
    4024                 :             : 
    4025                 :     3714568 :         case CPP_QUERY:
    4026                 :     3714568 :           if (!brace_depth && !paren_depth && !square_depth)
    4027                 :     2668188 :             ++condop_depth;
    4028                 :             :           break;
    4029                 :             : 
    4030                 :     3914659 :         case CPP_COLON:
    4031                 :     3914659 :           if (!brace_depth && !paren_depth && !square_depth && condop_depth > 0)
    4032                 :     2668172 :             condop_depth--;
    4033                 :             :           break;
    4034                 :             : 
    4035                 :    42070162 :         case CPP_KEYWORD:
    4036                 :    42070162 :           if (!cp_token_is_module_directive (token))
    4037                 :             :             break;
    4038                 :             :           /* FALLTHROUGH  */
    4039                 :             : 
    4040                 :          16 :         case CPP_PRAGMA:
    4041                 :             :           /* We fell into a pragma.  Skip it, and continue. */
    4042                 :          32 :           cp_parser_skip_to_pragma_eol (parser, recovering ? token : nullptr);
    4043                 :          16 :           continue;
    4044                 :             : 
    4045                 :             :         default:
    4046                 :             :           break;
    4047                 :             :         }
    4048                 :             : 
    4049                 :             :       /* Consume the token.  */
    4050                 :   917617569 :       cp_lexer_consume_token (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                 :             : 
    4059                 :             : static int
    4060                 :    61623059 : cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
    4061                 :             :                                        bool recovering,
    4062                 :             :                                        bool or_comma,
    4063                 :             :                                        bool consume_paren)
    4064                 :             : {
    4065                 :           0 :   cpp_ttype ttype = or_comma ? CPP_COMMA : CPP_EOF;
    4066                 :           0 :   return cp_parser_skip_to_closing_parenthesis_1 (parser, recovering,
    4067                 :         573 :                                                   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                 :             : 
    4074                 :             : static void
    4075                 :        3786 : cp_parser_skip_to_end_of_statement (cp_parser* parser)
    4076                 :             : {
    4077                 :        3786 :   unsigned nesting_depth = 0;
    4078                 :             : 
    4079                 :             :   /* Unwind generic function template scope if necessary.  */
    4080                 :        3786 :   if (parser->fully_implicit_function_template_p)
    4081                 :           6 :     abort_fully_implicit_template (parser);
    4082                 :             : 
    4083                 :       10102 :   while (true)
    4084                 :             :     {
    4085                 :       10102 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
    4086                 :             : 
    4087                 :       10102 :       switch (token->type)
    4088                 :             :         {
    4089                 :           0 :         case CPP_PRAGMA_EOL:
    4090                 :           0 :           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                 :        3105 :         case CPP_SEMICOLON:
    4098                 :             :           /* If the next token is a `;', we have reached the end of the
    4099                 :             :              statement.  */
    4100                 :        3105 :           if (!nesting_depth)
    4101                 :             :             return;
    4102                 :             :           break;
    4103                 :             : 
    4104                 :         457 :         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                 :         457 :           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                 :         405 :           if (--nesting_depth == 0)
    4126                 :             :             {
    4127                 :         390 :               cp_lexer_consume_token (parser->lexer);
    4128                 :         390 :               return;
    4129                 :             :             }
    4130                 :             :           break;
    4131                 :             : 
    4132                 :         408 :         case CPP_OPEN_BRACE:
    4133                 :         408 :           ++nesting_depth;
    4134                 :         408 :           break;
    4135                 :             : 
    4136                 :        1056 :         case CPP_KEYWORD:
    4137                 :        1056 :           if (!cp_token_is_module_directive (token))
    4138                 :             :             break;
    4139                 :             :           /* FALLTHROUGH  */
    4140                 :             : 
    4141                 :          35 :         case CPP_PRAGMA:
    4142                 :             :           /* We fell into a pragma.  Skip it, and continue or return. */
    4143                 :          35 :           cp_parser_skip_to_pragma_eol (parser, token);
    4144                 :          35 :           if (!nesting_depth)
    4145                 :             :             return;
    4146                 :          12 :           continue;
    4147                 :             : 
    4148                 :             :         default:
    4149                 :             :           break;
    4150                 :             :         }
    4151                 :             : 
    4152                 :             :       /* Consume the token.  */
    4153                 :        6304 :       cp_lexer_consume_token (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                 :             : 
    4161                 :             : static void
    4162                 :    95961130 : cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser)
    4163                 :             : {
    4164                 :             :   /* Look for the trailing `;'.  */
    4165                 :    95961130 :   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                 :         163 :       cp_parser_skip_to_end_of_statement (parser);
    4170                 :             :       /* If the next token is now a `;', consume it.  */
    4171                 :         163 :       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    4172                 :         119 :         cp_lexer_consume_token (parser->lexer);
    4173                 :             :     }
    4174                 :    95961130 : }
    4175                 :             : 
    4176                 :             : /* Skip tokens until we have consumed an entire block, or until we
    4177                 :             :    have consumed a non-nested `;'.  */
    4178                 :             : 
    4179                 :             : static void
    4180                 :       16074 : cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
    4181                 :             : {
    4182                 :       16074 :   int nesting_depth = 0;
    4183                 :             : 
    4184                 :             :   /* Unwind generic function template scope if necessary.  */
    4185                 :       16074 :   if (parser->fully_implicit_function_template_p)
    4186                 :          16 :     abort_fully_implicit_template (parser);
    4187                 :             : 
    4188                 :       40868 :   while (nesting_depth >= 0)
    4189                 :             :     {
    4190                 :       25055 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
    4191                 :             : 
    4192                 :       25055 :       switch (token->type)
    4193                 :             :         {
    4194                 :           0 :         case CPP_PRAGMA_EOL:
    4195                 :           0 :           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                 :       15094 :         case CPP_SEMICOLON:
    4203                 :             :           /* Stop if this is an unnested ';'. */
    4204                 :       15094 :           if (!nesting_depth)
    4205                 :       15813 :             nesting_depth = -1;
    4206                 :             :           break;
    4207                 :             : 
    4208                 :        1440 :         case CPP_CLOSE_BRACE:
    4209                 :             :           /* Stop if this is an unnested '}', or closes the outermost
    4210                 :             :              nesting level.  */
    4211                 :        1440 :           nesting_depth--;
    4212                 :        1440 :           if (nesting_depth < 0)
    4213                 :             :             return;
    4214                 :        1285 :           if (!nesting_depth)
    4215                 :       15813 :             nesting_depth = -1;
    4216                 :             :           break;
    4217                 :             : 
    4218                 :        1293 :         case CPP_OPEN_BRACE:
    4219                 :             :           /* Nest. */
    4220                 :        1293 :           nesting_depth++;
    4221                 :        1293 :           break;
    4222                 :             : 
    4223                 :        1077 :         case CPP_KEYWORD:
    4224                 :        1077 :           if (!cp_token_is_module_directive (token))
    4225                 :             :             break;
    4226                 :             :           /* FALLTHROUGH  */
    4227                 :             : 
    4228                 :          19 :         case CPP_PRAGMA:
    4229                 :             :           /* Skip it, and continue or return. */
    4230                 :          19 :           cp_parser_skip_to_pragma_eol (parser, token);
    4231                 :          19 :           if (!nesting_depth)
    4232                 :             :             return;
    4233                 :           0 :           continue;
    4234                 :             : 
    4235                 :             :         default:
    4236                 :             :           break;
    4237                 :             :         }
    4238                 :             : 
    4239                 :             :       /* Consume the token.  */
    4240                 :       24794 :       cp_lexer_consume_token (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                 :             : 
    4248                 :             : static bool
    4249                 :         197 : cp_parser_skip_to_closing_brace (cp_parser *parser)
    4250                 :             : {
    4251                 :         197 :   unsigned nesting_depth = 0;
    4252                 :             : 
    4253                 :         893 :   while (true)
    4254                 :             :     {
    4255                 :         545 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
    4256                 :             : 
    4257                 :         545 :       switch (token->type)
    4258                 :             :         {
    4259                 :           8 :         case CPP_PRAGMA_EOL:
    4260                 :           8 :           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                 :         182 :         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                 :         182 :           if (nesting_depth-- == 0)
    4271                 :             :             return true;
    4272                 :             :           break;
    4273                 :             : 
    4274                 :           1 :         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                 :           1 :           ++nesting_depth;
    4278                 :           1 :           break;
    4279                 :             : 
    4280                 :             :         default:
    4281                 :             :           break;
    4282                 :             :         }
    4283                 :             : 
    4284                 :             :       /* Consume the token.  */
    4285                 :         348 :       cp_lexer_consume_token (parser->lexer);
    4286                 :         348 :     }
    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                 :             : 
    4294                 :             : static void
    4295                 :     1927018 : cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok)
    4296                 :             : {
    4297                 :     1931301 :   cp_token *token;
    4298                 :             : 
    4299                 :     1931301 :   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                 :     1931301 :       gcc_checking_assert (cp_lexer_next_token_is_not (parser->lexer, CPP_EOF));
    4306                 :     1931301 :       token = cp_lexer_consume_token (parser->lexer);
    4307                 :             :     }
    4308                 :     1931301 :   while (token->type != CPP_PRAGMA_EOL);
    4309                 :             : 
    4310                 :     1927018 :   if (pragma_tok)
    4311                 :             :     {
    4312                 :     1927002 :       parser->lexer->in_pragma = false;
    4313                 :     1927002 :       if (parser->lexer->in_omp_attribute_pragma
    4314                 :     1927002 :           && cp_lexer_next_token_is (parser->lexer, CPP_EOF))
    4315                 :             :         {
    4316                 :        1206 :           parser->lexer = parser->lexer->next;
    4317                 :             :           /* Put the current source position back where it was before this
    4318                 :             :              lexer was pushed.  */
    4319                 :        1206 :           cp_lexer_set_source_position_from_token (parser->lexer->next_token);
    4320                 :             :         }
    4321                 :             :     }
    4322                 :     1927018 : }
    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                 :             : 
    4327                 :             : static void
    4328                 :       16078 : cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
    4329                 :             : {
    4330                 :       16078 :   parser->lexer->in_pragma = false;
    4331                 :       16078 :   if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL))
    4332                 :         165 :     cp_parser_skip_to_pragma_eol (parser, pragma_tok);
    4333                 :       15913 :   else if (parser->lexer->in_omp_attribute_pragma
    4334                 :       15913 :            && cp_lexer_next_token_is (parser->lexer, CPP_EOF))
    4335                 :             :     {
    4336                 :         477 :       parser->lexer = parser->lexer->next;
    4337                 :             :       /* Put the current source position back where it was before this
    4338                 :             :          lexer was pushed.  */
    4339                 :         477 :       cp_lexer_set_source_position_from_token (parser->lexer->next_token);
    4340                 :             :     }
    4341                 :       16078 : }
    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                 :             : 
    4347                 :             : static tree
    4348                 :    26358576 : cp_parser_make_typename_type (cp_parser *parser, tree id,
    4349                 :             :                               location_t id_location)
    4350                 :             : {
    4351                 :    26358576 :   tree result;
    4352                 :    26358576 :   if (identifier_p (id))
    4353                 :             :     {
    4354                 :    26358566 :       result = make_typename_type (parser->scope, id, typename_type,
    4355                 :             :                                    /*complain=*/tf_none);
    4356                 :    26358566 :       if (result == error_mark_node)
    4357                 :          23 :         cp_parser_diagnose_invalid_type_name (parser, id, id_location);
    4358                 :    26358566 :       return result;
    4359                 :             :     }
    4360                 :          10 :   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                 :             : 
    4370                 :             : static cp_declarator *
    4371                 :   166549935 : cp_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                 :   166549935 :   if (code == ERROR_MARK || target == cp_error_declarator)
    4377                 :          56 :     return cp_error_declarator;
    4378                 :             : 
    4379                 :   166549879 :   if (code == INDIRECT_REF)
    4380                 :    58721042 :     if (class_type == NULL_TREE)
    4381                 :    57609444 :       return make_pointer_declarator (cv_qualifiers, target, attributes);
    4382                 :             :     else
    4383                 :     1111598 :       return make_ptrmem_declarator (cv_qualifiers, class_type,
    4384                 :     1111598 :                                      target, attributes);
    4385                 :   107828837 :   else if (code == ADDR_EXPR && class_type == NULL_TREE)
    4386                 :    92080071 :     return make_reference_declarator (cv_qualifiers, target,
    4387                 :    92080071 :                                       false, attributes);
    4388                 :    15748766 :   else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE)
    4389                 :    15748766 :     return make_reference_declarator (cv_qualifiers, target,
    4390                 :    15748766 :                                       true, attributes);
    4391                 :           0 :   gcc_unreachable ();
    4392                 :             : }
    4393                 :             : 
    4394                 :             : /* Create a new C++ parser.  */
    4395                 :             : 
    4396                 :             : static cp_parser *
    4397                 :      101044 : cp_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                 :     2222968 :   for (unsigned i = 0; i < ARRAY_SIZE (binops); i++)
    4402                 :     2121924 :     binops_by_token[binops[i].token_type] = binops[i];
    4403                 :             : 
    4404                 :      101044 :   cp_parser *parser = ggc_cleared_alloc<cp_parser> ();
    4405                 :      101044 :   parser->lexer = lexer;
    4406                 :      101044 :   parser->context = cp_parser_context_new (NULL);
    4407                 :             : 
    4408                 :             :   /* For now, we always accept GNU extensions.  */
    4409                 :      101044 :   parser->allow_gnu_extensions_p = 1;
    4410                 :             : 
    4411                 :             :   /* The `>' token is a greater-than operator, not the end of a
    4412                 :             :      template-id.  */
    4413                 :      101044 :   parser->greater_than_is_operator_p = true;
    4414                 :             : 
    4415                 :      101044 :   parser->default_arg_ok_p = true;
    4416                 :             : 
    4417                 :             :   /* We are not parsing a constant-expression.  */
    4418                 :      101044 :   parser->integral_constant_expression_p = false;
    4419                 :      101044 :   parser->allow_non_integral_constant_expression_p = false;
    4420                 :      101044 :   parser->non_integral_constant_expression_p = false;
    4421                 :             : 
    4422                 :             :   /* Local variable names are not forbidden.  */
    4423                 :      101044 :   parser->local_variables_forbidden_p = 0;
    4424                 :             : 
    4425                 :             :   /* We are not processing an `extern "C"' declaration.  */
    4426                 :      101044 :   parser->in_unbraced_linkage_specification_p = false;
    4427                 :             : 
    4428                 :             :   /* We are not processing a declarator.  */
    4429                 :      101044 :   parser->in_declarator_p = false;
    4430                 :             : 
    4431                 :             :   /* We are not processing a template-argument-list.  */
    4432                 :      101044 :   parser->in_template_argument_list_p = false;
    4433                 :             : 
    4434                 :             :   /* We are not in an iteration statement.  */
    4435                 :      101044 :   parser->in_statement = 0;
    4436                 :             : 
    4437                 :             :   /* We are not in a switch statement.  */
    4438                 :      101044 :   parser->in_switch_statement_p = false;
    4439                 :             : 
    4440                 :             :   /* We are not parsing a type-id inside an expression.  */
    4441                 :      101044 :   parser->in_type_id_in_expr_p = false;
    4442                 :             : 
    4443                 :             :   /* String literals should be translated to the execution character set.  */
    4444                 :      101044 :   parser->translate_strings_p = true;
    4445                 :             : 
    4446                 :             :   /* We are not parsing a function body.  */
    4447                 :      101044 :   parser->in_function_body = false;
    4448                 :             : 
    4449                 :             :   /* We can correct until told otherwise.  */
    4450                 :      101044 :   parser->colon_corrects_to_scope_p = true;
    4451                 :             : 
    4452                 :             :   /* The unparsed function queue is empty.  */
    4453                 :      101044 :   push_unparsed_function_queues (parser);
    4454                 :             : 
    4455                 :             :   /* There are no classes being defined.  */
    4456                 :      101044 :   parser->num_classes_being_defined = 0;
    4457                 :             : 
    4458                 :             :   /* No template parameters apply.  */
    4459                 :      101044 :   parser->num_template_parameter_lists = 0;
    4460                 :             : 
    4461                 :             :   /* Special parsing data structures.  */
    4462                 :      101044 :   parser->omp_declare_simd = NULL;
    4463                 :      101044 :   parser->oacc_routine = NULL;
    4464                 :             : 
    4465                 :             :   /* Disallow OpenMP array sections in expressions.  */
    4466                 :      101044 :   parser->omp_array_section_p = false;
    4467                 :             : 
    4468                 :             :   /* Not declaring an implicit function template.  */
    4469                 :      101044 :   parser->auto_is_implicit_function_template_parm_p = false;
    4470                 :      101044 :   parser->fully_implicit_function_template_p = false;
    4471                 :      101044 :   parser->implicit_template_parms = 0;
    4472                 :      101044 :   parser->implicit_template_scope = 0;
    4473                 :             : 
    4474                 :             :   /* Allow constrained-type-specifiers. */
    4475                 :      101044 :   parser->prevent_constrained_type_specifiers = 0;
    4476                 :             : 
    4477                 :             :   /* We haven't yet seen an 'extern "C"'.  */
    4478                 :      101044 :   parser->innermost_linkage_specification_location = UNKNOWN_LOCATION;
    4479                 :             : 
    4480                 :      101044 :   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.  */
    4487                 :             : static void
    4488                 :    70323044 : cp_parser_push_lexer_for_tokens (cp_parser *parser, cp_token_cache *cache)
    4489                 :             : {
    4490                 :    70323044 :   cp_lexer *lexer = cp_lexer_new_from_tokens (cache);
    4491                 :    70323044 :   lexer->next = parser->lexer;
    4492                 :    70323044 :   parser->lexer = lexer;
    4493                 :             : 
    4494                 :             :   /* Move the current source position to that of the first token in the
    4495                 :             :      new lexer.  */
    4496                 :    70323044 :   cp_lexer_set_source_position_from_token (lexer->next_token);
    4497                 :    70323044 : }
    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.  */
    4501                 :             : static void
    4502                 :    70323044 : cp_parser_pop_lexer (cp_parser *parser)
    4503                 :             : {
    4504                 :    70323044 :   cp_lexer *lexer = parser->lexer;
    4505                 :    70323044 :   parser->lexer = lexer->next;
    4506                 :    70323044 :   cp_lexer_destroy (lexer);
    4507                 :             : 
    4508                 :             :   /* Put the current source position back where it was before this
    4509                 :             :      lexer was pushed.  */
    4510                 :    70323044 :   cp_lexer_set_source_position_from_token (parser->lexer->next_token);
    4511                 :    70323044 : }
    4512                 :             : 
    4513                 :             : /* Lexical conventions [gram.lex]  */
    4514                 :             : 
    4515                 :             : /* Parse an identifier.  Returns an IDENTIFIER_NODE representing the
    4516                 :             :    identifier.  */
    4517                 :             : 
    4518                 :             : static cp_expr
    4519                 :  5862671839 : cp_parser_identifier (cp_parser* parser)
    4520                 :             : {
    4521                 :  5862671839 :   cp_token *token;
    4522                 :             : 
    4523                 :             :   /* Look for the identifier.  */
    4524                 :  5862671839 :   token = cp_parser_require (parser, CPP_NAME, RT_NAME);
    4525                 :             :   /* Return the value.  */
    4526                 :  5862671839 :   if (token)
    4527                 :  4643316850 :     return cp_expr (token->u.value, token->location);
    4528                 :             :   else
    4529                 :  1219354989 :     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                 :             : 
    4553                 :             : static cp_expr
    4554                 :    15792936 : cp_parser_string_literal_common (cp_parser *parser, bool translate,
    4555                 :             :                                  bool wide_ok, bool udl_ok,
    4556                 :             :                                  bool lookup_udlit, bool uneval)
    4557                 :             : {
    4558                 :    15792936 :   tree value;
    4559                 :    15792936 :   size_t count;
    4560                 :    15792936 :   struct obstack str_ob;
    4561                 :    15792936 :   struct obstack loc_ob;
    4562                 :    15792936 :   cpp_string str, istr, *strs;
    4563                 :    15792936 :   cp_token *tok;
    4564                 :    15792936 :   enum cpp_ttype type, curr_type;
    4565                 :    15792936 :   int have_suffix_p = 0;
    4566                 :    15792936 :   tree string_tree;
    4567                 :    15792936 :   tree suffix_id = NULL_TREE;
    4568                 :    15792936 :   bool curr_tok_is_userdef_p = false;
    4569                 :             : 
    4570                 :    15792936 :   tok = cp_lexer_peek_token (parser->lexer);
    4571                 :    15792936 :   if (!cp_parser_is_string_literal (tok))
    4572                 :             :     {
    4573                 :          71 :       cp_parser_error (parser, "expected string-literal");
    4574                 :          71 :       return error_mark_node;
    4575                 :             :     }
    4576                 :             : 
    4577                 :    15792865 :   location_t loc = tok->location;
    4578                 :             : 
    4579                 :    15792865 :   if (cpp_userdef_string_p (tok->type))
    4580                 :             :     {
    4581                 :      527083 :       if (!udl_ok)
    4582                 :             :         {
    4583                 :           3 :           error_at (loc, "string literal with user-defined suffix "
    4584                 :             :                     "is invalid in this context");
    4585                 :           3 :           return error_mark_node;
    4586                 :             :         }
    4587                 :      527080 :       string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
    4588                 :      527080 :       curr_type = cpp_userdef_string_remove_type (tok->type);
    4589                 :      527080 :       curr_tok_is_userdef_p = true;
    4590                 :             :     }
    4591                 :             :   else
    4592                 :             :     {
    4593                 :    15265782 :       string_tree = tok->u.value;
    4594                 :    15265782 :       curr_type = tok->type;
    4595                 :             :     }
    4596                 :    15792862 :   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                 :    31585724 :   if (!cp_parser_is_string_literal
    4601                 :    15792862 :       (cp_lexer_peek_nth_token (parser->lexer, 2)))
    4602                 :             :     {
    4603                 :    13896231 :       cp_lexer_consume_token (parser->lexer);
    4604                 :             : 
    4605                 :    13896231 :       str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
    4606                 :    13896231 :       str.len = TREE_STRING_LENGTH (string_tree);
    4607                 :    13896231 :       count = 1;
    4608                 :             : 
    4609                 :    13896231 :       if (curr_tok_is_userdef_p)
    4610                 :             :         {
    4611                 :      527059 :           suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
    4612                 :      527059 :           have_suffix_p = 1;
    4613                 :      527059 :           curr_type = cpp_userdef_string_remove_type (tok->type);
    4614                 :             :         }
    4615                 :             :       else
    4616                 :    15792859 :         curr_type = tok->type;
    4617                 :             : 
    4618                 :             :       strs = &str;
    4619                 :             :     }
    4620                 :             :   else
    4621                 :             :     {
    4622                 :     1896631 :       location_t last_tok_loc = tok->location;
    4623                 :     1896631 :       gcc_obstack_init (&str_ob);
    4624                 :     1896631 :       gcc_obstack_init (&loc_ob);
    4625                 :     1896631 :       count = 0;
    4626                 :             : 
    4627                 :     5098836 :       do
    4628                 :             :         {
    4629                 :     5098836 :           cp_lexer_consume_token (parser->lexer);
    4630                 :     5098836 :           count++;
    4631                 :     5098836 :           str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
    4632                 :     5098836 :           str.len = TREE_STRING_LENGTH (string_tree);
    4633                 :             : 
    4634                 :     5098836 :           if (curr_tok_is_userdef_p)
    4635                 :             :             {
    4636                 :          57 :               tree curr_suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
    4637                 :          57 :               if (have_suffix_p == 0)
    4638                 :             :                 {
    4639                 :             :                   suffix_id = curr_suffix_id;
    4640                 :             :                   have_suffix_p = 1;
    4641                 :             :                 }
    4642                 :          15 :               else if (have_suffix_p == 1
    4643                 :          15 :                        && curr_suffix_id != suffix_id)
    4644                 :             :                 {
    4645                 :           9 :                   error ("inconsistent user-defined literal suffixes"
    4646                 :             :                          " %qD and %qD in string literal",
    4647                 :             :                          suffix_id, curr_suffix_id);
    4648                 :           9 :                   have_suffix_p = -1;
    4649                 :             :                 }
    4650                 :          57 :               curr_type = cpp_userdef_string_remove_type (tok->type);
    4651                 :             :             }
    4652                 :             :           else
    4653                 :     5098779 :             curr_type = tok->type;
    4654                 :             : 
    4655                 :     5098836 :           if (type != curr_type)
    4656                 :             :             {
    4657                 :       12213 :               if (type == CPP_STRING)
    4658                 :             :                 type = curr_type;
    4659                 :       12078 :               else if (curr_type != CPP_STRING)
    4660                 :             :                 {
    4661                 :          78 :                   rich_location rich_loc (line_table, tok->location);
    4662                 :          78 :                   rich_loc.add_range (last_tok_loc);
    4663                 :          78 :                   error_at (&rich_loc,
    4664                 :             :                             "concatenation of string literals with "
    4665                 :             :                             "conflicting encoding prefixes");
    4666                 :          78 :                 }
    4667                 :             :             }
    4668                 :             : 
    4669                 :     5098836 :           obstack_grow (&str_ob, &str, sizeof (cpp_string));
    4670                 :     5098836 :           obstack_grow (&loc_ob, &tok->location, sizeof (location_t));
    4671                 :             : 
    4672                 :     5098836 :           last_tok_loc = tok->location;
    4673                 :             : 
    4674                 :     5098836 :           tok = cp_lexer_peek_token (parser->lexer);
    4675                 :     5098836 :           if (cpp_userdef_string_p (tok->type))
    4676                 :             :             {
    4677                 :          39 :               if (!udl_ok)
    4678                 :             :                 {
    4679                 :           3 :                   error_at (loc, "string literal with user-defined suffix "
    4680                 :             :                             "is invalid in this context");
    4681                 :           3 :                   return error_mark_node;
    4682                 :             :                 }
    4683                 :          36 :               string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
    4684                 :          36 :               curr_type = cpp_userdef_string_remove_type (tok->type);
    4685                 :          36 :               curr_tok_is_userdef_p = true;
    4686                 :             :             }
    4687                 :             :           else
    4688                 :             :             {
    4689                 :     5098797 :               string_tree = tok->u.value;
    4690                 :     5098797 :               curr_type = tok->type;
    4691                 :     5098797 :               curr_tok_is_userdef_p = false;
    4692                 :             :             }
    4693                 :             :         }
    4694                 :     5098833 :       while (cp_parser_is_string_literal (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                 :     1896628 :       loc = make_location (loc, loc, get_finish (last_tok_loc));
    4700                 :             : 
    4701                 :     1896628 :       strs = (cpp_string *) obstack_finish (&str_ob);
    4702                 :             :     }
    4703                 :             : 
    4704                 :    15792859 :   if (type != CPP_STRING && !wide_ok)
    4705                 :             :     {
    4706                 :          68 :       cp_parser_error (parser, "a wide string is invalid in this context");
    4707                 :          68 :       type = CPP_STRING;
    4708                 :             :     }
    4709                 :    15792859 :   if (uneval)
    4710                 :      442673 :     type = CPP_UNEVAL_STRING;
    4711                 :             : 
    4712                 :    31585718 :   if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate)
    4713                 :    15792859 :       (parse_in, strs, count, &istr, type))
    4714                 :             :     {
    4715                 :    15792856 :       value = build_string (istr.len, (const char *)istr.text);
    4716                 :    15792856 :       free (CONST_CAST (unsigned char *, istr.text));
    4717                 :    15792856 :       if (count > 1)
    4718                 :             :         {
    4719                 :     1896628 :           location_t *locs = (location_t *)obstack_finish (&loc_ob);
    4720                 :     1896628 :           gcc_assert (g_string_concat_db);
    4721                 :     1896628 :           g_string_concat_db->record_string_concatenation (count, locs);
    4722                 :             :         }
    4723                 :             : 
    4724                 :    15792856 :       switch (type)
    4725                 :             :         {
    4726                 :    15675994 :         default:
    4727                 :    15675994 :         case CPP_STRING:
    4728                 :    15675994 :           TREE_TYPE (value) = char_array_type_node;
    4729                 :    15675994 :           break;
    4730                 :         607 :         case CPP_UTF8STRING:
    4731                 :         607 :           if (flag_char8_t)
    4732                 :         218 :             TREE_TYPE (value) = char8_array_type_node;
    4733                 :             :           else
    4734                 :         389 :             TREE_TYPE (value) = char_array_type_node;
    4735                 :             :           break;
    4736                 :         622 :         case CPP_STRING16:
    4737                 :         622 :           TREE_TYPE (value) = char16_array_type_node;
    4738                 :         622 :           break;
    4739                 :         673 :         case CPP_STRING32:
    4740                 :         673 :           TREE_TYPE (value) = char32_array_type_node;
    4741                 :         673 :           break;
    4742                 :      114960 :         case CPP_WSTRING:
    4743                 :      114960 :           TREE_TYPE (value) = wchar_array_type_node;
    4744                 :      114960 :           break;
    4745                 :             :         }
    4746                 :             : 
    4747                 :    15792856 :       value = fix_string_type (value);
    4748                 :             : 
    4749                 :    15792856 :       if (have_suffix_p)
    4750                 :             :         {
    4751                 :      527101 :           tree literal = build_userdef_literal (suffix_id, value,
    4752                 :             :                                                 OT_NONE, NULL_TREE);
    4753                 :      527101 :           if (lookup_udlit)
    4754                 :         855 :             value = finish_userdef_string_literal (literal);
    4755                 :             :           else
    4756                 :             :             value = literal;
    4757                 :             :         }
    4758                 :             :     }
    4759                 :             :   else
    4760                 :             :     /* cpp_interpret_string has issued an error.  */
    4761                 :           3 :     value = error_mark_node;
    4762                 :             : 
    4763                 :    15792859 :   if (count > 1)
    4764                 :             :     {
    4765                 :     1896628 :       obstack_free (&str_ob, 0);
    4766                 :     1896628 :       obstack_free (&loc_ob, 0);
    4767                 :             :     }
    4768                 :             : 
    4769                 :    15792859 :   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                 :             : 
    4780                 :             : static inline cp_expr
    4781                 :     9386346 : cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
    4782                 :             : {
    4783                 :     9386346 :   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                 :             : 
    4796                 :             : static inline cp_expr
    4797                 :     5963917 : cp_parser_userdef_string_literal (cp_parser *parser, bool lookup_udlit)
    4798                 :             : {
    4799                 :     5963917 :   return cp_parser_string_literal_common (parser, /*translate=*/true,
    4800                 :             :                                           /*wide_ok=*/true, /*udl_ok=*/true,
    4801                 :     5963917 :                                           lookup_udlit, /*uneval=*/false);
    4802                 :             : }
    4803                 :             : 
    4804                 :             : /* Parse an unevaluated string literal.
    4805                 :             : 
    4806                 :             :    unevaluated-string:
    4807                 :             :      string-literal  */
    4808                 :             : 
    4809                 :             : static inline cp_expr
    4810                 :      442673 : cp_parser_unevaluated_string_literal (cp_parser *parser)
    4811                 :             : {
    4812                 :      442673 :   return cp_parser_string_literal_common (parser, /*translate=*/false,
    4813                 :             :                                           /*wide_ok=*/false, /*udl_ok=*/false,
    4814                 :             :                                           /*lookup_udlit=*/false,
    4815                 :      442673 :                                           /*uneval=*/true);
    4816                 :             : }
    4817                 :             : 
    4818                 :             : /* Look up a literal operator with the name and the exact arguments.  */
    4819                 :             : 
    4820                 :             : static tree
    4821                 :      248474 : lookup_literal_operator (tree name, vec<tree, va_gc> *args)
    4822                 :             : {
    4823                 :      248474 :   tree decl = lookup_name (name);
    4824                 :      248474 :   if (!decl || !is_overloaded_fn (decl))
    4825                 :       95076 :     return error_mark_node;
    4826                 :             : 
    4827                 :      582278 :   for (lkp_iterator iter (decl); iter; ++iter)
    4828                 :             :     {
    4829                 :      483812 :       tree fn = *iter;
    4830                 :             : 
    4831                 :      483812 :       if (tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn)))
    4832                 :             :         {
    4833                 :             :           unsigned int ix;
    4834                 :             :           bool found = true;
    4835                 :             : 
    4836                 :             :           for (ix = 0;
    4837                 :     1368962 :                found && ix < vec_safe_length (args) && parmtypes != NULL_TREE;
    4838                 :      377573 :                ++ix, parmtypes = TREE_CHAIN (parmtypes))
    4839                 :             :             {
    4840                 :      377573 :               tree tparm = TREE_VALUE (parmtypes);
    4841                 :      377573 :               tree targ = TREE_TYPE ((*args)[ix]);
    4842                 :      377573 :               bool ptr = TYPE_PTR_P (tparm);
    4843                 :      377573 :               bool arr = TREE_CODE (targ) == ARRAY_TYPE;
    4844                 :      104151 :               if ((ptr || arr || !same_type_p (tparm, targ))
    4845                 :      475967 :                   && (!ptr || !arr
    4846                 :       88745 :                       || !same_type_p (TREE_TYPE (tparm),
    4847                 :             :                                        TREE_TYPE (targ))))
    4848                 :             :                 found = false;
    4849                 :             :             }
    4850                 :             : 
    4851                 :      483812 :           if (found
    4852                 :      130004 :               && ix == vec_safe_length (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                 :      613816 :               && parmtypes == void_list_node)
    4858                 :       54932 :             return decl;
    4859                 :             :         }
    4860                 :             :     }
    4861                 :             : 
    4862                 :       98466 :   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                 :             : 
    4868                 :             : static cp_expr
    4869                 :         101 : cp_parser_userdef_char_literal (cp_parser *parser)
    4870                 :             : {
    4871                 :         101 :   cp_token *token = cp_lexer_consume_token (parser->lexer);
    4872                 :         101 :   tree literal = token->u.value;
    4873                 :         101 :   tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
    4874                 :         101 :   tree value = USERDEF_LITERAL_VALUE (literal);
    4875                 :         101 :   tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
    4876                 :         101 :   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                 :         101 :   releasing_vec args;
    4881                 :         101 :   vec_safe_push (args, value);
    4882                 :         101 :   decl = lookup_literal_operator (name, args);
    4883                 :         101 :   if (!decl || decl == error_mark_node)
    4884                 :             :     {
    4885                 :          62 :       error ("unable to find character literal operator %qD with %qT argument",
    4886                 :          62 :              name, TREE_TYPE (value));
    4887                 :          62 :       return error_mark_node;
    4888                 :             :     }
    4889                 :          39 :   result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
    4890                 :          39 :   return result;
    4891                 :         101 : }
    4892                 :             : 
    4893                 :             : /* A subroutine of cp_parser_userdef_numeric_literal to
    4894                 :             :    create a char... template parameter pack from a string node.  */
    4895                 :             : 
    4896                 :             : static tree
    4897                 :       49075 : make_char_string_pack (tree value)
    4898                 :             : {
    4899                 :       49075 :   tree charvec;
    4900                 :       49075 :   tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
    4901                 :       49075 :   const unsigned char *str
    4902                 :       49075 :     = (const unsigned char *) TREE_STRING_POINTER (value);
    4903                 :       49075 :   int i, len = TREE_STRING_LENGTH (value) - 1;
    4904                 :       49075 :   tree argvec = make_tree_vec (1);
    4905                 :             : 
    4906                 :             :   /* Fill in CHARVEC with all of the parameters.  */
    4907                 :       49075 :   charvec = make_tree_vec (len);
    4908                 :      203275 :   for (i = 0; i < len; ++i)
    4909                 :             :     {
    4910                 :      154200 :       unsigned char s[3] = { '\'', str[i], '\'' };
    4911                 :      154200 :       cpp_string in = { 3, s };
    4912                 :      154200 :       cpp_string out = { 0, 0 };
    4913                 :      154200 :       if (!cpp_interpret_string (parse_in, &in, 1, &out, CPP_STRING))
    4914                 :           0 :         return NULL_TREE;
    4915                 :      154200 :       gcc_assert (out.len == 2);
    4916                 :      154200 :       TREE_VEC_ELT (charvec, i) = build_int_cst (char_type_node,
    4917                 :      154200 :                                                  out.text[0]);
    4918                 :             :     }
    4919                 :             : 
    4920                 :             :   /* Build the argument packs.  */
    4921                 :       49075 :   ARGUMENT_PACK_ARGS (argpack) = charvec;
    4922                 :             : 
    4923                 :       49075 :   TREE_VEC_ELT (argvec, 0) = argpack;
    4924                 :             : 
    4925                 :       49075 :   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                 :             : 
    4931                 :             : static tree
    4932                 :          61 : make_string_pack (tree value)
    4933                 :             : {
    4934                 :          61 :   tree charvec;
    4935                 :          61 :   tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
    4936                 :          61 :   const unsigned char *str
    4937                 :          61 :     = (const unsigned char *) TREE_STRING_POINTER (value);
    4938                 :          61 :   int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value))));
    4939                 :          61 :   int len = TREE_STRING_LENGTH (value) / sz - 1;
    4940                 :          61 :   tree argvec = make_tree_vec (2);
    4941                 :             : 
    4942                 :          61 :   tree str_char_type_node = TREE_TYPE (TREE_TYPE (value));
    4943                 :          61 :   str_char_type_node = TYPE_MAIN_VARIANT (str_char_type_node);
    4944                 :             : 
    4945                 :             :   /* First template parm is character type.  */
    4946                 :          61 :   TREE_VEC_ELT (argvec, 0) = str_char_type_node;
    4947                 :             : 
    4948                 :             :   /* Fill in CHARVEC with all of the parameters.  */
    4949                 :          61 :   charvec = make_tree_vec (len);
    4950                 :         242 :   for (int i = 0; i < len; ++i)
    4951                 :         181 :     TREE_VEC_ELT (charvec, i)
    4952                 :         362 :       = double_int_to_tree (str_char_type_node,
    4953                 :         181 :                             double_int::from_buffer (str + i * sz, sz));
    4954                 :             : 
    4955                 :             :   /* Build the argument packs.  */
    4956                 :          61 :   ARGUMENT_PACK_ARGS (argpack) = charvec;
    4957                 :             : 
    4958                 :          61 :   TREE_VEC_ELT (argvec, 1) = argpack;
    4959                 :             : 
    4960                 :          61 :   return argvec;
    4961                 :             : }
    4962                 :             : 
    4963                 :             : /* Parse a user-defined numeric constant.  returns a call to a user-defined
    4964                 :             :    literal operator.  */
    4965                 :             : 
    4966                 :             : static cp_expr
    4967                 :       85808 : cp_parser_userdef_numeric_literal (cp_parser *parser)
    4968                 :             : {
    4969                 :       85808 :   cp_token *token = cp_lexer_consume_token (parser->lexer);
    4970                 :       85808 :   tree literal = token->u.value;
    4971                 :       85808 :   tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
    4972                 :       85808 :   tree value = USERDEF_LITERAL_VALUE (literal);
    4973                 :       85808 :   int overflow = USERDEF_LITERAL_OVERFLOW (literal);
    4974                 :       85808 :   tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
    4975                 :       85808 :   tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
    4976                 :       85808 :   tree decl, result;
    4977                 :             : 
    4978                 :             :   /* Look for a literal operator taking the exact type of numeric argument
    4979                 :             :      as the literal value.  */
    4980                 :       85808 :   releasing_vec args;
    4981                 :       85808 :   vec_safe_push (args, value);
    4982                 :       85808 :   decl = lookup_literal_operator (name, args);
    4983                 :       85808 :   if (decl && decl != error_mark_node)
    4984                 :             :     {
    4985                 :        5007 :       result = finish_call_expr (decl, &args, false, true,
    4986                 :             :                                  tf_warning_or_error);
    4987                 :             : 
    4988                 :        5007 :       if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0)
    4989                 :             :         {
    4990                 :           3 :           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                 :        5004 :           if (overflow > 0)
    4997                 :           3 :             warning_at (token->location, OPT_Woverflow,
    4998                 :             :                         "floating literal exceeds range of %qT type",
    4999                 :             :                         long_double_type_node);
    5000                 :        5001 :           else if (overflow < 0)
    5001                 :           3 :             warning_at (token->location, OPT_Woverflow,
    5002                 :             :                         "floating literal truncated to zero");
    5003                 :             :         }
    5004                 :             : 
    5005                 :        5007 :       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                 :       80801 :   args->truncate (0);
    5012                 :       80801 :   vec_safe_push (args, num_string);
    5013                 :       80801 :   decl = lookup_literal_operator (name, args);
    5014                 :       80801 :   if (decl && decl != error_mark_node)
    5015                 :             :     {
    5016                 :          36 :       result = finish_call_expr (decl, &args, false, true,
    5017                 :             :                                  tf_warning_or_error);
    5018                 :          36 :       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                 :       80765 :   args->truncate (0);
    5025                 :       80765 :   decl = lookup_literal_operator (name, args);
    5026                 :       80765 :   if (decl && decl != error_mark_node)
    5027                 :             :     {
    5028                 :       49075 :       tree tmpl_args = make_char_string_pack (num_string);
    5029                 :       49075 :       if (tmpl_args == NULL_TREE)
    5030                 :             :         {
    5031                 :           0 :           error ("failed to translate literal to execution character set %qT",
    5032                 :             :                  num_string);
    5033                 :           0 :           return error_mark_node;
    5034                 :             :         }
    5035                 :       49075 :       decl = lookup_template_function (decl, tmpl_args);
    5036                 :       49075 :       result = finish_call_expr (decl, &args, false, true,
    5037                 :             :                                  tf_warning_or_error);
    5038                 :       49075 :       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                 :       31690 :   bool ext = cpp_get_options (parse_in)->ext_numeric_literals;
    5044                 :       31690 :   bool i14 = (cxx_dialect > cxx11
    5045                 :       31690 :               && (id_equal (suffix_id, "i")
    5046                 :       21084 :                   || id_equal (suffix_id, "if")
    5047                 :       10573 :                   || id_equal (suffix_id, "il")));
    5048                 :       31690 :   diagnostic_t kind = DK_ERROR;
    5049                 :       31690 :   int opt = 0;
    5050                 :             : 
    5051                 :       31690 :   if (i14 && ext)
    5052                 :             :     {
    5053                 :       31631 :       tree cxlit = lookup_qualified_name (std_node, "complex_literals",
    5054                 :             :                                           LOOK_want::NORMAL, false);
    5055                 :       31631 :       if (cxlit == error_mark_node)
    5056                 :             :         {
    5057                 :             :           /* No <complex>, so pedwarn and use GNU semantics.  */
    5058                 :       31690 :           kind = DK_PEDWARN;
    5059                 :       31690 :           opt = OPT_Wpedantic;
    5060                 :             :         }
    5061                 :             :     }
    5062                 :             : 
    5063                 :       31690 :   bool complained
    5064                 :       31690 :     = emit_diagnostic (kind, input_location, opt,
    5065                 :             :                        "unable to find numeric literal operator %qD", name);
    5066                 :             : 
    5067                 :       31690 :   if (!complained)
    5068                 :             :     /* Don't inform either.  */;
    5069                 :          74 :   else if (i14)
    5070                 :             :     {
    5071                 :          21 :       inform (token->location, "add %<using namespace std::complex_literals%> "
    5072                 :             :               "(from %<<complex>%>) to enable the C++14 user-defined literal "
    5073                 :             :               "suffixes");
    5074                 :          21 :       if (ext)
    5075                 :          15 :         inform (token->location, "or use %<j%> instead of %<i%> for the "
    5076                 :             :                 "GNU built-in suffix");
    5077                 :             :     }
    5078                 :          53 :   else if (!ext)
    5079                 :          44 :     inform (token->location, "use %<-fext-numeric-literals%> "
    5080                 :             :             "to enable more built-in suffixes");
    5081                 :             : 
    5082                 :       31690 :   if (kind == DK_ERROR)
    5083                 :          62 :     value = error_mark_node;
    5084                 :             :   else
    5085                 :             :     {
    5086                 :             :       /* Use the built-in semantics.  */
    5087                 :       31628 :       tree type;
    5088                 :       31628 :       if (id_equal (suffix_id, "i"))
    5089                 :             :         {
    5090                 :       10591 :           if (TREE_CODE (value) == INTEGER_CST)
    5091                 :          49 :             type = integer_type_node;
    5092                 :             :           else
    5093                 :       10542 :             type = double_type_node;
    5094                 :             :         }
    5095                 :       21037 :       else if (id_equal (suffix_id, "if"))
    5096                 :       10511 :         type = float_type_node;
    5097                 :             :       else /* if (id_equal (suffix_id, "il")) */
    5098                 :       10526 :         type = long_double_type_node;
    5099                 :             : 
    5100                 :       31628 :       value = fold_build2 (COMPLEX_EXPR, build_complex_type (type),
    5101                 :             :                            build_zero_cst (type), fold_convert (type, value));
    5102                 :             :     }
    5103                 :             : 
    5104                 :       63414 :   if (cp_parser_uncommitted_to_tentative_parse_p (parser))
    5105                 :             :     /* Avoid repeated diagnostics.  */
    5106                 :          34 :     token->u.value = value;
    5107                 :       31690 :   return value;
    5108                 :       85808 : }
    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                 :             : 
    5114                 :             : static tree
    5115                 :         855 : finish_userdef_string_literal (tree literal)
    5116                 :             : {
    5117                 :         855 :   tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
    5118                 :         855 :   tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
    5119                 :         855 :   tree value = USERDEF_LITERAL_VALUE (literal);
    5120                 :         855 :   int len = TREE_STRING_LENGTH (value)
    5121                 :         855 :         / TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
    5122                 :         855 :   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                 :         855 :   releasing_vec args;
    5127                 :         855 :   vec_safe_push (args, value);
    5128                 :         855 :   vec_safe_push (args, build_int_cst (size_type_node, len));
    5129                 :         855 :   decl = lookup_literal_operator (name, args);
    5130                 :             : 
    5131                 :         855 :   if (decl && decl != error_mark_node)
    5132                 :         711 :     return finish_call_expr (decl, &args, false, true,
    5133                 :         711 :                              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                 :         144 :   args->truncate (0);
    5139                 :         144 :   decl = lookup_literal_operator (name, args);
    5140                 :         144 :   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                 :          64 :       tree tmpl_args = make_tree_vec (1);
    5145                 :          64 :       TREE_VEC_ELT (tmpl_args, 0) = value;
    5146                 :          64 :       decl = lookup_template_function (decl, tmpl_args);
    5147                 :          64 :       tree res = resolve_nondeduced_context (decl, tf_none);
    5148                 :          64 :       if (DECL_P (res))
    5149                 :             :         decl = res;
    5150                 :             :       else
    5151                 :             :         {
    5152                 :          61 :           TREE_OPERAND (decl, 1) = make_string_pack (value);
    5153                 :          61 :           res = resolve_nondeduced_context (decl, tf_none);
    5154                 :          61 :           if (DECL_P (res))
    5155                 :          57 :             decl = res;
    5156                 :             :         }
    5157                 :          64 :       if (!DECL_P (decl) && cxx_dialect > cxx17)
    5158                 :           2 :         TREE_OPERAND (decl, 1) = tmpl_args;
    5159                 :          64 :       return finish_call_expr (decl, &args, false, true,
    5160                 :          64 :                                tf_warning_or_error);
    5161                 :             :     }
    5162                 :             : 
    5163                 :          80 :   error ("unable to find string literal operator %qD with %qT, %qT arguments",
    5164                 :          80 :          name, TREE_TYPE (value), size_type_node);
    5165                 :          80 :   return error_mark_node;
    5166                 :         855 : }
    5167                 :             : 
    5168                 :             : 
    5169                 :             : /* Basic concepts [gram.basic]  */
    5170                 :             : 
    5171                 :             : /* Parse a translation-unit.
    5172                 :             : 
    5173                 :             :    translation-unit:
    5174                 :             :      declaration-seq [opt]  */
    5175                 :             : 
    5176                 :             : static void
    5177                 :       99853 : cp_parser_translation_unit (cp_parser* parser)
    5178                 :             : {
    5179                 :       99853 :   gcc_checking_assert (!cp_error_declarator);
    5180                 :             : 
    5181                 :             :   /* Create the declarator obstack.  */
    5182                 :       99853 :   gcc_obstack_init (&declarator_obstack);
    5183                 :             :   /* Create the error declarator.  */
    5184                 :       99853 :   cp_error_declarator = make_declarator (cdk_error);
    5185                 :             :   /* Create the empty parameter list.  */
    5186                 :       99853 :   no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE,
    5187                 :             :                                              UNKNOWN_LOCATION);
    5188                 :             :   /* Remember where the base of the declarator obstack lies.  */
    5189                 :       99853 :   void *declarator_obstack_base = obstack_next_free (&declarator_obstack);
    5190                 :             : 
    5191                 :       99858 :   push_deferring_access_checks (flag_access_control
    5192                 :             :                                 ? dk_no_deferred : dk_no_check);
    5193                 :             : 
    5194                 :       99853 :   module_parse mp_state = MP_NOT_MODULE;
    5195                 :       99853 :   if (modules_p () && !header_module_p ())
    5196                 :             :     mp_state = MP_FIRST;
    5197                 :             : 
    5198                 :             :   bool implicit_extern_c = false;
    5199                 :             : 
    5200                 :             :   /* Parse until EOF.  */
    5201                 :     7376606 :   for (;;)
    5202                 :             :     {
    5203                 :     7376606 :       cp_token *token = cp_lexer_peek_token (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                 :     7376606 :       if (implicit_extern_c
    5209                 :     7376606 :           != cp_lexer_peek_token (parser->lexer)->implicit_extern_c)
    5210                 :             :         {
    5211                 :           0 :           implicit_extern_c = !implicit_extern_c;
    5212                 :           0 :           if (implicit_extern_c)
    5213                 :           0 :             push_lang_context (lang_name_c);
    5214                 :             :           else
    5215                 :           0 :             pop_lang_context ();
    5216                 :             :         }
    5217                 :             : 
    5218                 :     7376606 :       if (token->type == CPP_EOF)
    5219                 :             :         break;
    5220                 :             : 
    5221                 :     7276844 :       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                 :       41093 :           cp_token *next = token;
    5228                 :       41093 :           bool exporting = token->keyword == RID__EXPORT;
    5229                 :       41093 :           if (exporting)
    5230                 :             :             {
    5231                 :        1319 :               cp_lexer_consume_token (parser->lexer);
    5232                 :        1319 :               next = cp_lexer_peek_token (parser->lexer);
    5233                 :             :             }
    5234                 :       41093 :           if (next->keyword == RID__MODULE)
    5235                 :             :             {
    5236                 :        1630 :               mp_state
    5237                 :        1630 :                 = cp_parser_module_declaration (parser, mp_state, exporting);
    5238                 :        1630 :               continue;
    5239                 :             :             }
    5240                 :       39463 :           else if (next->keyword == RID__IMPORT)
    5241                 :             :             {
    5242                 :        1685 :               if (mp_state == MP_FIRST)
    5243                 :         810 :                 mp_state = MP_NOT_MODULE;
    5244                 :        1685 :               cp_parser_import_declaration (parser, mp_state, exporting);
    5245                 :        1657 :               continue;
    5246                 :             :             }
    5247                 :             :           else
    5248                 :       37778 :             gcc_checking_assert (!exporting);
    5249                 :             : 
    5250                 :       37778 :           if (mp_state == MP_GLOBAL && token->main_source_p)
    5251                 :             :             {
    5252                 :          27 :               static bool warned = false;
    5253                 :          27 :               if (!warned)
    5254                 :             :                 {
    5255                 :          12 :                   warned = true;
    5256                 :          12 :                   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                 :     7273529 :       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                 :        1216 :         mp_state = module_parse (mp_state + 1);
    5267                 :     7272313 :       else if (mp_state == MP_FIRST)
    5268                 :         264 :         mp_state = MP_NOT_MODULE;
    5269                 :             : 
    5270                 :     7273529 :       if (token->type == CPP_CLOSE_BRACE)
    5271                 :             :         {
    5272                 :          94 :           cp_parser_error (parser, "expected declaration");
    5273                 :          94 :           cp_lexer_consume_token (parser->lexer);
    5274                 :             :           /* If the next token is now a `;', consume it.  */
    5275                 :          94 :           if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    5276                 :          23 :             cp_lexer_consume_token (parser->lexer);
    5277                 :             :         }
    5278                 :             :       else
    5279                 :     7273435 :         cp_parser_toplevel_declaration (parser);
    5280                 :             :     }
    5281                 :             : 
    5282                 :             :   /* Get rid of the token array; we don't need it any more.  */
    5283                 :       99762 :   cp_lexer_destroy (parser->lexer);
    5284                 :       99762 :   parser->lexer = NULL;
    5285                 :             : 
    5286                 :             :   /* The EOF should have reset this. */
    5287                 :       99762 :   gcc_checking_assert (!implicit_extern_c);
    5288                 :             : 
    5289                 :             :   /* Make sure the declarator obstack was fully cleaned up.  */
    5290                 :       99762 :   gcc_assert (obstack_next_free (&declarator_obstack)
    5291                 :             :               == declarator_obstack_base);
    5292                 :       99762 : }
    5293                 :             : 
    5294                 :             : /* Return the appropriate tsubst flags for parsing, possibly in N3276
    5295                 :             :    decltype context.  */
    5296                 :             : 
    5297                 :             : static inline tsubst_flags_t
    5298                 :   393015041 : complain_flags (bool decltype_p)
    5299                 :             : {
    5300                 :   393015041 :   tsubst_flags_t complain = tf_warning_or_error;
    5301                 :   393015041 :   if (decltype_p)
    5302                 :     4451552 :     complain |= tf_decltype;
    5303                 :   393015041 :   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                 :             : 
    5310                 :             : static cp_token_position
    5311                 :      558684 : cp_parser_start_tentative_firewall (cp_parser *parser)
    5312                 :             : {
    5313                 :     1130577 :   if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
    5314                 :             :     return 0;
    5315                 :             : 
    5316                 :       13209 :   cp_parser_parse_tentatively (parser);
    5317                 :       13209 :   cp_parser_commit_to_topmost_tentative_parse (parser);
    5318                 :       13209 :   return cp_lexer_token_position (parser->lexer, 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                 :             : 
    5324                 :             : static void
    5325                 :      558684 : cp_parser_end_tentative_firewall (cp_parser *parser, cp_token_position start,
    5326                 :             :                                   tree expr)
    5327                 :             : {
    5328                 :      558684 :   if (!start)
    5329                 :             :     return;
    5330                 :             : 
    5331                 :             :   /* Finish the firewall level.  */
    5332                 :       13209 :   cp_parser_parse_definitely (parser);
    5333                 :             :   /* And remember the result of the parse for when we try again.  */
    5334                 :       13209 :   cp_token *token = cp_lexer_token_at (parser->lexer, start);
    5335                 :       13209 :   token->type = CPP_PREPARSED_EXPR;
    5336                 :       13209 :   token->u.value = expr;
    5337                 :       13209 :   token->keyword = RID_MAX;
    5338                 :       13209 :   cp_lexer_purge_tokens_after (parser->lexer, 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                 :             : 
    5346                 :             : struct tentative_firewall
    5347                 :             : {
    5348                 :             :   cp_parser *parser;
    5349                 :             :   bool set;
    5350                 :             : 
    5351                 :   197909587 :   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                 :   197909587 :     if ((set = cp_parser_uncommitted_to_tentative_parse_p (parser)))
    5356                 :             :       {
    5357                 :   192284539 :         cp_parser_parse_tentatively (parser);
    5358                 :   192284539 :         cp_parser_commit_to_topmost_tentative_parse (parser);
    5359                 :   192284539 :         cp_parser_parse_tentatively (parser);
    5360                 :             :       }
    5361                 :   197909587 :   }
    5362                 :             : 
    5363                 :   197909584 :   ~tentative_firewall()
    5364                 :             :   {
    5365                 :   197909584 :     if (set)
    5366                 :             :       {
    5367                 :             :         /* Finish the inner tentative parse and the firewall, propagating any
    5368                 :             :            uncommitted error state to the outer tentative parse.  */
    5369                 :   384569072 :         bool err = cp_parser_error_occurred (parser);
    5370                 :   192284536 :         cp_parser_parse_definitely (parser);
    5371                 :   192284536 :         cp_parser_parse_definitely (parser);
    5372                 :   192284536 :         if (err)
    5373                 :   209430777 :           cp_parser_simulate_error (parser);
    5374                 :             :       }
    5375                 :   197909584 :   }
    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                 :             : 
    5385                 :             : template <typename traits_t>
    5386                 :             : class token_pair
    5387                 :             : {
    5388                 :             :  public:
    5389                 :             :   /* token_pair's ctor.  */
    5390                 :   895798051 :   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                 :   599173240 :   bool require_open (cp_parser *parser)
    5398                 :             :   {
    5399                 :   599173240 :     m_open_loc = cp_lexer_peek_token (parser->lexer)->location;
    5400                 :   599173240 :     return cp_parser_require (parser, traits_t::open_token_type,
    5401                 :   599173240 :                               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                 :   296613134 :   cp_token * consume_open (cp_parser *parser)
    5408                 :             :   {
    5409                 :   296613134 :     cp_token *tok = cp_lexer_consume_token (parser->lexer);
    5410                 :   296613134 :     gcc_assert (tok->type == traits_t::open_token_type);
    5411                 :   296613134 :     m_open_loc = tok->location;
    5412                 :   296613134 :     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                 :   767647398 :   cp_token *require_close (cp_parser *parser) const
    5421                 :             :   {
    5422                 :   767647398 :     return cp_parser_require (parser, traits_t::close_token_type,
    5423                 :             :                               traits_t::required_token_close,
    5424                 :   360274165 :                               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                 :             : 
    5435                 :             : struct 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                 :             : 
    5446                 :             : typedef token_pair<matching_paren_traits> matching_parens;
    5447                 :             : 
    5448                 :             : /* Traits for token_pair<T> for tracking matching pairs of braces.  */
    5449                 :             : 
    5450                 :             : struct 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                 :             : 
    5461                 :             : typedef 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                 :             : 
    5467                 :             : static cp_expr
    5468                 :       29974 : cp_parser_statement_expr (cp_parser *parser)
    5469                 :             : {
    5470                 :       29974 :   cp_token_position start = cp_parser_start_tentative_firewall (parser);
    5471                 :       29974 :   auto oas = make_temp_override (parser->omp_array_section_p, false);
    5472                 :             : 
    5473                 :             :   /* Consume the '('.  */
    5474                 :       29974 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
    5475                 :       29974 :   matching_parens parens;
    5476                 :       29974 :   parens.consume_open (parser);
    5477                 :             :   /* Start the statement-expression.  */
    5478                 :       29974 :   tree expr = begin_stmt_expr ();
    5479                 :             :   /* Parse the compound-statement.  */
    5480                 :       29974 :   cp_parser_compound_statement (parser, expr, BCS_STMT_EXPR, false);
    5481                 :             :   /* Finish up.  */
    5482                 :       29974 :   expr = finish_stmt_expr (expr, false);
    5483                 :             :   /* Consume the ')'.  */
    5484                 :       29974 :   location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
    5485                 :       29974 :   if (!parens.require_close (parser))
    5486                 :           0 :     cp_parser_skip_to_end_of_statement (parser);
    5487                 :             : 
    5488                 :       29974 :   cp_parser_end_tentative_firewall (parser, start, expr);
    5489                 :       29974 :   location_t combined_loc = make_location (start_loc, start_loc, finish_loc);
    5490                 :       29974 :   return cp_expr (expr, combined_loc);
    5491                 :       29974 : }
    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                 :             : 
    5507                 :             : static int
    5508                 :    26724803 : cp_parser_fold_operator (cp_token *token)
    5509                 :             : {
    5510                 :    26251884 :   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                 :             : 
    5558                 :             : static bool
    5559                 :      447694 : is_binary_op (tree_code code)
    5560                 :             : {
    5561                 :      447694 :   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                 :      447634 :     default:
    5594                 :      447634 :       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                 :             : 
    5601                 :             : static int
    5602                 :      472919 : cp_parser_fold_operator (cp_parser *parser)
    5603                 :             : {
    5604                 :      472919 :   cp_token* token = cp_lexer_peek_token (parser->lexer);
    5605                 :      472919 :   int code = cp_parser_fold_operator (token);
    5606                 :      472919 :   if (code != ERROR_MARK)
    5607                 :      472919 :     cp_lexer_consume_token (parser->lexer);
    5608                 :      472919 :   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                 :             : 
    5620                 :             : static cp_expr
    5621                 :      472925 : cp_parser_fold_expression (cp_parser *parser, tree expr1)
    5622                 :             : {
    5623                 :      472925 :   cp_id_kind pidk;
    5624                 :      472925 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
    5625                 :      472925 :   const cp_token *token = nullptr;
    5626                 :             : 
    5627                 :             :   // Left fold.
    5628                 :      472925 :   if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    5629                 :             :     {
    5630                 :         508 :       if (expr1)
    5631                 :           6 :         return error_mark_node;
    5632                 :         502 :       cp_lexer_consume_token (parser->lexer);
    5633                 :         502 :       token = cp_lexer_peek_token (parser->lexer);
    5634                 :         502 :       int op = cp_parser_fold_operator (parser);
    5635                 :         502 :       if (op == ERROR_MARK)
    5636                 :             :         {
    5637                 :           0 :           cp_parser_error (parser, "expected binary operator");
    5638                 :           0 :           return error_mark_node;
    5639                 :             :         }
    5640                 :             : 
    5641                 :         502 :       tree expr = cp_parser_cast_expression (parser, false, false,
    5642                 :             :                                              false, &pidk);
    5643                 :         502 :       if (expr == error_mark_node)
    5644                 :           0 :         return error_mark_node;
    5645                 :         502 :       loc = make_location (token->location, loc, parser->lexer);
    5646                 :         502 :       return finish_left_unary_fold_expr (loc, expr, op);
    5647                 :             :     }
    5648                 :             : 
    5649                 :      472417 :   token = cp_lexer_peek_token (parser->lexer);
    5650                 :      472417 :   int op = cp_parser_fold_operator (parser);
    5651                 :      472417 :   if (op == ERROR_MARK)
    5652                 :             :     {
    5653                 :           0 :       cp_parser_error (parser, "expected binary operator");
    5654                 :           0 :       return error_mark_node;
    5655                 :             :     }
    5656                 :             : 
    5657                 :      472417 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS))
    5658                 :             :     {
    5659                 :           0 :       cp_parser_error (parser, "expected ...");
    5660                 :           0 :       return error_mark_node;
    5661                 :             :     }
    5662                 :      472417 :   cp_lexer_consume_token (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                 :      472417 :   if (EXPR_P (expr1) && warning_suppressed_p (expr1, OPT_Wparentheses))
    5668                 :             :     /* OK, the expression was parenthesized.  */;
    5669                 :      447694 :   else if (is_binary_op (TREE_CODE (expr1)))
    5670                 :          60 :     error_at (location_of (expr1),
    5671                 :             :               "binary expression in operand of fold-expression");
    5672                 :      447634 :   else if (TREE_CODE (expr1) == COND_EXPR
    5673                 :      447634 :            || (REFERENCE_REF_P (expr1)
    5674                 :           0 :                && TREE_CODE (TREE_OPERAND (expr1, 0)) == COND_EXPR))
    5675                 :           2 :     error_at (location_of (expr1),
    5676                 :             :               "conditional expression in operand of fold-expression");
    5677                 :             : 
    5678                 :             :   // Right fold.
    5679                 :      472417 :   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
    5680                 :             :     {
    5681                 :      461271 :       loc = make_location (token->location, loc, parser->lexer);
    5682                 :      461271 :       return finish_right_unary_fold_expr (loc, expr1, op);
    5683                 :             :     }
    5684                 :             : 
    5685                 :       11146 :   if (cp_lexer_next_token_is_not (parser->lexer, token->type))
    5686                 :             :     {
    5687                 :           0 :       cp_parser_error (parser, "mismatched operator in fold-expression");
    5688                 :           0 :       return error_mark_node;
    5689                 :             :     }
    5690                 :       11146 :   cp_lexer_consume_token (parser->lexer);
    5691                 :             : 
    5692                 :             :   // Binary left or right fold.
    5693                 :       11146 :   tree expr2 = cp_parser_cast_expression (parser, false, false, false, &pidk);
    5694                 :       11146 :   if (expr2 == error_mark_node)
    5695                 :           0 :     return error_mark_node;
    5696                 :       11146 :   loc = make_location (token->location, loc, parser->lexer);
    5697                 :       11146 :   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                 :             : 
    5754                 :             : static cp_expr
    5755                 :   794294499 : cp_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                 :   794294499 :   cp_token *token = NULL;
    5763                 :             : 
    5764                 :             :   /* Assume the primary expression is not an id-expression.  */
    5765                 :   794294499 :   *idk = CP_ID_KIND_NONE;
    5766                 :             : 
    5767                 :             :   /* Peek at the next token.  */
    5768                 :   794294499 :   token = cp_lexer_peek_token (parser->lexer);
    5769                 :   794294499 :   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                 :    91582983 :     case CPP_CHAR:
    5780                 :    91582983 :     case CPP_CHAR16:
    5781                 :    91582983 :     case CPP_CHAR32:
    5782                 :    91582983 :     case CPP_WCHAR:
    5783                 :    91582983 :     case CPP_UTF8CHAR:
    5784                 :    91582983 :     case CPP_NUMBER:
    5785                 :    91582983 :     case CPP_PREPARSED_EXPR:
    5786                 :    91582983 :       if (TREE_CODE (token->u.value) == USERDEF_LITERAL)
    5787                 :       85808 :         return cp_parser_userdef_numeric_literal (parser);
    5788                 :    91497175 :       token = cp_lexer_consume_token (parser->lexer);
    5789                 :    91497175 :       if (TREE_CODE (token->u.value) == FIXED_CST)
    5790                 :             :         {
    5791                 :          56 :           error_at (token->location,
    5792                 :             :                     "fixed-point types not supported in C++");
    5793                 :          56 :           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                 :    91497119 :       if ((TREE_CODE (token->u.value) == REAL_CST
    5799                 :    88246121 :            || (TREE_CODE (token->u.value) == EXCESS_PRECISION_EXPR
    5800                 :      196286 :                && TREE_CODE (TREE_OPERAND (token->u.value, 0)) == REAL_CST))
    5801                 :     3447278 :           && parser->integral_constant_expression_p
    5802                 :    93285416 :           && 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                 :       13624 :           if (cast_p)
    5808                 :             :             {
    5809                 :        7118 :               cp_token *next_token;
    5810                 :             : 
    5811                 :        7118 :               next_token = cp_lexer_peek_token (parser->lexer);
    5812                 :        7118 :               if (/* The comma at the end of an
    5813                 :             :                      enumerator-definition.  */
    5814                 :        7118 :                   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                 :           2 :                       || parser->greater_than_is_operator_p)
    5826                 :             :                   /* C++0x only: A ">>" treated like two ">" tokens,
    5827                 :             :                      in a template-argument-list.  */
    5828                 :          28 :                   && (next_token->type != CPP_RSHIFT
    5829                 :           0 :                       || (cxx_dialect == cxx98)
    5830                 :           0 :                       || 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                 :        6534 :             cp_parser_non_integral_constant_expression (parser, NIC_FLOAT);
    5840                 :             :         }
    5841                 :    91497119 :       return (cp_expr (token->u.value, token->location, token->flags & DECIMAL_INT)
    5842                 :    91497119 :               .maybe_add_location_wrapper ());
    5843                 :             : 
    5844                 :         101 :     case CPP_CHAR_USERDEF:
    5845                 :         101 :     case CPP_CHAR16_USERDEF:
    5846                 :         101 :     case CPP_CHAR32_USERDEF:
    5847                 :         101 :     case CPP_WCHAR_USERDEF:
    5848                 :         101 :     case CPP_UTF8CHAR_USERDEF:
    5849                 :         101 :       return cp_parser_userdef_char_literal (parser);
    5850                 :             : 
    5851                 :     8926918 :     case CPP_STRING:
    5852                 :     8926918 :     case CPP_STRING16:
    5853                 :     8926918 :     case CPP_STRING32:
    5854                 :     8926918 :     case CPP_WSTRING:
    5855                 :     8926918 :     case CPP_UTF8STRING:
    5856                 :     8926918 :     case CPP_STRING_USERDEF:
    5857                 :     8926918 :     case CPP_STRING16_USERDEF:
    5858                 :     8926918 :     case CPP_STRING32_USERDEF:
    5859                 :     8926918 :     case CPP_WSTRING_USERDEF:
    5860                 :     8926918 :     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                 :     8926918 :       if (parser->translate_strings_p)
    5865                 :     5435920 :         return (cp_parser_userdef_string_literal (parser,
    5866                 :             :                                                   /*lookup_udlit=*/true)
    5867                 :     5435920 :                 .maybe_add_location_wrapper ());
    5868                 :             :       else
    5869                 :     3490998 :         return (cp_parser_string_literal (parser,
    5870                 :             :                                           /*translate=*/false,
    5871                 :             :                                           /*wide_ok=*/true)
    5872                 :     3490998 :                 .maybe_add_location_wrapper ());
    5873                 :             : 
    5874                 :    26282375 :     case CPP_OPEN_PAREN:
    5875                 :             :       /* If we see `( { ' then we are looking at the beginning of
    5876                 :             :          a GNU statement-expression.  */
    5877                 :    26282375 :       if (cp_parser_allow_gnu_extensions_p (parser)
    5878                 :    26282375 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_BRACE))
    5879                 :             :         {
    5880                 :             :           /* Statement-expressions are not allowed by the standard.  */
    5881                 :       29983 :           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                 :       29983 :           if (!parser->in_function_body
    5891                 :       29978 :               || parser->in_template_argument_list_p)
    5892                 :             :             {
    5893                 :           9 :               error_at (token->location,
    5894                 :             :                         "statement-expressions are not allowed outside "
    5895                 :             :                         "functions nor in template-argument lists");
    5896                 :           9 :               cp_parser_skip_to_end_of_block_or_statement (parser);
    5897                 :           9 :               if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
    5898                 :           9 :                 cp_lexer_consume_token (parser->lexer);
    5899                 :           9 :               return error_mark_node;
    5900                 :             :             }
    5901                 :             :           else
    5902                 :       29974 :             return cp_parser_statement_expr (parser);
    5903                 :             :         }
    5904                 :             :       /* Otherwise it's a normal parenthesized expression.  */
    5905                 :    26252392 :       {
    5906                 :    26252392 :         cp_expr expr;
    5907                 :    26252392 :         bool saved_greater_than_is_operator_p;
    5908                 :             : 
    5909                 :    26252392 :         location_t open_paren_loc = token->location;
    5910                 :             : 
    5911                 :             :         /* Consume the `('.  */
    5912                 :    26252392 :         matching_parens parens;
    5913                 :    26252392 :         parens.consume_open (parser);
    5914                 :             :         /* Within a parenthesized expression, a `>' token is always
    5915                 :             :            the greater-than operator.  */
    5916                 :    26252392 :         saved_greater_than_is_operator_p
    5917                 :    26252392 :           = parser->greater_than_is_operator_p;
    5918                 :    26252392 :         parser->greater_than_is_operator_p = true;
    5919                 :             : 
    5920                 :    26252392 :         if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    5921                 :             :           /* Left fold expression. */
    5922                 :         502 :           expr = NULL_TREE;
    5923                 :             :         else
    5924                 :             :           /* Parse the parenthesized expression.  */
    5925                 :    26251890 :           expr = cp_parser_expression (parser, idk, cast_p, decltype_p);
    5926                 :             : 
    5927                 :    26252392 :         token = cp_lexer_peek_token (parser->lexer);
    5928                 :    52504088 :         if (token->type == CPP_ELLIPSIS || cp_parser_fold_operator (token))
    5929                 :             :           {
    5930                 :      472925 :             expr = cp_parser_fold_expression (parser, expr);
    5931                 :      472925 :             if (expr != error_mark_node
    5932                 :      472925 :                 && cxx_dialect < cxx17)
    5933                 :           1 :               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                 :    25779467 :           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                 :    26252392 :         if (*idk != CP_ID_KIND_QUALIFIED)
    5950                 :    25940808 :           *idk = CP_ID_KIND_NONE;
    5951                 :             : 
    5952                 :             :         /* The `>' token might be the end of a template-id or
    5953                 :             :            template-parameter-list now.  */
    5954                 :    26252392 :         parser->greater_than_is_operator_p
    5955                 :    26252392 :           = saved_greater_than_is_operator_p;
    5956                 :             : 
    5957                 :             :         /* Consume the `)'.  */
    5958                 :    26252392 :         token = cp_lexer_peek_token (parser->lexer);
    5959                 :    26252392 :         location_t close_paren_loc = token->location;
    5960                 :    26252392 :         bool no_wparens = warning_suppressed_p (expr, OPT_Wparentheses);
    5961                 :    26252392 :         expr.set_range (open_paren_loc, close_paren_loc);
    5962                 :    26252392 :         if (no_wparens)
    5963                 :    24253982 :           suppress_warning (expr, OPT_Wparentheses);
    5964                 :    26252392 :         if (!parens.require_close (parser)
    5965                 :    26252392 :             && !cp_parser_uncommitted_to_tentative_parse_p (parser))
    5966                 :         103 :           cp_parser_skip_to_end_of_statement (parser);
    5967                 :             : 
    5968                 :    26252392 :         return expr;
    5969                 :             :       }
    5970                 :             : 
    5971                 :      528715 :     case CPP_OPEN_SQUARE:
    5972                 :      528715 :       {
    5973                 :      528715 :         if (c_dialect_objc ())
    5974                 :             :           {
    5975                 :             :             /* We might have an Objective-C++ message. */
    5976                 :           0 :             cp_parser_parse_tentatively (parser);
    5977                 :           0 :             tree msg = cp_parser_objc_message_expression (parser);
    5978                 :             :             /* If that works out, we're done ... */
    5979                 :           0 :             if (cp_parser_parse_definitely (parser))
    5980                 :           0 :               return msg;
    5981                 :             :             /* ... else, fall though to see if it's a lambda.  */
    5982                 :             :           }
    5983                 :      528715 :         cp_expr lam = cp_parser_lambda_expression (parser);
    5984                 :             :         /* Don't warn about a failed tentative parse.  */
    5985                 :     1057430 :         if (cp_parser_error_occurred (parser))
    5986                 :           5 :           return error_mark_node;
    5987                 :      528710 :         maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR);
    5988                 :      528710 :         return lam;
    5989                 :             :       }
    5990                 :             : 
    5991                 :           0 :     case CPP_OBJC_STRING:
    5992                 :           0 :       if (c_dialect_objc ())
    5993                 :             :         /* We have an Objective-C++ string literal. */
    5994                 :           0 :         return cp_parser_objc_expression (parser);
    5995                 :           0 :       cp_parser_error (parser, "expected primary-expression");
    5996                 :           0 :       return error_mark_node;
    5997                 :             : 
    5998                 :    77980756 :     case CPP_KEYWORD:
    5999                 :    77980756 :       switch (token->keyword)
    6000                 :             :         {
    6001                 :             :           /* These two are the boolean literals.  */
    6002                 :    32122349 :         case RID_TRUE:
    6003                 :    32122349 :           cp_lexer_consume_token (parser->lexer);
    6004                 :    32122349 :           return cp_expr (boolean_true_node, token->location);
    6005                 :    13445293 :         case RID_FALSE:
    6006                 :    13445293 :           cp_lexer_consume_token (parser->lexer);
    6007                 :    13445293 :           return cp_expr (boolean_false_node, token->location);
    6008                 :             : 
    6009                 :             :           /* The `__null' literal.  */
    6010                 :      126504 :         case RID_NULL:
    6011                 :      126504 :           cp_lexer_consume_token (parser->lexer);
    6012                 :      126504 :           return cp_expr (null_node, token->location);
    6013                 :             : 
    6014                 :             :           /* The `nullptr' literal.  */
    6015                 :     2898297 :         case RID_NULLPTR:
    6016                 :     2898297 :           cp_lexer_consume_token (parser->lexer);
    6017                 :     2898297 :           return cp_expr (nullptr_node, token->location);
    6018                 :             : 
    6019                 :             :           /* Recognize the `this' keyword.  */
    6020                 :    28510215 :         case RID_THIS:
    6021                 :    28510215 :           cp_lexer_consume_token (parser->lexer);
    6022                 :    28510215 :           if (parser->local_variables_forbidden_p & THIS_FORBIDDEN)
    6023                 :             :             {
    6024                 :          36 :               error_at (token->location,
    6025                 :             :                         "%<this%> may not be used in this context");
    6026                 :          36 :               return error_mark_node;
    6027                 :             :             }
    6028                 :             :           /* Pointers cannot appear in constant-expressions.  */
    6029                 :    28510179 :           if (cp_parser_non_integral_constant_expression (parser, NIC_THIS))
    6030                 :           0 :             return error_mark_node;
    6031                 :    28510179 :           return cp_expr (finish_this_expr (), token->location);
    6032                 :             : 
    6033                 :             :           /* The `operator' keyword can be the beginning of an
    6034                 :             :              id-expression.  */
    6035                 :      209353 :         case RID_OPERATOR:
    6036                 :      209353 :           goto id_expression;
    6037                 :             : 
    6038                 :      126408 :         case RID_FUNCTION_NAME:
    6039                 :      126408 :         case RID_PRETTY_FUNCTION_NAME:
    6040                 :      126408 :         case RID_C99_FUNCTION_NAME:
    6041                 :      126408 :           {
    6042                 :      126408 :             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                 :      126408 :             token = cp_lexer_consume_token (parser->lexer);
    6052                 :             : 
    6053                 :      126408 :             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                 :           0 :               default:
    6065                 :           0 :                 gcc_unreachable ();
    6066                 :             :               }
    6067                 :             : 
    6068                 :      126408 :             if (cp_parser_non_integral_constant_expression (parser, name))
    6069                 :           3 :               return error_mark_node;
    6070                 :             : 
    6071                 :             :             /* Look up the name.  */
    6072                 :      126405 :             return finish_fname (token->u.value);
    6073                 :             :           }
    6074                 :             : 
    6075                 :       31083 :         case RID_VA_ARG:
    6076                 :       31083 :           {
    6077                 :       31083 :             tree expression;
    6078                 :       31083 :             tree type;
    6079                 :       31083 :             location_t type_location;
    6080                 :       31083 :             location_t start_loc
    6081                 :       31083 :               = cp_lexer_peek_token (parser->lexer)->location;
    6082                 :             :             /* The `__builtin_va_arg' construct is used to handle
    6083                 :             :                `va_arg'.  Consume the `__builtin_va_arg' token.  */
    6084                 :       31083 :             cp_lexer_consume_token (parser->lexer);
    6085                 :             :             /* Look for the opening `('.  */
    6086                 :       31083 :             matching_parens parens;
    6087                 :       31083 :             parens.require_open (parser);
    6088                 :             :             /* Now, parse the assignment-expression.  */
    6089                 :       31083 :             expression = cp_parser_assignment_expression (parser);
    6090                 :             :             /* Look for the `,'.  */
    6091                 :       31083 :             cp_parser_require (parser, CPP_COMMA, RT_COMMA);
    6092                 :       31083 :             type_location = cp_lexer_peek_token (parser->lexer)->location;
    6093                 :             :             /* Parse the type-id.  */
    6094                 :       31083 :             {
    6095                 :       31083 :               type_id_in_expr_sentinel s (parser);
    6096                 :       31083 :               type = cp_parser_type_id (parser);
    6097                 :       31083 :             }
    6098                 :             :             /* Look for the closing `)'.  */
    6099                 :       31083 :             location_t finish_loc
    6100                 :       31083 :               = cp_lexer_peek_token (parser->lexer)->location;
    6101                 :       31083 :             parens.require_close (parser);
    6102                 :             :             /* Using `va_arg' in a constant-expression is not
    6103                 :             :                allowed.  */
    6104                 :       31083 :             if (cp_parser_non_integral_constant_expression (parser,
    6105                 :             :                                                             NIC_VA_ARG))
    6106                 :           0 :               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                 :       31083 :             location_t combined_loc
    6113                 :       31083 :               = make_location (type_location, start_loc, finish_loc);
    6114                 :       31083 :             return build_x_va_arg (combined_loc, expression, type);
    6115                 :             :           }
    6116                 :             : 
    6117                 :        2584 :         case RID_OFFSETOF:
    6118                 :        2584 :           return cp_parser_builtin_offsetof (parser);
    6119                 :             : 
    6120                 :             :         // C++ concepts
    6121                 :      507825 :         case RID_REQUIRES:
    6122                 :      507825 :           return cp_parser_requires_expression (parser);
    6123                 :             : 
    6124                 :             :         /* Objective-C++ expressions.  */
    6125                 :           0 :         case RID_AT_ENCODE:
    6126                 :           0 :         case RID_AT_PROTOCOL:
    6127                 :           0 :         case RID_AT_SELECTOR:
    6128                 :           0 :           return cp_parser_objc_expression (parser);
    6129                 :             : 
    6130                 :          12 :         case RID_OMP_ALL_MEMORY:
    6131                 :          12 :           gcc_assert (flag_openmp);
    6132                 :          12 :           cp_lexer_consume_token (parser->lexer);
    6133                 :          12 :           error_at (token->location,
    6134                 :             :                     "%<omp_all_memory%> may only be used in OpenMP "
    6135                 :             :                     "%<depend%> clause");
    6136                 :          12 :           return error_mark_node;
    6137                 :             : 
    6138                 :          15 :         case RID_TEMPLATE:
    6139                 :          15 :           if (parser->in_function_body
    6140                 :          15 :               && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
    6141                 :             :                   == CPP_LESS))
    6142                 :             :             {
    6143                 :           9 :               error_at (token->location,
    6144                 :             :                         "a template declaration cannot appear at block scope");
    6145                 :           9 :               cp_parser_skip_to_end_of_block_or_statement (parser);
    6146                 :           9 :               return error_mark_node;
    6147                 :             :             }
    6148                 :             :           /* FALLTHRU */
    6149                 :         824 :         default:
    6150                 :         824 :           cp_parser_error (parser, "expected primary-expression");
    6151                 :         824 :           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                 :   495419904 :     case CPP_NAME:
    6158                 :   495419904 :       if (const cp_trait* trait = cp_lexer_peek_trait_expr (parser->lexer))
    6159                 :     1841142 :         return cp_parser_trait (parser, trait);
    6160                 :             :       /* FALLTHRU */
    6161                 :   587269127 :     case CPP_SCOPE:
    6162                 :   587269127 :     case CPP_TEMPLATE_ID:
    6163                 :   587269127 :     case CPP_NESTED_NAME_SPECIFIER:
    6164                 :   587269127 :       {
    6165                 :   493578762 :       id_expression:
    6166                 :   587269127 :         cp_expr id_expression;
    6167                 :   587269127 :         cp_expr decl;
    6168                 :   587269127 :         const char *error_msg;
    6169                 :   587269127 :         bool template_p;
    6170                 :   587269127 :         bool done;
    6171                 :   587269127 :         cp_token *id_expr_token;
    6172                 :             : 
    6173                 :             :         /* Parse the id-expression.  */
    6174                 :   587269127 :         id_expression
    6175                 :   587269127 :           = 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                 :   587269127 :         if (id_expression == error_mark_node)
    6182                 :        2613 :           return error_mark_node;
    6183                 :   587266514 :         id_expr_token = token;
    6184                 :   587266514 :         token = cp_lexer_peek_token (parser->lexer);
    6185                 :   587266514 :         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                 :   587266514 :         if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR
    6195                 :   587266514 :                  || TREE_CODE (id_expression) == TYPE_DECL)
    6196                 :   565985191 :           decl = id_expression;
    6197                 :             :         /* Look up the name.  */
    6198                 :             :         else
    6199                 :             :           {
    6200                 :   561119603 :             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                 :   561119603 :             if (id_expr_token->type == CPP_NAME
    6206                 :   491450794 :                 && id_expr_token->error_reported)
    6207                 :             :               {
    6208                 :           0 :                 cp_parser_simulate_error (parser);
    6209                 :           0 :                 return error_mark_node;
    6210                 :             :               }
    6211                 :             : 
    6212                 :   561119603 :             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                 :   561119603 :             if (ambiguous_decls)
    6222                 :         106 :               return error_mark_node;
    6223                 :             : 
    6224                 :             :             /* In Objective-C++, we may have an Objective-C 2.0
    6225                 :             :                dot-syntax for classes here.  */
    6226                 :   561119497 :             if (c_dialect_objc ()
    6227                 :           0 :                 && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
    6228                 :           0 :                 && TREE_CODE (decl) == TYPE_DECL
    6229                 :   561119497 :                 && objc_is_class_name (decl))
    6230                 :             :               {
    6231                 :           0 :                 tree component;
    6232                 :           0 :                 cp_lexer_consume_token (parser->lexer);
    6233                 :           0 :                 component = cp_parser_identifier (parser);
    6234                 :           0 :                 if (component == error_mark_node)
    6235                 :           0 :                   return error_mark_node;
    6236                 :             : 
    6237                 :           0 :                 tree result = objc_build_class_component_ref (id_expression,
    6238                 :           0 :                                                               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                 :           0 :                 location_t combined_loc
    6246                 :           0 :                   = make_location (input_location, id_expression.get_start (),
    6247                 :             :                                    get_finish (input_location));
    6248                 :           0 :                 protected_set_expr_location (result, combined_loc);
    6249                 :           0 :                 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                 :   561119497 :             tree decl_tree = objc_lookup_ivar (decl.get_value (),
    6264                 :             :                                                id_expression);
    6265                 :   561119497 :             if (decl_tree != decl.get_value ())
    6266                 :           0 :               decl = cp_expr (decl_tree);
    6267                 :             : 
    6268                 :             :             /* If name lookup gives us a SCOPE_REF, then the
    6269                 :             :                qualifying scope was dependent.  */
    6270                 :   561119497 :             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                 :    21281197 :                 return decl;
    6283                 :             :               }
    6284                 :             :             /* Check to see if DECL is a local variable in a context
    6285                 :             :                where that is forbidden.  */
    6286                 :   539838300 :             if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
    6287                 :     2751406 :                 && local_variable_p (decl)
    6288                 :             :                 /* DR 2082 permits local variables in unevaluated contexts
    6289                 :             :                    within a default argument.  */
    6290                 :   539838335 :                 && !cp_unevaluated_operand)
    6291                 :             :               {
    6292                 :          20 :                 const char *msg
    6293                 :          20 :                   = (TREE_CODE (decl) == PARM_DECL
    6294                 :          20 :                      ? G_("parameter %qD may not appear in this context")
    6295                 :          20 :                      : G_("local variable %qD may not appear in this context"));
    6296                 :          20 :                 error_at (id_expression.get_location (), msg,
    6297                 :             :                           decl.get_value ());
    6298                 :          20 :                 return error_mark_node;
    6299                 :             :               }
    6300                 :             :           }
    6301                 :             : 
    6302                 :   565985191 :         decl = (finish_id_expression
    6303                 :  1131970378 :                 (id_expression, decl, parser->scope,
    6304                 :             :                  idk,
    6305                 :   565985191 :                  parser->integral_constant_expression_p,
    6306                 :   565985191 :                  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                 :   565985187 :         if (error_msg)
    6313                 :        1377 :           cp_parser_error (parser, 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                 :   565985187 :         location_t caret_loc = get_pure_location (id_expression.get_location ());
    6323                 :   565985187 :         location_t start_loc = get_start (id_expr_token->location);
    6324                 :   565985187 :         location_t finish_loc = get_finish (id_expression.get_location ());
    6325                 :   565985187 :         location_t combined_loc
    6326                 :   565985187 :           = make_location (caret_loc, start_loc, finish_loc);
    6327                 :             : 
    6328                 :   565985187 :         decl.set_location (combined_loc);
    6329                 :   565985187 :         return decl;
    6330                 :             :       }
    6331                 :             : 
    6332                 :             :       /* Anything else is an error.  */
    6333                 :       91735 :     default:
    6334                 :       91735 :       cp_parser_error (parser, "expected primary-expression");
    6335                 :       91735 :       return error_mark_node;
    6336                 :             :     }
    6337                 :             : }
    6338                 :             : 
    6339                 :             : static inline cp_expr
    6340                 :     3247492 : cp_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                 :     3247492 :   return cp_parser_primary_expression (parser, address_p, cast_p, template_arg_p,
    6347                 :             :                                        /*decltype*/false, idk);
    6348                 :             : }
    6349                 :             : 
    6350                 :             : /* Complain about missing template keyword when naming a dependent
    6351                 :             :    member template.  */
    6352                 :             : 
    6353                 :             : static void
    6354                 :          16 : missing_template_diag (location_t loc, diagnostic_t diag_kind = DK_WARNING)
    6355                 :             : {
    6356                 :          16 :   if (warning_suppressed_at (loc, OPT_Wmissing_template_keyword))
    6357                 :           0 :     return;
    6358                 :             : 
    6359                 :          16 :   gcc_rich_location richloc (loc);
    6360                 :          16 :   richloc.add_fixit_insert_before ("template");
    6361                 :          16 :   emit_diagnostic (diag_kind, &richloc, OPT_Wmissing_template_keyword,
    6362                 :             :                    "expected %qs keyword before dependent "
    6363                 :             :                    "template name", "template");
    6364                 :          16 :   suppress_warning_at (loc, OPT_Wmissing_template_keyword);
    6365                 :          16 : }
    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                 :             : 
    6401                 :             : static cp_expr
    6402                 :  1252975639 : cp_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                 :  1252975639 :   bool global_scope_p;
    6410                 :  1252975639 :   bool nested_name_specifier_p;
    6411                 :             : 
    6412                 :             :   /* Assume the `template' keyword was not used.  */
    6413                 :  1252975639 :   if (template_p)
    6414                 :   731075989 :     *template_p = template_keyword_p;
    6415                 :             : 
    6416                 :             :   /* Look for the optional `::' operator.  */
    6417                 :  1252975639 :   global_scope_p
    6418                 :  2505951278 :     = (!template_keyword_p
    6419                 :  1252975639 :        && (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                 :  1252975639 :   nested_name_specifier_p
    6425                 :  1252975639 :     = (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                 :  1252975639 :   cp_expr id = NULL_TREE;
    6434                 :  1252975639 :   tree scope = parser->scope;
    6435                 :             : 
    6436                 :             :   /* Peek at the next token.  */
    6437                 :  1252975639 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
    6438                 :             : 
    6439                 :             :   /* If there is a nested-name-specifier, then we are looking at
    6440                 :             :      the first qualified-id production.  */
    6441                 :  1252975639 :   if (nested_name_specifier_p)
    6442                 :             :     {
    6443                 :    98602341 :       tree saved_object_scope;
    6444                 :    98602341 :       tree saved_qualifying_scope;
    6445                 :             : 
    6446                 :             :       /* See if the next token is the `template' keyword.  */
    6447                 :    98602341 :       if (!template_p)
    6448                 :    10921181 :         template_p = &template_keyword_p;
    6449                 :    98602341 :       *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                 :    98602341 :       saved_object_scope = parser->object_scope;
    6453                 :    98602341 :       saved_qualifying_scope = parser->qualifying_scope;
    6454                 :             :       /* Process the final unqualified-id.  */
    6455                 :    98602341 :       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                 :    98602341 :       parser->scope = scope;
    6461                 :    98602341 :       parser->object_scope = saved_object_scope;
    6462                 :    98602341 :       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                 :  1154373298 :   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                 :      127634 :       if (token->type == CPP_NAME
    6472                 :      150049 :           && !cp_parser_nth_token_starts_template_argument_list_p
    6473                 :       22415 :                (parser, 2))
    6474                 :       22415 :         return cp_parser_identifier (parser);
    6475                 :             : 
    6476                 :      105219 :       cp_parser_parse_tentatively (parser);
    6477                 :             :       /* Try a template-id.  */
    6478                 :      105219 :       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                 :      105219 :       if (cp_parser_parse_definitely (parser))
    6484                 :          17 :         return id;
    6485                 :             : 
    6486                 :             :       /* Peek at the next token.  (Changes in the token buffer may
    6487                 :             :          have invalidated the pointer obtained above.)  */
    6488                 :      105202 :       token = cp_lexer_peek_token (parser->lexer);
    6489                 :             : 
    6490                 :      105202 :       switch (token->type)
    6491                 :             :         {
    6492                 :           0 :         case CPP_NAME:
    6493                 :           0 :           id = cp_parser_identifier (parser);
    6494                 :           0 :           break;
    6495                 :             : 
    6496                 :      105150 :         case CPP_KEYWORD:
    6497                 :      105150 :           if (token->keyword == RID_OPERATOR)
    6498                 :             :             {
    6499                 :      100016 :               id = cp_parser_operator_function_id (parser);
    6500                 :      100016 :               break;
    6501                 :             :             }
    6502                 :             :           /* Fall through.  */
    6503                 :             : 
    6504                 :        5186 :         default:
    6505                 :        5186 :           cp_parser_error (parser, "expected id-expression");
    6506                 :        5186 :           return error_mark_node;
    6507                 :             :         }
    6508                 :             :     }
    6509                 :             :   else
    6510                 :             :     {
    6511                 :  1154245664 :       if (!scope)
    6512                 :  1154245664 :         scope = parser->context->object_type;
    6513                 :  1154245664 :       id = cp_parser_unqualified_id (parser, template_keyword_p,
    6514                 :             :                                      /*check_dependency_p=*/true,
    6515                 :             :                                      declarator_p,
    6516                 :             :                                      optional_p);
    6517                 :             :     }
    6518                 :             : 
    6519                 :  1233261750 :   if (id && TREE_CODE (id) == IDENTIFIER_NODE
    6520                 :  1187676352 :       && warn_missing_template_keyword
    6521                 :  1187676352 :       && !template_keyword_p
    6522                 :             :       /* Don't warn if we're looking inside templates.  */
    6523                 :  1187676260 :       && check_dependency_p
    6524                 :             :       /* In a template argument list a > could be closing
    6525                 :             :          the enclosing targs.  */
    6526                 :   716889764 :       && !parser->in_template_argument_list_p
    6527                 :   673460812 :       && 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                 :    97145899 :       && !(declarator_p && constructor_name_p (id, scope))
    6531                 :    96521558 :       && cp_parser_nth_token_starts_template_argument_list_p (parser, 1)
    6532                 :  1253096740 :       && warning_enabled_at (token->location,
    6533                 :             :                              OPT_Wmissing_template_keyword))
    6534                 :             :     {
    6535                 :        4525 :       saved_token_sentinel toks (parser->lexer, STS_ROLLBACK);
    6536                 :        4525 :       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                 :        4525 :           && (cp_lexer_peek_token (parser->lexer)->type
    6541                 :             :               <= CPP_LAST_PUNCTUATOR))
    6542                 :          16 :         missing_template_diag (token->location);
    6543                 :        4525 :     }
    6544                 :             : 
    6545                 :  1252948021 :   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                 :             : 
    6570                 :             : static cp_expr
    6571                 :  1261298681 : cp_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                 :  1261298681 :   cp_token *token;
    6578                 :             : 
    6579                 :             :   /* Peek at the next token.  */
    6580                 :  1261298681 :   token = cp_lexer_peek_token (parser->lexer);
    6581                 :             : 
    6582                 :  1261298681 :   switch ((int) token->type)
    6583                 :             :     {
    6584                 :  1165821881 :     case CPP_NAME:
    6585                 :  1165821881 :       {
    6586                 :  1165821881 :         tree id;
    6587                 :             : 
    6588                 :             :         /* We don't know yet whether or not this will be a
    6589                 :             :            template-id.  */
    6590                 :  1165821881 :         cp_parser_parse_tentatively (parser);
    6591                 :             :         /* Try a template-id.  */
    6592                 :  1165821881 :         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                 :  1165821881 :         if (cp_parser_parse_definitely (parser))
    6597                 :           0 :           return id;
    6598                 :             :         /* Otherwise, it's an ordinary identifier.  */
    6599                 :  1165821881 :         return cp_parser_identifier (parser);
    6600                 :             :       }
    6601                 :             : 
    6602                 :    29951913 :     case CPP_TEMPLATE_ID:
    6603                 :    29951913 :       return cp_parser_template_id_expr (parser, template_keyword_p,
    6604                 :             :                                          check_dependency_p,
    6605                 :    29951913 :                                          declarator_p);
    6606                 :             : 
    6607                 :     6122367 :     case CPP_COMPL:
    6608                 :     6122367 :       {
    6609                 :     6122367 :         tree type_decl;
    6610                 :     6122367 :         tree qualifying_scope;
    6611                 :     6122367 :         tree object_scope;
    6612                 :     6122367 :         tree scope;
    6613                 :     6122367 :         bool done;
    6614                 :     6122367 :         location_t tilde_loc = token->location;
    6615                 :             : 
    6616                 :             :         /* Consume the `~' token.  */
    6617                 :     6122367 :         cp_lexer_consume_token (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                 :     6122367 :         scope = parser->scope;
    6654                 :     6122367 :         object_scope = parser->object_scope;
    6655                 :     6122367 :         qualifying_scope = parser->qualifying_scope;
    6656                 :             : 
    6657                 :             :         /* Check for invalid scopes.  */
    6658                 :     6122367 :         if (scope == error_mark_node)
    6659                 :             :           {
    6660                 :           4 :             if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    6661                 :           4 :               cp_lexer_consume_token (parser->lexer);
    6662                 :           4 :             return error_mark_node;
    6663                 :             :           }
    6664                 :     6122363 :         if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
    6665                 :             :           {
    6666                 :          44 :             if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
    6667                 :          12 :               error_at (token->location,
    6668                 :             :                         "scope %qT before %<~%> is not a class-name",
    6669                 :             :                         scope);
    6670                 :          32 :             cp_parser_simulate_error (parser);
    6671                 :          16 :             if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    6672                 :          16 :               cp_lexer_consume_token (parser->lexer);
    6673                 :          16 :             return error_mark_node;
    6674                 :             :           }
    6675                 :     6122347 :         if (template_keyword_p)
    6676                 :             :           {
    6677                 :          12 :             if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
    6678                 :           4 :               error_at (tilde_loc, "%<template%> keyword not permitted in "
    6679                 :             :                         "destructor name");
    6680                 :           8 :             cp_parser_simulate_error (parser);
    6681                 :           4 :             return error_mark_node;
    6682                 :             :           }
    6683                 :             : 
    6684                 :     6122343 :         gcc_assert (!scope || TYPE_P (scope));
    6685                 :             : 
    6686                 :     6122343 :         token = cp_lexer_peek_token (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                 :     6122343 :         location_t loc
    6693                 :     6122343 :           = make_location (tilde_loc, tilde_loc, 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                 :     6122343 :         if (scope
    6699                 :      489294 :             && token->type == CPP_NAME
    6700                 :      489246 :             && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
    6701                 :             :                 != CPP_LESS)
    6702                 :     6611561 :             && (token->u.value == TYPE_IDENTIFIER (scope)
    6703                 :          99 :                 || (CLASS_TYPE_P (scope)
    6704                 :          89 :                     && constructor_name_p (token->u.value, scope))))
    6705                 :             :           {
    6706                 :      489119 :             cp_lexer_consume_token (parser->lexer);
    6707                 :      489119 :             return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
    6708                 :             :           }
    6709                 :             : 
    6710                 :             :         /* ~auto means the destructor of whatever the object is.  */
    6711                 :     5633224 :         if (cp_parser_is_keyword (token, RID_AUTO))
    6712                 :             :           {
    6713                 :           3 :             if (cxx_dialect < cxx14)
    6714                 :           0 :               pedwarn (loc, OPT_Wc__14_extensions,
    6715                 :             :                        "%<~auto%> only available with "
    6716                 :             :                        "%<-std=c++14%> or %<-std=gnu++14%>");
    6717                 :           3 :             cp_lexer_consume_token (parser->lexer);
    6718                 :           3 :             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                 :     5633221 :         if (token->type == CPP_TEMPLATE_ID && declarator_p)
    6724                 :             :           {
    6725                 :          87 :             auto_diagnostic_group d;
    6726                 :          87 :             bool w = false;
    6727                 :          93 :             if (cxx_dialect >= cxx20 && !cp_parser_simulate_error (parser))
    6728                 :          15 :               w = pedwarn (tilde_loc, OPT_Wtemplate_id_cdtor,
    6729                 :             :                            "template-id not allowed for destructor in C++20");
    6730                 :          72 :             else if (cxx_dialect < cxx20
    6731                 :          72 :                      && !cp_parser_uncommitted_to_tentative_parse_p (parser))
    6732                 :          48 :               w = warning_at (tilde_loc, OPT_Wtemplate_id_cdtor,
    6733                 :             :                               "template-id not allowed for destructor in C++20");
    6734                 :          63 :             if (w)
    6735                 :          23 :               inform (tilde_loc, "remove the %qs", "< >");
    6736                 :          87 :           }
    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                 :     5633221 :         done = false;
    6745                 :     5633221 :         type_decl = NULL_TREE;
    6746                 :     5633221 :         if (scope)
    6747                 :             :           {
    6748                 :         175 :             cp_parser_parse_tentatively (parser);
    6749                 :         175 :             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                 :         175 :             if (cp_parser_parse_definitely (parser))
    6757                 :             :               done = true;
    6758                 :             :           }
    6759                 :             :         /* In "N::S::~S", look in "N" as well.  */
    6760                 :     5633221 :         if (!done && scope && qualifying_scope)
    6761                 :             :           {
    6762                 :           0 :             cp_parser_parse_tentatively (parser);
    6763                 :           0 :             parser->scope = qualifying_scope;
    6764                 :           0 :             parser->object_scope = NULL_TREE;
    6765                 :           0 :             parser->qualifying_scope = NULL_TREE;
    6766                 :           0 :             type_decl
    6767                 :           0 :               = 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                 :           0 :             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                 :     5633221 :         else if (!done && object_scope)
    6779                 :             :           {
    6780                 :          27 :             cp_parser_parse_tentatively (parser);
    6781                 :          27 :             parser->scope = object_scope;
    6782                 :          27 :             parser->object_scope = NULL_TREE;
    6783                 :          27 :             parser->qualifying_scope = NULL_TREE;
    6784                 :          27 :             type_decl
    6785                 :          27 :               = 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                 :          27 :             if (cp_parser_parse_definitely (parser))
    6793                 :           0 :               done = true;
    6794                 :             :           }
    6795                 :             :         /* Look in the surrounding context.  */
    6796                 :     5633221 :         if (!done)
    6797                 :             :           {
    6798                 :     5633126 :             parser->scope = NULL_TREE;
    6799                 :     5633126 :             parser->object_scope = NULL_TREE;
    6800                 :     5633126 :             parser->qualifying_scope = NULL_TREE;
    6801                 :     5633126 :             if (processing_template_decl)
    6802                 :     3332475 :               cp_parser_parse_tentatively (parser);
    6803                 :     5633126 :             type_decl
    6804                 :     5633126 :               = 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                 :     5633126 :             if (processing_template_decl
    6812                 :     5633126 :                 && ! 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                 :       24312 :                 if (cp_parser_uncommitted_to_tentative_parse_p (parser))
    6817                 :             :                   {
    6818                 :       12130 :                     cp_parser_simulate_error (parser);
    6819                 :       12130 :                     return error_mark_node;
    6820                 :             :                   }
    6821                 :             :                 /* Otherwise, accept it and check for a match at instantiation
    6822                 :             :                    time.  */
    6823                 :          26 :                 type_decl = cp_parser_identifier (parser);
    6824                 :          26 :                 if (type_decl != error_mark_node)
    6825                 :          20 :                   type_decl = build_min_nt_loc (loc, BIT_NOT_EXPR, type_decl);
    6826                 :          26 :                 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                 :     5621065 :         if (type_decl == error_mark_node && scope)
    6834                 :          12 :           return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
    6835                 :     5621053 :         else if (type_decl == error_mark_node)
    6836                 :          22 :           return error_mark_node;
    6837                 :             : 
    6838                 :             :         /* Check that destructor name and scope match.  */
    6839                 :     5621031 :         if (declarator_p && scope && !check_dtor_name (scope, type_decl))
    6840                 :             :           {
    6841                 :          85 :             if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
    6842                 :          11 :               error_at (loc,
    6843                 :             :                         "declaration of %<~%T%> as member of %qT",
    6844                 :             :                         type_decl, scope);
    6845                 :          74 :             cp_parser_simulate_error (parser);
    6846                 :          37 :             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                 :     5620994 :         if (declarator_p
    6854                 :     5307534 :             && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
    6855                 :     5307340 :             && !DECL_SELF_REFERENCE_P (type_decl)
    6856                 :     5620994 :             && !cp_parser_uncommitted_to_tentative_parse_p (parser))
    6857                 :           7 :           error_at (loc,
    6858                 :             :                     "typedef-name %qD used as destructor declarator",
    6859                 :             :                     type_decl);
    6860                 :             : 
    6861                 :     5620994 :         return build_min_nt_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type_decl));
    6862                 :             :       }
    6863                 :             : 
    6864                 :    35273067 :     case CPP_KEYWORD:
    6865                 :    35273067 :       if (token->keyword == RID_OPERATOR)
    6866                 :             :         {
    6867                 :    30042893 :           cp_expr id;
    6868                 :             : 
    6869                 :             :           /* This could be a template-id, so we try that first.  */
    6870                 :    30042893 :           cp_parser_parse_tentatively (parser);
    6871                 :             :           /* Try a template-id.  */
    6872                 :    30042893 :           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                 :    30042893 :           if (cp_parser_parse_definitely (parser))
    6877                 :         998 :             return id;
    6878                 :             :           /* We still don't know whether we're looking at an
    6879                 :             :              operator-function-id or a conversion-function-id.  */
    6880                 :    30041895 :           cp_parser_parse_tentatively (parser);
    6881                 :             :           /* Try an operator-function-id.  */
    6882                 :    30041895 :           id = cp_parser_operator_function_id (parser);
    6883                 :             :           /* If that didn't work, try a conversion-function-id.  */
    6884                 :    30041895 :           if (!cp_parser_parse_definitely (parser))
    6885                 :     1172620 :             id = cp_parser_conversion_function_id (parser);
    6886                 :             : 
    6887                 :    30041895 :           return id;
    6888                 :             :         }
    6889                 :             :       /* Fall through.  */
    6890                 :             : 
    6891                 :    29359627 :     default:
    6892                 :    29359627 :       if (optional_p)
    6893                 :    19686271 :         return NULL_TREE;
    6894                 :     9673356 :       cp_parser_error (parser, "expected unqualified-id");
    6895                 :     9673356 :       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                 :             : 
    6903                 :             : static void
    6904                 :     2758202 : check_template_keyword_in_nested_name_spec (tree name)
    6905                 :             : {
    6906                 :     2568629 :   if (CLASS_TYPE_P (name)
    6907                 :     5326831 :       && ((CLASSTYPE_USE_TEMPLATE (name)
    6908                 :     2508232 :            && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (name)))
    6909                 :       60397 :           || CLASSTYPE_IS_TEMPLATE (name)))
    6910                 :             :     return;
    6911                 :             : 
    6912                 :      189577 :   if (TREE_CODE (name) == TYPENAME_TYPE
    6913                 :      189577 :       && TREE_CODE (TYPENAME_TYPE_FULLNAME (name)) == TEMPLATE_ID_EXPR)
    6914                 :             :     return;
    6915                 :             :   /* Alias templates are also OK.  */
    6916                 :          18 :   else if (alias_template_specialization_p (name, nt_opaque))
    6917                 :             :     return;
    6918                 :             : 
    6919                 :           4 :   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                 :             : 
    6952                 :             : static tree
    6953                 :  4410311805 : cp_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                 :  4410311805 :   bool success = false;
    6961                 :  4410311805 :   cp_token_position start = 0;
    6962                 :  4410311805 :   cp_token *token;
    6963                 :             : 
    6964                 :             :   /* Remember where the nested-name-specifier starts.  */
    6965                 :  4410311805 :   if (cp_parser_uncommitted_to_tentative_parse_p (parser)
    6966                 :  3340924117 :       && cp_lexer_next_token_is_not (parser->lexer, CPP_NESTED_NAME_SPECIFIER))
    6967                 :             :     {
    6968                 :  3291966762 :       start = cp_lexer_token_position (parser->lexer, false);
    6969                 :  3291966762 :       push_deferring_access_checks (dk_deferred);
    6970                 :             :     }
    6971                 :             : 
    6972                 :  4709670865 :   while (true)
    6973                 :             :     {
    6974                 :  4709670865 :       tree new_scope;
    6975                 :  4709670865 :       tree old_scope;
    6976                 :  4709670865 :       tree saved_qualifying_scope;
    6977                 :             : 
    6978                 :             :       /* Spot cases that cannot be the beginning of a
    6979                 :             :          nested-name-specifier.  */
    6980                 :  4709670865 :       token = cp_lexer_peek_token (parser->lexer);
    6981                 :             : 
    6982                 :             :       /* If the next token is CPP_NESTED_NAME_SPECIFIER, just process
    6983                 :             :          the already parsed nested-name-specifier.  */
    6984                 :  4709670865 :       if (token->type == CPP_NESTED_NAME_SPECIFIER)
    6985                 :             :         {
    6986                 :             :           /* Grab the nested-name-specifier and continue the loop.  */
    6987                 :   134547564 :           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                 :   134547564 :           if (is_declaration
    6992                 :   134547564 :               && !check_dependency_p
    6993                 :     9278103 :               && TREE_CODE (parser->scope) == TYPENAME_TYPE)
    6994                 :             :             {
    6995                 :       74215 :               new_scope = resolve_typename_type (parser->scope,
    6996                 :             :                                                  /*only_current_p=*/false);
    6997                 :       74215 :               if (TREE_CODE (new_scope) != TYPENAME_TYPE)
    6998                 :       74180 :                 parser->scope = new_scope;
    6999                 :             :             }
    7000                 :   134547564 :           success = true;
    7001                 :   134547564 :           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                 :  4575123301 :       if (success && token->keyword == RID_TEMPLATE)
    7008                 :             :         ;
    7009                 :             :       /* A template-id can start a nested-name-specifier.  */
    7010                 :  4574120654 :       else if (token->type == CPP_TEMPLATE_ID)
    7011                 :             :         ;
    7012                 :             :       /* DR 743: decltype can be used in a nested-name-specifier.  */
    7013                 :  4519026768 :       else if (token_is_decltype (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                 :  4518979268 :           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                 :  3399654432 :           token = cp_lexer_peek_nth_token (parser->lexer, 2);
    7025                 :             : 
    7026                 :  3399654432 :           if (token->type == CPP_COLON
    7027                 :     8471373 :               && parser->colon_corrects_to_scope_p
    7028                 :          96 :               && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_NAME
    7029                 :             :               /* name:name is a valid sequence in an Objective C message.  */
    7030                 :  3399654490 :               && !parser->objective_c_message_context_p)
    7031                 :             :             {
    7032                 :          58 :               gcc_rich_location richloc (token->location);
    7033                 :          58 :               richloc.add_fixit_replace ("::");
    7034                 :          58 :               error_at (&richloc,
    7035                 :             :                         "found %<:%> in nested-name-specifier, "
    7036                 :             :                         "expected %<::%>");
    7037                 :          58 :               token->type = CPP_SCOPE;
    7038                 :          58 :             }
    7039                 :             : 
    7040                 :  3399654432 :           if (token->type != CPP_SCOPE
    7041                 :  6669101159 :               && !cp_parser_nth_token_starts_template_argument_list_p
    7042                 :  3269446727 :                   (parser, 2))
    7043                 :             :             break;
    7044                 :             :         }
    7045                 :             : 
    7046                 :             :       /* The nested-name-specifier is optional, so we parse
    7047                 :             :          tentatively.  */
    7048                 :   383587593 :       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                 :   383587593 :       if (success)
    7053                 :             :         {
    7054                 :    62063517 :           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                 :    62063517 :           if (!template_keyword_p
    7060                 :    62063517 :               && typename_keyword_p
    7061                 :    62063517 :               && 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                 :   383587593 :       old_scope = parser->scope;
    7068                 :   383587593 :       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                 :   383587593 :       if (is_declaration
    7074                 :   383587593 :           && !check_dependency_p
    7075                 :     1649574 :           && !typename_keyword_p
    7076                 :     1649574 :           && parser->scope
    7077                 :       18678 :           && TREE_CODE (parser->scope) == TYPENAME_TYPE)
    7078                 :           0 :         parser->scope = resolve_typename_type (parser->scope,
    7079                 :             :                                                /*only_current_p=*/false);
    7080                 :             :       /* Parse the qualifying entity.  */
    7081                 :   383587593 :       new_scope
    7082                 :   383587593 :         = 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                 :   383587590 :       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                 :   383587590 :       if (!cp_parser_parse_definitely (parser))
    7094                 :             :         {
    7095                 :   218776090 :           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                 :   218776090 :           parser->scope = old_scope;
    7101                 :   218776090 :           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                 :   218776090 :           if (cp_lexer_next_token_is (parser->lexer, CPP_DECLTYPE)
    7110                 :   218776090 :               && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
    7111                 :             :                   == CPP_SCOPE))
    7112                 :             :             {
    7113                 :           9 :               token = cp_lexer_consume_token (parser->lexer);
    7114                 :           9 :               tree dtype = token->u.tree_check_value->value;
    7115                 :           9 :               if (dtype != error_mark_node)
    7116                 :           9 :                 error_at (token->location, "%<decltype%> evaluates to %qT, "
    7117                 :             :                           "which is not a class or enumeration type",
    7118                 :             :                           dtype);
    7119                 :           9 :               parser->scope = error_mark_node;
    7120                 :           9 :               error_p = true;
    7121                 :             :               /* As below.  */
    7122                 :           9 :               success = true;
    7123                 :           9 :               cp_lexer_consume_token (parser->lexer);
    7124                 :             :             }
    7125                 :             : 
    7126                 :   218776090 :           if (cp_lexer_next_token_is (parser->lexer, CPP_TEMPLATE_ID)
    7127                 :   218776090 :               && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SCOPE))
    7128                 :             :             {
    7129                 :             :               /* If we have a non-type template-id followed by ::, it can't
    7130                 :             :                  possibly be valid.  */
    7131                 :          53 :               token = cp_lexer_peek_token (parser->lexer);
    7132                 :          53 :               tree tid = token->u.tree_check_value->value;
    7133                 :          53 :               if (TREE_CODE (tid) == TEMPLATE_ID_EXPR
    7134                 :          53 :                   && TREE_CODE (TREE_OPERAND (tid, 0)) != IDENTIFIER_NODE)
    7135                 :             :                 {
    7136                 :          14 :                   tree tmpl = NULL_TREE;
    7137                 :          14 :                   if (is_overloaded_fn (tid))
    7138                 :             :                     {
    7139                 :           9 :                       tree fns = get_fns (tid);
    7140                 :           9 :                       if (OVL_SINGLE_P (fns))
    7141                 :           9 :                         tmpl = OVL_FIRST (fns);
    7142                 :           9 :                       if (function_concept_p (fns))
    7143                 :           2 :                         error_at (token->location, "concept-id %qD "
    7144                 :             :                                   "in nested-name-specifier", tid);
    7145                 :             :                       else
    7146                 :           7 :                         error_at (token->location, "function template-id "
    7147                 :             :                                   "%qD in nested-name-specifier", tid);
    7148                 :             :                     }
    7149                 :             :                   else
    7150                 :             :                     {
    7151                 :           5 :                       tmpl = TREE_OPERAND (tid, 0);
    7152                 :           5 :                       if (variable_concept_p (tmpl)
    7153                 :          10 :                           || standard_concept_p (tmpl))
    7154                 :           2 :                         error_at (token->location, "concept-id %qD "
    7155                 :             :                                   "in nested-name-specifier", tid);
    7156                 :             :                       else
    7157                 :             :                         {
    7158                 :             :                           /* Variable template.  */
    7159                 :           3 :                           gcc_assert (variable_template_p (tmpl));
    7160                 :           3 :                           error_at (token->location, "variable template-id "
    7161                 :             :                                     "%qD in nested-name-specifier", tid);
    7162                 :             :                         }
    7163                 :             :                     }
    7164                 :          14 :                   if (tmpl)
    7165                 :          14 :                     inform (DECL_SOURCE_LOCATION (tmpl),
    7166                 :             :                             "%qD declared here", tmpl);
    7167                 :             : 
    7168                 :          14 :                   parser->scope = error_mark_node;
    7169                 :          14 :                   error_p = true;
    7170                 :             :                   /* As below.  */
    7171                 :          14 :                   success = true;
    7172                 :          14 :                   cp_lexer_consume_token (parser->lexer);
    7173                 :          14 :                   cp_lexer_consume_token (parser->lexer);
    7174                 :             :                 }
    7175                 :             :             }
    7176                 :             : 
    7177                 :  4679795709 :           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                 :    50707821 :           while (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
    7183                 :     6786911 :                  && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
    7184                 :             :                      == CPP_SCOPE)
    7185                 :    50707956 :                  && (cp_lexer_peek_nth_token (parser->lexer, 3)->type
    7186                 :             :                      != CPP_COMPL))
    7187                 :             :             {
    7188                 :         131 :               token = cp_lexer_consume_token (parser->lexer);
    7189                 :         131 :               if (!error_p)
    7190                 :             :                 {
    7191                 :         127 :                   if (!token->error_reported)
    7192                 :             :                     {
    7193                 :         127 :                       tree decl;
    7194                 :         127 :                       tree ambiguous_decls;
    7195                 :             : 
    7196                 :         127 :                       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                 :         127 :                       if (TREE_CODE (decl) == TEMPLATE_DECL)
    7204                 :          11 :                         error_at (token->location,
    7205                 :             :                                   "%qD used without template arguments",
    7206                 :             :                                   decl);
    7207                 :         116 :                       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                 :          12 :                           if (cp_parser_uncommitted_to_tentative_parse_p
    7212                 :          12 :                               (parser))
    7213                 :             :                             {
    7214                 :           0 :                               error_at (token->location,
    7215                 :             :                                         "reference to %qD is ambiguous",
    7216                 :             :                                         token->u.value);
    7217                 :           0 :                               print_candidates (ambiguous_decls);
    7218                 :             :                             }
    7219                 :          12 :                           decl = error_mark_node;
    7220                 :             :                         }
    7221                 :             :                       else
    7222                 :             :                         {
    7223                 :         104 :                           if (cxx_dialect != cxx98)
    7224                 :          83 :                             cp_parser_name_lookup_error
    7225                 :          83 :                             (parser, token->u.value, decl, NLE_NOT_CXX98,
    7226                 :             :                              token->location);
    7227                 :             :                           else
    7228                 :          21 :                             cp_parser_name_lookup_error
    7229                 :          21 :                             (parser, token->u.value, decl, NLE_CXX98,
    7230                 :             :                              token->location);
    7231                 :             :                         }
    7232                 :             :                     }
    7233                 :         127 :                   parser->scope = error_mark_node;
    7234                 :         127 :                   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                 :         127 :                   success = true;
    7244                 :             :                 }
    7245                 :         131 :               cp_lexer_consume_token (parser->lexer);
    7246                 :             :             }
    7247                 :             :           break;
    7248                 :             :         }
    7249                 :             :       /* We've found one valid nested-name-specifier.  */
    7250                 :   164811500 :       success = true;
    7251                 :             :       /* Name lookup always gives us a DECL.  */
    7252                 :   164811500 :       if (TREE_CODE (new_scope) == TYPE_DECL)
    7253                 :    74817455 :         new_scope = TREE_TYPE (new_scope);
    7254                 :             :       /* Uses of "template" must be followed by actual templates.  */
    7255                 :   164811500 :       if (template_keyword_p)
    7256                 :     2758202 :         check_template_keyword_in_nested_name_spec (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                 :   164811500 :       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                 :    74825089 :           && !COMPLETE_TYPE_P (new_scope)
    7263                 :             :           /* Do not try to complete dependent types.  */
    7264                 :   211364809 :           && !dependent_type_p (new_scope))
    7265                 :             :         {
    7266                 :      640837 :           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                 :      640833 :           if (!COMPLETE_TYPE_P (new_scope)
    7271                 :      640833 :               && currently_open_class (new_scope))
    7272                 :       43043 :             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                 :   164811496 :       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                 :  4410311798 :   if (success && start)
    7285                 :             :     {
    7286                 :   127605931 :       cp_token *token;
    7287                 :             : 
    7288                 :   127605931 :       token = cp_lexer_token_at (parser->lexer, start);
    7289                 :             :       /* Reset the contents of the START token.  */
    7290                 :   127605931 :       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                 :   127605931 :       token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
    7294                 :   127605931 :       token->tree_check_p = true;
    7295                 :   127605931 :       token->u.tree_check_value->value = parser->scope;
    7296                 :   127605931 :       token->u.tree_check_value->checks = get_deferred_access_checks ();
    7297                 :   127605931 :       token->u.tree_check_value->qualifying_scope =
    7298                 :   127605931 :         parser->qualifying_scope;
    7299                 :   127605931 :       token->keyword = RID_MAX;
    7300                 :             : 
    7301                 :             :       /* Purge all subsequent tokens.  */
    7302                 :   127605931 :       cp_lexer_purge_tokens_after (parser->lexer, start);
    7303                 :             :     }
    7304                 :             : 
    7305                 :  4410311798 :   if (start)
    7306                 :  3291966755 :     pop_to_parent_deferring_access_checks ();
    7307                 :             : 
    7308                 :  4410311798 :   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                 :             : 
    7316                 :             : static tree
    7317                 :   943828793 : cp_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                 :   943828793 :   tree scope;
    7324                 :             : 
    7325                 :             :   /* Look for the nested-name-specifier.  */
    7326                 :   943828793 :   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                 :   943828793 :   if (!scope)
    7333                 :             :     {
    7334                 :   903829810 :       cp_parser_error (parser, "expected nested-name-specifier");
    7335                 :   903829810 :       parser->scope = NULL_TREE;
    7336                 :             :     }
    7337                 :             : 
    7338                 :   943828793 :   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                 :             : 
    7358                 :             : static tree
    7359                 :   383587593 : cp_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                 :   383587593 :   tree saved_scope;
    7367                 :   383587593 :   tree saved_qualifying_scope;
    7368                 :   383587593 :   tree saved_object_scope;
    7369                 :   383587593 :   tree scope;
    7370                 :   383587593 :   bool only_class_p;
    7371                 :   383587593 :   bool successful_parse_p;
    7372                 :             : 
    7373                 :             :   /* DR 743: decltype can appear in a nested-name-specifier.  */
    7374                 :   383587593 :   if (cp_lexer_next_token_is_decltype (parser->lexer))
    7375                 :             :     {
    7376                 :       47500 :       scope = cp_parser_decltype (parser);
    7377                 :       47500 :       if (TREE_CODE (scope) != ENUMERAL_TYPE
    7378                 :         258 :           && !MAYBE_CLASS_TYPE_P (scope))
    7379                 :             :         {
    7380                 :         926 :           cp_parser_simulate_error (parser);
    7381                 :         463 :           return error_mark_node;
    7382                 :             :         }
    7383                 :       47037 :       if (TYPE_NAME (scope))
    7384                 :        6219 :         scope = TYPE_NAME (scope);
    7385                 :       47037 :       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                 :   383540093 :   saved_scope = parser->scope;
    7392                 :   383540093 :   saved_qualifying_scope = parser->qualifying_scope;
    7393                 :   383540093 :   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                 :  1146633758 :   only_class_p = template_keyword_p
    7397                 :   383540093 :     || (saved_scope && TYPE_P (saved_scope) && cxx_dialect == cxx98);
    7398                 :   379553572 :   if (!only_class_p)
    7399                 :   379553572 :     cp_parser_parse_tentatively (parser);
    7400                 :   383540093 :   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                 :   383540093 :                                 /*enum_ok=*/cxx_dialect > cxx98);
    7408                 :   383540090 :   successful_parse_p = only_class_p || cp_parser_parse_definitely (parser);
    7409                 :             :   /* If that didn't work, try for a namespace-name.  */
    7410                 :   383540090 :   if (!only_class_p && !successful_parse_p)
    7411                 :             :     {
    7412                 :             :       /* Restore the saved scope.  */
    7413                 :   167812356 :       parser->scope = saved_scope;
    7414                 :   167812356 :       parser->qualifying_scope = saved_qualifying_scope;
    7415                 :   167812356 :       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                 :   167812356 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)
    7421                 :   167812356 :           || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
    7422                 :    77825636 :         return error_mark_node;
    7423                 :    89986720 :       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                 :             : 
    7431                 :             : static bool
    7432                 :    28881454 : cp_parser_compound_literal_p (cp_parser *parser)
    7433                 :             : {
    7434                 :    28881454 :   cp_lexer_save_tokens (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                 :    28881454 :   bool compound_literal_p
    7440                 :    28881454 :     = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
    7441                 :             :                                               /*consume_paren=*/true)
    7442                 :    28881454 :        && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));
    7443                 :             : 
    7444                 :             :   /* Roll back the tokens we skipped.  */
    7445                 :    28881454 :   cp_lexer_rollback_tokens (parser->lexer);
    7446                 :             : 
    7447                 :    28881454 :   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                 :             : 
    7453                 :             : bool
    7454                 :      192974 : literal_integer_zerop (const_tree expr)
    7455                 :             : {
    7456                 :      192974 :   return (location_wrapper_p (expr)
    7457                 :      192974 :           && 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                 :             : 
    7502                 :             : static cp_expr
    7503                 :   836803386 : cp_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                 :   836803386 :   cp_token *token;
    7508                 :   836803386 :   location_t loc;
    7509                 :   836803386 :   enum rid keyword;
    7510                 :   836803386 :   cp_id_kind idk = CP_ID_KIND_NONE;
    7511                 :   836803386 :   cp_expr postfix_expression = NULL_TREE;
    7512                 :   836803386 :   bool is_member_access = false;
    7513                 :             : 
    7514                 :             :   /* Peek at the next token.  */
    7515                 :   836803386 :   token = cp_lexer_peek_token (parser->lexer);
    7516                 :   836803386 :   loc = token->location;
    7517                 :   836803386 :   location_t start_loc = get_range_from_loc (line_table, loc).m_start;
    7518                 :             : 
    7519                 :             :   /* Some of the productions are determined by keywords.  */
    7520                 :   836803386 :   keyword = token->keyword;
    7521                 :   836803386 :   switch (keyword)
    7522                 :             :     {
    7523                 :     7423387 :     case RID_DYNCAST:
    7524                 :     7423387 :     case RID_STATCAST:
    7525                 :     7423387 :     case RID_REINTCAST:
    7526                 :     7423387 :     case RID_CONSTCAST:
    7527                 :     7423387 :       {
    7528                 :     7423387 :         tree type;
    7529                 :     7423387 :         cp_expr expression;
    7530                 :     7423387 :         const char *saved_message;
    7531                 :     7423387 :         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                 :     7423387 :         cp_lexer_consume_token (parser->lexer);
    7537                 :             : 
    7538                 :             :         /* New types cannot be defined in the cast.  */
    7539                 :     7423387 :         saved_message = parser->type_definition_forbidden_message;
    7540                 :     7423387 :         parser->type_definition_forbidden_message
    7541                 :     7423387 :           = G_("types may not be defined in casts");
    7542                 :             : 
    7543                 :             :         /* Look for the opening `<'.  */
    7544                 :     7423387 :         cp_parser_require (parser, CPP_LESS, RT_LESS);
    7545                 :             :         /* Parse the type to which we are casting.  */
    7546                 :     7423387 :         saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
    7547                 :     7423387 :         parser->in_type_id_in_expr_p = true;
    7548                 :     7423387 :         type = cp_parser_type_id (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
    7549                 :             :                                   NULL);
    7550                 :     7423387 :         parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
    7551                 :             :         /* Look for the closing `>'.  */
    7552                 :     7423387 :         cp_parser_require (parser, CPP_GREATER, RT_GREATER);
    7553                 :             :         /* Restore the old message.  */
    7554                 :     7423387 :         parser->type_definition_forbidden_message = saved_message;
    7555                 :             : 
    7556                 :     7423387 :         bool saved_greater_than_is_operator_p
    7557                 :             :           = parser->greater_than_is_operator_p;
    7558                 :     7423387 :         parser->greater_than_is_operator_p = true;
    7559                 :             : 
    7560                 :             :         /* And the expression which is being cast.  */
    7561                 :     7423387 :         matching_parens parens;
    7562                 :     7423387 :         parens.require_open (parser);
    7563                 :     7423387 :         expression = cp_parser_expression (parser, & idk, /*cast_p=*/true);
    7564                 :     7423387 :         cp_token *close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN,
    7565                 :             :                                                    RT_CLOSE_PAREN);
    7566                 :     7423387 :         location_t end_loc = close_paren ?
    7567                 :             :           close_paren->location : UNKNOWN_LOCATION;
    7568                 :             : 
    7569                 :     7423387 :         parser->greater_than_is_operator_p
    7570                 :     7423387 :           = saved_greater_than_is_operator_p;
    7571                 :             : 
    7572                 :             :         /* Only type conversions to integral or enumeration types
    7573                 :             :            can be used in constant-expressions.  */
    7574                 :     7423387 :         if (!cast_valid_in_integral_constant_expression_p (type)
    7575                 :     7423387 :             && cp_parser_non_integral_constant_expression (parser, NIC_CAST))
    7576                 :             :           {
    7577                 :           6 :             postfix_expression = error_mark_node;
    7578                 :           6 :             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                 :     7423381 :         location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
    7587                 :             : 
    7588                 :     7423381 :         switch (keyword)
    7589                 :             :           {
    7590                 :       47443 :           case RID_DYNCAST:
    7591                 :       47443 :             postfix_expression
    7592                 :       47443 :               = build_dynamic_cast (cp_cast_loc, type, expression,
    7593                 :             :                                     tf_warning_or_error);
    7594                 :       47443 :             break;
    7595                 :     6446773 :           case RID_STATCAST:
    7596                 :     6446773 :             postfix_expression
    7597                 :     6446773 :               = build_static_cast (cp_cast_loc, type, expression,
    7598                 :             :                                    tf_warning_or_error);
    7599                 :     6446773 :             break;
    7600                 :      469194 :           case RID_REINTCAST:
    7601                 :      469194 :             postfix_expression
    7602                 :      469194 :               = build_reinterpret_cast (cp_cast_loc, type, expression,
    7603                 :             :                                         tf_warning_or_error);
    7604                 :      469194 :             break;
    7605                 :      459971 :           case RID_CONSTCAST:
    7606                 :      459971 :             postfix_expression
    7607                 :      459971 :               = build_const_cast (cp_cast_loc, type, expression,
    7608                 :             :                                   tf_warning_or_error);
    7609                 :      459971 :             break;
    7610                 :             :           default:
    7611                 :             :             gcc_unreachable ();
    7612                 :             :           }
    7613                 :             :       }
    7614                 :     7423381 :       break;
    7615                 :             : 
    7616                 :      129094 :     case RID_TYPEID:
    7617                 :      129094 :       {
    7618                 :      129094 :         tree type;
    7619                 :      129094 :         const char *saved_message;
    7620                 :      129094 :         bool saved_in_type_id_in_expr_p;
    7621                 :             : 
    7622                 :             :         /* Consume the `typeid' token.  */
    7623                 :      129094 :         cp_lexer_consume_token (parser->lexer);
    7624                 :             :         /* Look for the `(' token.  */
    7625                 :      129094 :         matching_parens parens;
    7626                 :      129094 :         parens.require_open (parser);
    7627                 :             :         /* Types cannot be defined in a `typeid' expression.  */
    7628                 :      129094 :         saved_message = parser->type_definition_forbidden_message;
    7629                 :      129094 :         parser->type_definition_forbidden_message
    7630                 :      129094 :           = 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                 :      129094 :         cp_parser_parse_tentatively (parser);
    7634                 :             :         /* Try a type-id first.  */
    7635                 :      129094 :         saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
    7636                 :      129094 :         parser->in_type_id_in_expr_p = true;
    7637                 :      129094 :         type = cp_parser_type_id (parser);
    7638                 :      129094 :         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                 :      129094 :         cp_token *close_paren = parens.require_close (parser);
    7643                 :             :         /* If all went well, simply lookup the type-id.  */
    7644                 :      129094 :         if (cp_parser_parse_definitely (parser))
    7645                 :      126797 :           postfix_expression = get_typeid (type, tf_warning_or_error);
    7646                 :             :         /* Otherwise, fall back to the expression variant.  */
    7647                 :             :         else
    7648                 :             :           {
    7649                 :        2297 :             tree expression;
    7650                 :             : 
    7651                 :             :             /* Look for an expression.  */
    7652                 :        2297 :             expression = cp_parser_expression (parser, & idk);
    7653                 :             :             /* Compute its typeid.  */
    7654                 :        2297 :             postfix_expression = build_typeid (expression, tf_warning_or_error);
    7655                 :             :             /* Look for the `)' token.  */
    7656                 :        2297 :             close_paren = parens.require_close (parser);
    7657                 :             :           }
    7658                 :             :         /* Restore the saved message.  */
    7659                 :      129094 :         parser->type_definition_forbidden_message = saved_message;
    7660                 :             :         /* `typeid' may not appear in an integral constant expression.  */
    7661                 :      129094 :         if (cp_parser_non_integral_constant_expression (parser, NIC_TYPEID))
    7662                 :           1 :           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                 :      129094 :         if (close_paren)
    7670                 :             :           {
    7671                 :      129084 :             location_t typeid_loc
    7672                 :      129084 :               = make_location (start_loc, start_loc, close_paren->location);
    7673                 :      129084 :             postfix_expression.set_location (typeid_loc);
    7674                 :      129084 :             postfix_expression.maybe_add_location_wrapper ();
    7675                 :             :           }
    7676                 :             :       }
    7677                 :      129094 :       break;
    7678                 :             : 
    7679                 :      189585 :     case RID_TYPENAME:
    7680                 :      189585 :       {
    7681                 :      189585 :         tree type;
    7682                 :             :         /* The syntax permitted here is the same permitted for an
    7683                 :             :            elaborated-type-specifier.  */
    7684                 :      189585 :         ++parser->prevent_constrained_type_specifiers;
    7685                 :      189585 :         type = cp_parser_elaborated_type_specifier (parser,
    7686                 :             :                                                     /*is_friend=*/false,
    7687                 :             :                                                     /*is_declaration=*/false);
    7688                 :      189585 :         --parser->prevent_constrained_type_specifiers;
    7689                 :      189585 :         postfix_expression = cp_parser_functional_cast (parser, type);
    7690                 :             :       }
    7691                 :      189585 :       break;
    7692                 :             : 
    7693                 :      187488 :     case RID_ADDRESSOF:
    7694                 :      187488 :     case RID_BUILTIN_SHUFFLE:
    7695                 :      187488 :     case RID_BUILTIN_SHUFFLEVECTOR:
    7696                 :      187488 :     case RID_BUILTIN_LAUNDER:
    7697                 :      187488 :     case RID_BUILTIN_ASSOC_BARRIER:
    7698                 :      187488 :       {
    7699                 :      187488 :         vec<tree, va_gc> *vec;
    7700                 :             : 
    7701                 :      187488 :         cp_lexer_consume_token (parser->lexer);
    7702                 :      187488 :         vec = cp_parser_parenthesized_expression_list (parser, non_attr,
    7703                 :             :                     /*cast_p=*/false, /*allow_expansion_p=*/true,
    7704                 :             :                     /*non_constant_p=*/NULL);
    7705                 :      187488 :         if (vec == NULL)
    7706                 :             :           {
    7707                 :           0 :             postfix_expression = error_mark_node;
    7708                 :           0 :             break;
    7709                 :             :           }
    7710                 :             : 
    7711                 :      872195 :         for (tree p : *vec)
    7712                 :      684707 :           mark_exp_read (p);
    7713                 :             : 
    7714                 :      187488 :         switch (keyword)
    7715                 :             :           {
    7716                 :      124884 :           case RID_ADDRESSOF:
    7717                 :      124884 :             if (vec->length () == 1)
    7718                 :      124884 :               postfix_expression
    7719                 :      124884 :                 = cp_build_addressof (loc, (*vec)[0], tf_warning_or_error);
    7720                 :             :             else
    7721                 :             :               {
    7722                 :           0 :                 error_at (loc, "wrong number of arguments to "
    7723                 :             :                                "%<__builtin_addressof%>");
    7724                 :           0 :                 postfix_expression = error_mark_node;
    7725                 :             :               }
    7726                 :             :             break;
    7727                 :             : 
    7728                 :       11819 :           case RID_BUILTIN_LAUNDER:
    7729                 :       11819 :             if (vec->length () == 1)
    7730                 :       11810 :               postfix_expression = finish_builtin_launder (loc, (*vec)[0],
    7731                 :             :                                                            tf_warning_or_error);
    7732                 :             :             else
    7733                 :             :               {
    7734                 :           9 :                 error_at (loc, "wrong number of arguments to "
    7735                 :             :                                "%<__builtin_launder%>");
    7736                 :           9 :                 postfix_expression = error_mark_node;
    7737                 :             :               }
    7738                 :             :             break;
    7739                 :             : 
    7740                 :          11 :           case RID_BUILTIN_ASSOC_BARRIER:
    7741                 :          11 :             if (vec->length () == 1)
    7742                 :          11 :               postfix_expression = build1_loc (loc, PAREN_EXPR,
    7743                 :          11 :                                                TREE_TYPE ((*vec)[0]),
    7744                 :          11 :                                                (*vec)[0]);
    7745                 :             :             else
    7746                 :             :               {
    7747                 :           0 :                 error_at (loc, "wrong number of arguments to "
    7748                 :             :                                "%<__builtin_assoc_barrier%>");
    7749                 :           0 :                 postfix_expression = error_mark_node;
    7750                 :             :               }
    7751                 :             :             break;
    7752                 :             : 
    7753                 :       15226 :           case RID_BUILTIN_SHUFFLE:
    7754                 :       15226 :             if (vec->length () == 2)
    7755                 :       14365 :               postfix_expression
    7756                 :       14365 :                 = build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE,
    7757                 :       14365 :                                          (*vec)[1], tf_warning_or_error);
    7758                 :         861 :             else if (vec->length () == 3)
    7759                 :         861 :               postfix_expression
    7760                 :         861 :                 = build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1],
    7761                 :         861 :                                          (*vec)[2], tf_warning_or_error);
    7762                 :             :             else
    7763                 :             :               {
    7764                 :           0 :                 error_at (loc, "wrong number of arguments to "
    7765                 :             :                                "%<__builtin_shuffle%>");
    7766                 :           0 :                 postfix_expression = error_mark_node;
    7767                 :             :               }
    7768                 :             :             break;
    7769                 :             : 
    7770                 :       35548 :           case RID_BUILTIN_SHUFFLEVECTOR:
    7771                 :       35548 :             if (vec->length () < 3)
    7772                 :             :               {
    7773                 :           0 :                 error_at (loc, "wrong number of arguments to "
    7774                 :             :                                "%<__builtin_shufflevector%>");
    7775                 :           0 :                 postfix_expression = error_mark_node;
    7776                 :             :               }
    7777                 :             :             else
    7778                 :             :               {
    7779                 :       35548 :                 postfix_expression
    7780                 :       35548 :                   = build_x_shufflevector (loc, vec, tf_warning_or_error);
    7781                 :             :               }
    7782                 :             :             break;
    7783                 :             : 
    7784                 :           0 :           default:
    7785                 :           0 :             gcc_unreachable ();
    7786                 :             :           }
    7787                 :             :         break;
    7788                 :             :       }
    7789                 :             : 
    7790                 :         185 :     case RID_BUILTIN_CONVERTVECTOR:
    7791                 :         185 :       {
    7792                 :         185 :         tree expression;
    7793                 :         185 :         tree type;
    7794                 :             :         /* Consume the `__builtin_convertvector' token.  */
    7795                 :         185 :         cp_lexer_consume_token (parser->lexer);
    7796                 :             :         /* Look for the opening `('.  */
    7797                 :         185 :         matching_parens parens;
    7798                 :         185 :         parens.require_open (parser);
    7799                 :             :         /* Now, parse the assignment-expression.  */
    7800                 :         185 :         expression = cp_parser_assignment_expression (parser);
    7801                 :             :         /* Look for the `,'.  */
    7802                 :         185 :         cp_parser_require (parser, CPP_COMMA, RT_COMMA);
    7803                 :         185 :         location_t type_location
    7804                 :         185 :           = cp_lexer_peek_token (parser->lexer)->location;
    7805                 :             :         /* Parse the type-id.  */
    7806                 :         185 :         {
    7807                 :         185 :           type_id_in_expr_sentinel s (parser);
    7808                 :         185 :           type = cp_parser_type_id (parser);
    7809                 :         185 :         }
    7810                 :             :         /* Look for the closing `)'.  */
    7811                 :         185 :         parens.require_close (parser);
    7812                 :         185 :         postfix_expression
    7813                 :         185 :           = cp_build_vec_convert (expression, type_location, type,
    7814                 :             :                                   tf_warning_or_error);
    7815                 :         185 :         break;
    7816                 :             :       }
    7817                 :             : 
    7818                 :       25447 :     case RID_BUILTIN_BIT_CAST:
    7819                 :       25447 :       {
    7820                 :       25447 :         tree expression;
    7821                 :       25447 :         tree type;
    7822                 :             :         /* Consume the `__builtin_bit_cast' token.  */
    7823                 :       25447 :         cp_lexer_consume_token (parser->lexer);
    7824                 :             :         /* Look for the opening `('.  */
    7825                 :       25447 :         matching_parens parens;
    7826                 :       25447 :         parens.require_open (parser);
    7827                 :       25447 :         location_t type_location
    7828                 :       25447 :           = cp_lexer_peek_token (parser->lexer)->location;
    7829                 :             :         /* Parse the type-id.  */
    7830                 :       25447 :         {
    7831                 :       25447 :           type_id_in_expr_sentinel s (parser);
    7832                 :       25447 :           type = cp_parser_type_id (parser);
    7833                 :       25447 :         }
    7834                 :             :         /* Look for the `,'.  */
    7835                 :       25447 :         cp_parser_require (parser, CPP_COMMA, RT_COMMA);
    7836                 :             :         /* Now, parse the assignment-expression.  */
    7837                 :       25447 :         expression = cp_parser_assignment_expression (parser);
    7838                 :             :         /* Look for the closing `)'.  */
    7839                 :       25447 :         parens.require_close (parser);
    7840                 :       25447 :         postfix_expression
    7841                 :       25447 :           = cp_build_bit_cast (type_location, type, expression,
    7842                 :             :                                tf_warning_or_error);
    7843                 :       25447 :         break;
    7844                 :             :       }
    7845                 :             : 
    7846                 :   828848200 :     default:
    7847                 :   828848200 :       {
    7848                 :   828848200 :         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                 :   828848200 :         cp_parser_parse_tentatively (parser);
    7855                 :             :         /* Look for the simple-type-specifier.  */
    7856                 :   828848200 :         ++parser->prevent_constrained_type_specifiers;
    7857                 :   828848200 :         type = cp_parser_simple_type_specifier (parser,
    7858                 :             :                                                 /*decl_specs=*/NULL,
    7859                 :             :                                                 CP_PARSER_FLAGS_NONE);
    7860                 :   828848200 :         --parser->prevent_constrained_type_specifiers;
    7861                 :             :         /* Parse the cast itself.  */
    7862                 :  1695465317 :         if (!cp_parser_error_occurred (parser))
    7863                 :    37768917 :           postfix_expression
    7864                 :    37768917 :             = cp_parser_functional_cast (parser, type);
    7865                 :             :         /* If that worked, we're done.  */
    7866                 :   828848200 :         if (cp_parser_parse_definitely (parser))
    7867                 :             :           break;
    7868                 :             : 
    7869                 :             :         /* If the functional-cast didn't work out, try a
    7870                 :             :            compound-literal.  */
    7871                 :   791079890 :         if (cp_parser_allow_gnu_extensions_p (parser)
    7872                 :   791079890 :             && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    7873                 :             :           {
    7874                 :    25632719 :             cp_expr initializer = NULL_TREE;
    7875                 :             : 
    7876                 :    25632719 :             cp_parser_parse_tentatively (parser);
    7877                 :             : 
    7878                 :    25632719 :             matching_parens parens;
    7879                 :    25632719 :             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                 :    25632719 :             if (!cp_parser_compound_literal_p (parser))
    7884                 :    51232410 :               cp_parser_simulate_error (parser);
    7885                 :             :             else
    7886                 :             :               {
    7887                 :             :                 /* Parse the type.  */
    7888                 :       33028 :                 bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
    7889                 :       33028 :                 parser->in_type_id_in_expr_p = true;
    7890                 :       33028 :                 type = cp_parser_type_id (parser);
    7891                 :       33028 :                 parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
    7892                 :       33028 :                 parens.require_close (parser);
    7893                 :             :               }
    7894                 :             : 
    7895                 :             :             /* If things aren't going well, there's no need to
    7896                 :             :                keep going.  */
    7897                 :    51298329 :             if (!cp_parser_error_occurred (parser))
    7898                 :             :               /* Parse the brace-enclosed initializer list.  */
    7899                 :       32891 :               initializer = cp_parser_braced_list (parser);
    7900                 :             :             /* If that worked, we're definitely looking at a
    7901                 :             :                compound-literal expression.  */
    7902                 :    25632719 :             if (cp_parser_parse_definitely (parser))
    7903                 :             :               {
    7904                 :             :                 /* Warn the user that a compound literal is not
    7905                 :             :                    allowed in standard C++.  */
    7906                 :       32883 :                 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                 :       32883 :                 if (cp_parser_non_integral_constant_expression (parser,
    7918                 :             :                                                                 NIC_NCC))
    7919                 :             :                   {
    7920                 :           0 :                     postfix_expression = error_mark_node;
    7921                 :       32883 :                     break;
    7922                 :             :                   }
    7923                 :             :                 /* Form the representation of the compound-literal.  */
    7924                 :       32883 :                 postfix_expression
    7925                 :       32883 :                   = finish_compound_literal (type, initializer,
    7926                 :             :                                              tf_warning_or_error, fcl_c99);
    7927                 :       32883 :                 postfix_expression.set_location (initializer.get_location ());
    7928                 :       32883 :                 break;
    7929                 :             :               }
    7930                 :             :           }
    7931                 :             : 
    7932                 :             :         /* It must be a primary-expression.  */
    7933                 :   791047007 :         postfix_expression
    7934                 :   791047007 :           = cp_parser_primary_expression (parser, address_p, cast_p,
    7935                 :             :                                           /*template_arg_p=*/false,
    7936                 :             :                                           decltype_p,
    7937                 :             :                                           &idk);
    7938                 :             :       }
    7939                 :   791047003 :       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                 :  1141996352 :   while (true)
    7949                 :             :     {
    7950                 :  1141996352 :       if (idk == CP_ID_KIND_UNQUALIFIED
    7951                 :   167434191 :           && identifier_p (postfix_expression)
    7952                 :  1142105421 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
    7953                 :             :         /* It is not a Koenig lookup function call.  */
    7954                 :        1442 :         postfix_expression
    7955                 :        1442 :           = unqualified_name_lookup_error (postfix_expression);
    7956                 :             : 
    7957                 :             :       /* Peek at the next token.  */
    7958                 :  1141996352 :       token = cp_lexer_peek_token (parser->lexer);
    7959                 :             : 
    7960                 :  1141996352 :       switch (token->type)
    7961                 :             :         {
    7962                 :     9681863 :         case CPP_OPEN_SQUARE:
    7963                 :     9681863 :           if (cp_next_tokens_can_be_std_attribute_p (parser))
    7964                 :             :             {
    7965                 :          10 :               cp_parser_error (parser,
    7966                 :             :                                "two consecutive %<[%> shall "
    7967                 :             :                                "only introduce an attribute");
    7968                 :          10 :               return error_mark_node;
    7969                 :             :             }
    7970                 :     9681853 :           postfix_expression
    7971                 :     9681853 :             = cp_parser_postfix_open_square_expression (parser,
    7972                 :             :                                                         postfix_expression,
    7973                 :             :                                                         false,
    7974                 :             :                                                         decltype_p);
    7975                 :     9681853 :           postfix_expression.set_range (start_loc,
    7976                 :             :                                         postfix_expression.get_location ());
    7977                 :             : 
    7978                 :     9681853 :           idk = CP_ID_KIND_NONE;
    7979                 :     9681853 :           is_member_access = false;
    7980                 :     9681853 :           break;
    7981                 :             : 
    7982                 :   184092422 :         case CPP_OPEN_PAREN:
    7983                 :             :           /* postfix-expression ( expression-list [opt] ) */
    7984                 :   184092422 :           {
    7985                 :   184092422 :             bool koenig_p;
    7986                 :   184092422 :             bool is_builtin_constant_p;
    7987                 :   184092422 :             bool saved_integral_constant_expression_p = false;
    7988                 :   184092422 :             bool saved_non_integral_constant_expression_p = false;
    7989                 :   184092422 :             tsubst_flags_t complain = complain_flags (decltype_p);
    7990                 :   184092422 :             vec<tree, va_gc> *args;
    7991                 :   184092422 :             location_t close_paren_loc = UNKNOWN_LOCATION;
    7992                 :   184092422 :             location_t combined_loc = UNKNOWN_LOCATION;
    7993                 :             : 
    7994                 :   184092422 :             is_member_access = false;
    7995                 :             : 
    7996                 :   184092422 :             tree stripped_expression
    7997                 :   184092422 :               = tree_strip_any_location_wrapper (postfix_expression);
    7998                 :   184092422 :             is_builtin_constant_p
    7999                 :   184092422 :               = DECL_IS_BUILTIN_CONSTANT_P (stripped_expression);
    8000                 :   184092422 :             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                 :       58365 :                 saved_integral_constant_expression_p
    8005                 :       58365 :                   = parser->integral_constant_expression_p;
    8006                 :       58365 :                 saved_non_integral_constant_expression_p
    8007                 :       58365 :                   = parser->non_integral_constant_expression_p;
    8008                 :       58365 :                 parser->integral_constant_expression_p = false;
    8009                 :             :               }
    8010                 :   184034057 :             else if (TREE_CODE (stripped_expression) == FUNCTION_DECL
    8011                 :   184034057 :                      && fndecl_built_in_p (stripped_expression,
    8012                 :             :                                            BUILT_IN_CLASSIFY_TYPE))
    8013                 :             :               {
    8014                 :             :                 /* __builtin_classify_type (type)  */
    8015                 :         408 :                 auto cl1 = make_temp_override
    8016                 :         408 :                              (parser->type_definition_forbidden_message,
    8017                 :             :                               G_("types may not be defined in "
    8018                 :         408 :                                  "%<__builtin_classify_type%> calls"));
    8019                 :         408 :                 auto cl2 = make_temp_override
    8020                 :         408 :                              (parser->type_definition_forbidden_message_arg,
    8021                 :         408 :                               NULL);
    8022                 :         408 :                 auto cl3 = make_temp_override (parser->in_type_id_in_expr_p,
    8023                 :         408 :                                                true);
    8024                 :         408 :                 cp_unevaluated uev;
    8025                 :         408 :                 cp_parser_parse_tentatively (parser);
    8026                 :         408 :                 matching_parens parens;
    8027                 :         408 :                 parens.consume_open (parser);
    8028                 :         408 :                 tree type = cp_parser_type_id (parser);
    8029                 :         408 :                 parens.require_close (parser);
    8030                 :         408 :                 if (cp_parser_parse_definitely (parser))
    8031                 :             :                   {
    8032                 :         258 :                     if (dependent_type_p (type))
    8033                 :             :                       {
    8034                 :          99 :                         postfix_expression = build_vl_exp (CALL_EXPR, 4);
    8035                 :          99 :                         CALL_EXPR_FN (postfix_expression)
    8036                 :          99 :                           = stripped_expression;
    8037                 :          99 :                         CALL_EXPR_STATIC_CHAIN (postfix_expression) = type;
    8038                 :          99 :                         CALL_EXPR_ARG (postfix_expression, 0)
    8039                 :          99 :                           = build_min (SIZEOF_EXPR, size_type_node, type);
    8040                 :          99 :                         TREE_TYPE (postfix_expression) = integer_type_node;
    8041                 :             :                       }
    8042                 :             :                     else
    8043                 :             :                       {
    8044                 :         159 :                         postfix_expression
    8045                 :         159 :                           = build_int_cst (integer_type_node,
    8046                 :         159 :                                            type_to_class (type));
    8047                 :             :                       }
    8048                 :         258 :                     break;
    8049                 :             :                   }
    8050                 :         408 :               }
    8051                 :   368184328 :             args = (cp_parser_parenthesized_expression_list
    8052                 :   184092164 :                     (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                 :   184092164 :             if (is_builtin_constant_p)
    8058                 :             :               {
    8059                 :       58365 :                 parser->integral_constant_expression_p
    8060                 :       58365 :                   = saved_integral_constant_expression_p;
    8061                 :       58365 :                 parser->non_integral_constant_expression_p
    8062                 :       58365 :                   = saved_non_integral_constant_expression_p;
    8063                 :             :               }
    8064                 :             : 
    8065                 :   184092164 :             if (args == NULL)
    8066                 :             :               {
    8067                 :          32 :                 postfix_expression = error_mark_node;
    8068                 :          32 :                 break;
    8069                 :             :               }
    8070                 :             : 
    8071                 :             :             /* Function calls are not permitted in
    8072                 :             :                constant-expressions.  */
    8073                 :   184092132 :             if (! builtin_valid_in_constant_expr_p (postfix_expression)
    8074                 :   184092132 :                 && cp_parser_non_integral_constant_expression (parser,
    8075                 :             :                                                                NIC_FUNC_CALL))
    8076                 :             :               {
    8077                 :           4 :                 postfix_expression = error_mark_node;
    8078                 :           4 :                 release_tree_vector (args);
    8079                 :           4 :                 break;
    8080                 :             :               }
    8081                 :             : 
    8082                 :   184092128 :             koenig_p = false;
    8083                 :   184092128 :             if (idk == CP_ID_KIND_UNQUALIFIED
    8084                 :   159074445 :                 || idk == CP_ID_KIND_TEMPLATE_ID)
    8085                 :             :               {
    8086                 :    29099488 :                 if (identifier_p (postfix_expression)
    8087                 :             :                     /* In C++20, we may need to perform ADL for a template
    8088                 :             :                        name.  */
    8089                 :    28991871 :                     || (TREE_CODE (postfix_expression) == TEMPLATE_ID_EXPR
    8090                 :     1728833 :                         && identifier_p (TREE_OPERAND (postfix_expression, 0))))
    8091                 :             :                   {
    8092                 :      107640 :                     if (!args->is_empty ())
    8093                 :             :                       {
    8094                 :      107475 :                         koenig_p = true;
    8095                 :      107475 :                         if (!any_type_dependent_arguments_p (args))
    8096                 :       20544 :                           postfix_expression
    8097                 :       20544 :                             = perform_koenig_lookup (postfix_expression, args,
    8098                 :             :                                                      complain);
    8099                 :             :                       }
    8100                 :             :                     else
    8101                 :         165 :                       postfix_expression
    8102                 :         165 :                         = 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                 :    28991848 :                 else if (!args->is_empty ()
    8108                 :    28991848 :                          && 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                 :    23012368 :                     bool do_adl_p = true;
    8114                 :    23012368 :                     tree fns = get_fns (postfix_expression);
    8115                 :    65540298 :                     for (lkp_iterator iter (fns); iter; ++iter)
    8116                 :             :                       {
    8117                 :    45241359 :                         tree fn = STRIP_TEMPLATE (*iter);
    8118                 :    45241359 :                         if ((TREE_CODE (fn) == USING_DECL
    8119                 :          11 :                              && DECL_DEPENDENT_P (fn))
    8120                 :    45241348 :                             || DECL_FUNCTION_MEMBER_P (fn)
    8121                 :    87769436 :                             || DECL_LOCAL_DECL_P (fn))
    8122                 :             :                           {
    8123                 :             :                             do_adl_p = false;
    8124                 :             :                             break;
    8125                 :             :                           }
    8126                 :             :                       }
    8127                 :             : 
    8128                 :    23012368 :                     if (do_adl_p)
    8129                 :             :                       {
    8130                 :    20298939 :                         koenig_p = true;
    8131                 :    20298939 :                         if (!any_type_dependent_arguments_p (args))
    8132                 :    12463856 :                           postfix_expression
    8133                 :    12463856 :                             = 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                 :   184092128 :             if (close_paren_loc != UNKNOWN_LOCATION)
    8146                 :   184091878 :               combined_loc = make_location (token->location, start_loc,
    8147                 :             :                                             close_paren_loc);
    8148                 :   184092128 :             iloc_sentinel ils (combined_loc);
    8149                 :             : 
    8150                 :   184092128 :             if (TREE_CODE (postfix_expression) == OFFSET_REF
    8151                 :             :                 || TREE_CODE (postfix_expression) == MEMBER_REF
    8152                 :             :                 || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
    8153                 :      235254 :               postfix_expression = (build_offset_ref_call_from_tree
    8154                 :             :                                     (postfix_expression, &args,
    8155                 :             :                                      complain));
    8156                 :             :             else
    8157                 :             :               /* All other function calls.  */
    8158                 :             :               {
    8159                 :   183856874 :                 if (DECL_P (postfix_expression)
    8160                 :    10575590 :                     && parser->omp_for_parse_state
    8161                 :         764 :                     && parser->omp_for_parse_state->in_intervening_code
    8162                 :   183857264 :                     && omp_runtime_api_call (postfix_expression))
    8163                 :             :                   {
    8164                 :          14 :                     error_at (loc, "calls to the OpenMP runtime API are "
    8165                 :             :                                    "not permitted in intervening code");
    8166                 :          14 :                     parser->omp_for_parse_state->fail = true;
    8167                 :             :                   }
    8168                 :   183856874 :                 bool disallow_virtual = (idk == CP_ID_KIND_QUALIFIED);
    8169                 :   183856874 :                 postfix_expression
    8170                 :   183856874 :                   = finish_call_expr (postfix_expression, &args,
    8171                 :             :                                       disallow_virtual,
    8172                 :             :                                       koenig_p,
    8173                 :             :                                       complain);
    8174                 :             :               }
    8175                 :             : 
    8176                 :   184092115 :             if (close_paren_loc != UNKNOWN_LOCATION)
    8177                 :   184091865 :               postfix_expression.set_location (combined_loc);
    8178                 :             : 
    8179                 :             :             /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
    8180                 :   184092115 :             idk = CP_ID_KIND_NONE;
    8181                 :             : 
    8182                 :   184092115 :             release_tree_vector (args);
    8183                 :   184092115 :           }
    8184                 :   184092115 :           break;
    8185                 :             : 
    8186                 :   109325900 :         case CPP_DOT:
    8187                 :   109325900 :         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                 :   109325900 :           cp_lexer_consume_token (parser->lexer);
    8195                 :             : 
    8196                 :   109325900 :           postfix_expression
    8197                 :   109325900 :             = cp_parser_postfix_dot_deref_expression (parser, token->type,
    8198                 :             :                                                       postfix_expression,
    8199                 :             :                                                       false, &idk, loc);
    8200                 :             : 
    8201                 :   109325896 :           is_member_access = true;
    8202                 :   109325896 :           break;
    8203                 :             : 
    8204                 :     1717423 :         case CPP_PLUS_PLUS:
    8205                 :             :           /* postfix-expression ++  */
    8206                 :             :           /* Consume the `++' token.  */
    8207                 :     1717423 :           cp_lexer_consume_token (parser->lexer);
    8208                 :             :           /* Generate a representation for the complete expression.  */
    8209                 :     1717423 :           postfix_expression
    8210                 :     1717423 :             = finish_increment_expr (postfix_expression,
    8211                 :             :                                      POSTINCREMENT_EXPR);
    8212                 :             :           /* Increments may not appear in constant-expressions.  */
    8213                 :     1717423 :           if (cp_parser_non_integral_constant_expression (parser, NIC_INC))
    8214                 :           0 :             postfix_expression = error_mark_node;
    8215                 :     1717423 :           idk = CP_ID_KIND_NONE;
    8216                 :     1717423 :           is_member_access = false;
    8217                 :     1717423 :           break;
    8218                 :             : 
    8219                 :      375389 :         case CPP_MINUS_MINUS:
    8220                 :             :           /* postfix-expression -- */
    8221                 :             :           /* Consume the `--' token.  */
    8222                 :      375389 :           cp_lexer_consume_token (parser->lexer);
    8223                 :             :           /* Generate a representation for the complete expression.  */
    8224                 :      375389 :           postfix_expression
    8225                 :      375389 :             = finish_increment_expr (postfix_expression,
    8226                 :             :                                      POSTDECREMENT_EXPR);
    8227                 :             :           /* Decrements may not appear in constant-expressions.  */
    8228                 :      375389 :           if (cp_parser_non_integral_constant_expression (parser, NIC_DEC))
    8229                 :           0 :             postfix_expression = error_mark_node;
    8230                 :      375389 :           idk = CP_ID_KIND_NONE;
    8231                 :      375389 :           is_member_access = false;
    8232                 :      375389 :           break;
    8233                 :             : 
    8234                 :   836803355 :         default:
    8235                 :   836803355 :           if (pidk_return != NULL)
    8236                 :    32982770 :             * pidk_return = idk;
    8237                 :   836803355 :           if (member_access_only_p)
    8238                 :     2283363 :             return is_member_access
    8239                 :     2283363 :               ? postfix_expression
    8240                 :     2283363 :               : cp_expr (error_mark_node);
    8241                 :             :           else
    8242                 :   834519992 :             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                 :             : 
    8251                 :             : static cp_expr
    8252                 :   280763209 : cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p,
    8253                 :             :                                              bool allow_expansion_p,
    8254                 :             :                                              bool *non_constant_p)
    8255                 :             : {
    8256                 :   280763209 :   cp_expr expr (NULL_TREE);
    8257                 :   280763209 :   bool expr_non_constant_p;
    8258                 :             : 
    8259                 :             :   /* Parse the next assignment-expression.  */
    8260                 :   280763209 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    8261                 :             :     {
    8262                 :             :       /* A braced-init-list.  */
    8263                 :      131360 :       cp_lexer_set_source_position (parser->lexer);
    8264                 :      131360 :       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
    8265                 :      260447 :       expr = cp_parser_braced_list (parser,
    8266                 :             :                                     (non_constant_p != nullptr
    8267                 :             :                                     ? &expr_non_constant_p
    8268                 :             :                                     : nullptr));
    8269                 :      131360 :       if (non_constant_p && expr_non_constant_p)
    8270                 :          21 :         *non_constant_p = true;
    8271                 :             :     }
    8272                 :   280631849 :   else if (non_constant_p)
    8273                 :             :     {
    8274                 :     5576812 :       expr = cp_parser_constant_expression (parser,
    8275                 :             :                                             /*allow_non_constant_p=*/true,
    8276                 :             :                                             &expr_non_constant_p);
    8277                 :     5576812 :       if (expr_non_constant_p)
    8278                 :     1958012 :         *non_constant_p = true;
    8279                 :             :     }
    8280                 :             :   else
    8281                 :   275055037 :     expr = cp_parser_assignment_expression (parser, /*pidk=*/NULL, cast_p);
    8282                 :             : 
    8283                 :             :   /* If we have an ellipsis, then this is an expression expansion.  */
    8284                 :   280763209 :   if (allow_expansion_p
    8285                 :   280763209 :       && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    8286                 :             :     {
    8287                 :             :       /* Consume the `...'.  */
    8288                 :     2968340 :       cp_lexer_consume_token (parser->lexer);
    8289                 :             : 
    8290                 :             :       /* Build the argument pack.  */
    8291                 :     2968340 :       expr = make_pack_expansion (expr);
    8292                 :             :     }
    8293                 :   280763209 :   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                 :             : 
    8306                 :             : static tree
    8307                 :     9682765 : cp_parser_postfix_open_square_expression (cp_parser *parser,
    8308                 :             :                                           tree postfix_expression,
    8309                 :             :                                           bool for_offsetof,
    8310                 :             :                                           bool decltype_p)
    8311                 :             : {
    8312                 :     9682765 :   tree index = NULL_TREE;
    8313                 :     9682765 :   releasing_vec expression_list = NULL;
    8314                 :     9682765 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
    8315                 :     9682765 :   bool saved_greater_than_is_operator_p;
    8316                 :     9682765 :   bool saved_colon_corrects_to_scope_p;
    8317                 :             : 
    8318                 :             :   /* Consume the `[' token.  */
    8319                 :     9682765 :   cp_lexer_consume_token (parser->lexer);
    8320                 :             : 
    8321                 :     9682765 :   saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
    8322                 :     9682765 :   parser->greater_than_is_operator_p = true;
    8323                 :             : 
    8324                 :     9682765 :   saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
    8325                 :     9682765 :   if (parser->omp_array_section_p)
    8326                 :        2999 :     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                 :     9682765 :   if (for_offsetof)
    8337                 :         912 :     index = cp_parser_constant_expression (parser);
    8338                 :     9681853 :   else if (!parser->omp_array_section_p
    8339                 :     9681853 :            || cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
    8340                 :             :     {
    8341                 :     9681296 :       if (cxx_dialect >= cxx23
    8342                 :     9681296 :           && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
    8343                 :          86 :         *&expression_list = make_tree_vector ();
    8344                 :     9681210 :       else if (cxx_dialect >= cxx23)
    8345                 :             :         {
    8346                 :     1169079 :           while (true)
    8347                 :             :             {
    8348                 :     1169010 :               cp_expr expr
    8349                 :     1169010 :                 = cp_parser_parenthesized_expression_list_elt (parser,
    8350                 :             :                                                                /*cast_p=*/
    8351                 :             :                                                                false,
    8352                 :             :                                                                /*allow_exp_p=*/
    8353                 :             :                                                                true,
    8354                 :             :                                                                /*non_cst_p=*/
    8355                 :             :                                                                NULL);
    8356                 :             : 
    8357                 :     1169010 :               if (expr == error_mark_node)
    8358                 :             :                 index = error_mark_node;
    8359                 :     1169010 :               else if (expression_list.get () == NULL
    8360                 :     1169010 :                        && !PACK_EXPANSION_P (expr.get_value ()))
    8361                 :             :                 index = expr.get_value ();
    8362                 :             :               else
    8363                 :          73 :                 vec_safe_push (expression_list, expr.get_value ());
    8364                 :             : 
    8365                 :             :               /* If the next token isn't a `,', then we are done.  */
    8366                 :     1169010 :               if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
    8367                 :             :                 break;
    8368                 :             : 
    8369                 :          69 :               if (expression_list.get () == NULL && index != error_mark_node)
    8370                 :             :                 {
    8371                 :          51 :                   *&expression_list = make_tree_vector_single (index);
    8372                 :          51 :                   index = NULL_TREE;
    8373                 :             :                 }
    8374                 :             : 
    8375                 :             :               /* Otherwise, consume the `,' and keep going.  */
    8376                 :          69 :               cp_lexer_consume_token (parser->lexer);
    8377                 :          69 :             }
    8378                 :     1168941 :           if (expression_list.get () && index == error_mark_node)
    8379                 :           0 :             expression_list.release ();
    8380                 :             :         }
    8381                 :     8512269 :       else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    8382                 :             :         {
    8383                 :          32 :           cp_lexer_set_source_position (parser->lexer);
    8384                 :          32 :           maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
    8385                 :          32 :           index = cp_parser_braced_list (parser);
    8386                 :             :         }
    8387                 :             :       else
    8388                 :     8512237 :         index = cp_parser_expression (parser, NULL, /*cast_p=*/false,
    8389                 :             :                                       /*decltype_p=*/false,
    8390                 :     8512237 :                                       /*warn_comma_p=*/warn_comma_subscript);
    8391                 :             :     }
    8392                 :             : 
    8393                 :     9682765 :   parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
    8394                 :             : 
    8395                 :     9682765 :   if (cxx_dialect >= cxx23
    8396                 :     1169029 :       && parser->omp_array_section_p
    8397                 :           6 :       && expression_list.get () != NULL
    8398                 :     9682769 :       && vec_safe_length (expression_list) > 1)
    8399                 :             :     {
    8400                 :           4 :       error_at (loc, "cannot use multidimensional subscript in OpenMP array "
    8401                 :             :                 "section");
    8402                 :           4 :       index = error_mark_node;
    8403                 :             :     }
    8404                 :     9682765 :   if (parser->omp_array_section_p
    8405                 :     9682765 :       && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    8406                 :             :     {
    8407                 :        2385 :       cp_lexer_consume_token (parser->lexer);
    8408                 :        2385 :       tree length = NULL_TREE;
    8409                 :        2385 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE))
    8410                 :             :         {
    8411                 :        2103 :           if (cxx_dialect >= cxx23)
    8412                 :             :             {
    8413                 :           4 :               cp_expr expr
    8414                 :           4 :                 = cp_parser_parenthesized_expression_list_elt (parser,
    8415                 :             :                                                                /*cast_p=*/
    8416                 :             :                                                                false,
    8417                 :             :                                                                /*allow_exp_p=*/
    8418                 :             :                                                                true,
    8419                 :             :                                                                /*non_cst_p=*/
    8420                 :             :                                                                NULL);
    8421                 :             : 
    8422                 :           4 :               if (expr == error_mark_node)
    8423                 :             :                 length = error_mark_node;
    8424                 :             :               else
    8425                 :             :                 length = expr.get_value ();
    8426                 :             : 
    8427                 :           4 :               if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
    8428                 :             :                 {
    8429                 :           4 :                   error_at (loc, "cannot use multidimensional subscript in "
    8430                 :             :                             "OpenMP array section");
    8431                 :           4 :                   length = error_mark_node;
    8432                 :             :                 }
    8433                 :             :             }
    8434                 :             :           else
    8435                 :        2099 :             length
    8436                 :        2099 :               = cp_parser_expression (parser, NULL, /*cast_p=*/false,
    8437                 :             :                                       /*decltype_p=*/false,
    8438                 :        2099 :                                       /*warn_comma_p=*/warn_comma_subscript);
    8439                 :             :         }
    8440                 :             : 
    8441                 :        2385 :       parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
    8442                 :             : 
    8443                 :        2385 :       if (index == error_mark_node || length == error_mark_node)
    8444                 :             :         {
    8445                 :           6 :           cp_parser_skip_to_closing_square_bracket (parser);
    8446                 :           6 :           return error_mark_node;
    8447                 :             :         }
    8448                 :             :       else
    8449                 :        2379 :         cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
    8450                 :             : 
    8451                 :        2379 :       return grok_omp_array_section (input_location, postfix_expression, index,
    8452                 :        2379 :                                      length);
    8453                 :             :     }
    8454                 :             : 
    8455                 :     9680380 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
    8456                 :             : 
    8457                 :             :   /* Look for the closing `]'.  */
    8458                 :     9680380 :   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
    8459                 :             : 
    8460                 :             :   /* Build the ARRAY_REF.  */
    8461                 :    19360634 :   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                 :     9680380 :   if (!for_offsetof
    8469                 :     9680380 :       && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
    8470                 :           5 :     postfix_expression = error_mark_node;
    8471                 :             : 
    8472                 :             :   return postfix_expression;
    8473                 :     9682765 : }
    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                 :             : 
    8480                 :             : bool
    8481                 :          66 : cp_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                 :          66 :   diagnostic_t kind = (processing_template_decl
    8487                 :          66 :                        && MAYBE_CLASS_TYPE_P (*scope) ? DK_PEDWARN : DK_ERROR);
    8488                 :             : 
    8489                 :          66 :   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                 :          39 :       kind = DK_IGNORED;
    8504                 :             :       break;
    8505                 :          36 :     default:
    8506                 :             :       /* Avoid clobbering e.g. DECLs.  */
    8507                 :          36 :       if (!EXPR_P (*postfix_expression))
    8508                 :             :         kind = DK_ERROR;
    8509                 :             :       break;
    8510                 :             :     }
    8511                 :             : 
    8512                 :             :   if (kind == DK_IGNORED)
    8513                 :             :     return false;
    8514                 :             : 
    8515                 :          62 :   location_t exploc = location_of (*postfix_expression);
    8516                 :          62 :   cxx_incomplete_type_diagnostic (exploc, *postfix_expression, *scope, kind);
    8517                 :          62 :   if (!MAYBE_CLASS_TYPE_P (*scope))
    8518                 :             :     return true;
    8519                 :          35 :   if (kind == DK_ERROR)
    8520                 :          31 :     *scope = *postfix_expression = error_mark_node;
    8521                 :           4 :   else if (processing_template_decl)
    8522                 :             :     {
    8523                 :           4 :       *dependent_p = true;
    8524                 :           4 :       *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                 :             : 
    8542                 :             : static tree
    8543                 :   109329295 : cp_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                 :   109329295 :   tree name;
    8550                 :   109329295 :   bool dependent_p;
    8551                 :   109329295 :   bool pseudo_destructor_p;
    8552                 :   109329295 :   tree scope = NULL_TREE;
    8553                 :   109329295 :   location_t start_loc = postfix_expression.get_start ();
    8554                 :             : 
    8555                 :             :   /* If this is a `->' operator, dereference the pointer.  */
    8556                 :   109329295 :   if (token_type == CPP_DEREF)
    8557                 :    28746246 :     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                 :   109329291 :   dependent_p = type_dependent_object_expression_p (postfix_expression);
    8562                 :             :   /* The identifier following the `->' or `.' is not qualified.  */
    8563                 :   109329291 :   parser->scope = NULL_TREE;
    8564                 :   109329291 :   parser->qualifying_scope = NULL_TREE;
    8565                 :   109329291 :   parser->object_scope = NULL_TREE;
    8566                 :   109329291 :   *idk = CP_ID_KIND_NONE;
    8567                 :             : 
    8568                 :             :   /* Enter the scope corresponding to the type of the object
    8569                 :             :      given by the POSTFIX_EXPRESSION.  */
    8570                 :   109329291 :   if (!dependent_p)
    8571                 :             :     {
    8572                 :    46661692 :       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                 :    46661692 :       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                 :    46661692 :       if (postfix_expression != current_class_ref
    8585                 :    46428763 :           && scope != error_mark_node
    8586                 :    93090232 :           && !currently_open_class (scope))
    8587                 :             :         {
    8588                 :    12219152 :           scope = complete_type (scope);
    8589                 :    12219152 :           if (!COMPLETE_TYPE_P (scope)
    8590                 :    12219152 :               && cp_parser_dot_deref_incomplete (&scope, &postfix_expression,
    8591                 :             :                                                  &dependent_p))
    8592                 :          27 :             return error_mark_node;
    8593                 :             :         }
    8594                 :             : 
    8595                 :    46661665 :       if (!dependent_p)
    8596                 :             :         {
    8597                 :             :           /* Let the name lookup machinery know that we are processing a
    8598                 :             :              class member access expression.  */
    8599                 :    46661661 :           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                 :    46661661 :           if (!scope)
    8604                 :           0 :             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                 :    46661661 :           if (scope == error_mark_node)
    8609                 :         254 :             postfix_expression = error_mark_node;
    8610                 :             :         }
    8611                 :             :     }
    8612                 :             : 
    8613                 :   109329264 :   if (dependent_p)
    8614                 :             :     {
    8615                 :    62667603 :       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                 :    62667603 :       if (type == NULL_TREE || is_auto (type))
    8619                 :    14379034 :         type = finish_typeof (postfix_expression);
    8620                 :    62667603 :       parser->context->object_type = type;
    8621                 :             :     }
    8622                 :             : 
    8623                 :             :   /* Assume this expression is not a pseudo-destructor access.  */
    8624                 :   109329264 :   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                 :   109329264 :   if ((scope && SCALAR_TYPE_P (scope)) || dependent_p)
    8631                 :             :     {
    8632                 :    62667783 :       tree s;
    8633                 :    62667783 :       tree type;
    8634                 :             : 
    8635                 :    62667783 :       cp_parser_parse_tentatively (parser);
    8636                 :             :       /* Parse the pseudo-destructor-name.  */
    8637                 :    62667783 :       s = NULL_TREE;
    8638                 :    62667783 :       cp_parser_pseudo_destructor_name (parser, postfix_expression,
    8639                 :             :                                         &s, &type);
    8640                 :    62667783 :       if (dependent_p
    8641                 :    62667783 :           && (cp_parser_error_occurred (parser)
    8642                 :      258670 :               || !SCALAR_TYPE_P (type)))
    8643                 :    62667583 :         cp_parser_abort_tentative_parse (parser);
    8644                 :         200 :       else if (cp_parser_parse_definitely (parser))
    8645                 :             :         {
    8646                 :         127 :           pseudo_destructor_p = true;
    8647                 :         127 :           postfix_expression
    8648                 :         127 :             = finish_pseudo_destructor_expr (postfix_expression,
    8649                 :             :                                              s, type, location);
    8650                 :             :         }
    8651                 :             :     }
    8652                 :             : 
    8653                 :    62667783 :   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                 :   109329137 :       bool template_p;
    8659                 :   109329137 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
    8660                 :             :       /* Parse the id-expression.  */
    8661                 :   109329137 :       name = (cp_parser_id_expression
    8662                 :   109329137 :               (parser,
    8663                 :   109329137 :                cp_parser_optional_template_keyword (parser),
    8664                 :             :                /*check_dependency_p=*/true,
    8665                 :             :                &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                 :   109329137 :       if (parser->scope)
    8681                 :      109653 :         *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                 :   109329137 :       if (TREE_CODE (name) == TYPE_DECL)
    8686                 :             :         {
    8687                 :           4 :           error_at (token->location, "invalid use of %qD", name);
    8688                 :           4 :           postfix_expression = error_mark_node;
    8689                 :             :         }
    8690                 :             :       else
    8691                 :             :         {
    8692                 :   109329133 :           if (name != error_mark_node && !BASELINK_P (name) && parser->scope)
    8693                 :             :             {
    8694                 :      109589 :               if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
    8695                 :             :                 {
    8696                 :          16 :                   error_at (token->location, "%<%D::%D%> is not a class member",
    8697                 :             :                             parser->scope, name);
    8698                 :          16 :                   postfix_expression = error_mark_node;
    8699                 :             :                 }
    8700                 :             :               else
    8701                 :      109573 :                 name = build_qualified_name (/*type=*/NULL_TREE,
    8702                 :             :                                              parser->scope,
    8703                 :             :                                              name,
    8704                 :             :                                              template_p);
    8705                 :      109589 :               parser->scope = NULL_TREE;
    8706                 :      109589 :               parser->qualifying_scope = NULL_TREE;
    8707                 :      109589 :               parser->object_scope = NULL_TREE;
    8708                 :             :             }
    8709                 :   109329133 :           if (parser->scope && name && BASELINK_P (name))
    8710                 :          64 :             adjust_result_of_qualified_name_lookup
    8711                 :          64 :               (name, parser->scope, scope);
    8712                 :   109329133 :           postfix_expression
    8713                 :   109329133 :             = 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                 :   109329133 :           location_t combined_loc
    8722                 :   109329133 :             = make_location (input_location, start_loc, parser->lexer);
    8723                 :   109329133 :           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                 :   109329264 :   parser->context->object_type = NULL_TREE;
    8730                 :             : 
    8731                 :             :   /* Outside of offsetof, these operators may not appear in
    8732                 :             :      constant-expressions.  */
    8733                 :   109329264 :   if (!for_offsetof
    8734                 :   218655620 :       && (cp_parser_non_integral_constant_expression
    8735                 :   189909054 :           (parser, token_type == CPP_DEREF ? NIC_ARROW : NIC_POINT)))
    8736                 :           2 :     postfix_expression = error_mark_node;
    8737                 :             : 
    8738                 :   109329264 :   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                 :             : 
    8774                 :             : static vec<tree, va_gc> *
    8775                 :   254141301 : cp_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                 :   254141301 :   vec<tree, va_gc> *expression_list;
    8784                 :   254141301 :   bool saved_greater_than_is_operator_p;
    8785                 :   254141301 :   bool saved_omp_array_section_p;
    8786                 :             : 
    8787                 :             :   /* Assume all the expressions will be constant.  */
    8788                 :   254141301 :   if (non_constant_p)
    8789                 :     4423557 :     *non_constant_p = false;
    8790                 :             : 
    8791                 :   254141301 :   matching_parens parens;
    8792                 :   254141301 :   if (!parens.require_open (parser))
    8793                 :             :     return NULL;
    8794                 :             : 
    8795                 :   253723942 :   expression_list = make_tree_vector ();
    8796                 :             : 
    8797                 :             :   /* Within a parenthesized expression, a `>' token is always
    8798                 :             :      the greater-than operator.  */
    8799                 :   253723942 :   saved_greater_than_is_operator_p
    8800                 :   253723942 :     = parser->greater_than_is_operator_p;
    8801                 :   253723942 :   parser->greater_than_is_operator_p = true;
    8802                 :             : 
    8803                 :   253723942 :   saved_omp_array_section_p = parser->omp_array_section_p;
    8804                 :   253723942 :   parser->omp_array_section_p = false;
    8805                 :             : 
    8806                 :   253723942 :   cp_expr expr (NULL_TREE);
    8807                 :             : 
    8808                 :             :   /* Consume expressions until there are no more.  */
    8809                 :   253723942 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
    8810                 :   382878763 :     while (true)
    8811                 :             :       {
    8812                 :             :         /* At the beginning of attribute lists, check to see if the
    8813                 :             :            next token is an identifier.  */
    8814                 :   280345050 :         if (is_attribute_list == id_attr
    8815                 :   280345050 :             && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
    8816                 :      729322 :           expr = cp_lexer_consume_token (parser->lexer)->u.value;
    8817                 :   279615728 :         else if (is_attribute_list == assume_attr)
    8818                 :       20465 :           expr = cp_parser_conditional_expression (parser);
    8819                 :   279595263 :         else if (is_attribute_list == uneval_string_attr)
    8820                 :        1068 :           expr = cp_parser_unevaluated_string_literal (parser);
    8821                 :             :         else
    8822                 :   279594195 :           expr
    8823                 :   279594195 :             = cp_parser_parenthesized_expression_list_elt (parser, cast_p,
    8824                 :             :                                                            allow_expansion_p,
    8825                 :             :                                                            non_constant_p);
    8826                 :             : 
    8827                 :   280345050 :         if (wrap_locations_p)
    8828                 :   226041996 :           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                 :   280345050 :         vec_safe_push (expression_list, expr.get_value ());
    8835                 :             : 
    8836                 :   280345050 :         if (expr == error_mark_node)
    8837                 :         807 :           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                 :   280344307 :       get_comma:;
    8844                 :             :         /* If the next token isn't a `,', then we are done.  */
    8845                 :   280344307 :         if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
    8846                 :             :           break;
    8847                 :             : 
    8848                 :             :         /* Otherwise, consume the `,' and keep going.  */
    8849                 :   102533713 :         cp_lexer_consume_token (parser->lexer);
    8850                 :             :       }
    8851                 :             : 
    8852                 :   253723199 :   if (close_paren_loc)
    8853                 :   184091911 :     *close_paren_loc = cp_lexer_peek_token (parser->lexer)->location;
    8854                 :             : 
    8855                 :   253723199 :   if (!parens.require_close (parser))
    8856                 :             :     {
    8857                 :         906 :       int ending;
    8858                 :             : 
    8859                 :          99 :     skip_comma:;
    8860                 :             :       /* We try and resync to an unnested comma, as that will give the
    8861                 :             :          user better diagnostics.  */
    8862                 :         906 :       ending = cp_parser_skip_to_closing_parenthesis (parser,
    8863                 :             :                                                       /*recovering=*/true,
    8864                 :             :                                                       /*or_comma=*/true,
    8865                 :             :                                                       /*consume_paren=*/true);
    8866                 :         906 :       if (ending < 0)
    8867                 :          64 :         goto get_comma;
    8868                 :         842 :       if (!ending)
    8869                 :             :         {
    8870                 :         136 :           parser->greater_than_is_operator_p
    8871                 :         136 :             = saved_greater_than_is_operator_p;
    8872                 :         136 :           parser->omp_array_section_p = saved_omp_array_section_p;
    8873                 :         136 :           return NULL;
    8874                 :             :         }
    8875                 :             :     }
    8876                 :             : 
    8877                 :   253723806 :   parser->greater_than_is_operator_p
    8878                 :   253723806 :     = saved_greater_than_is_operator_p;
    8879                 :   253723806 :   parser->omp_array_section_p = saved_omp_array_section_p;
    8880                 :             : 
    8881                 :   253723806 :   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                 :             : 
    8896                 :             : static void
    8897                 :    62667783 : cp_parser_pseudo_destructor_name (cp_parser* parser,
    8898                 :             :                                   tree object,
    8899                 :             :                                   tree* scope,
    8900                 :             :                                   tree* type)
    8901                 :             : {
    8902                 :    62667783 :   bool nested_name_specifier_p;
    8903                 :             : 
    8904                 :             :   /* Handle ~auto.  */
    8905                 :    62667783 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMPL)
    8906                 :      277155 :       && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_AUTO)
    8907                 :    62667789 :       && !type_dependent_expression_p (object))
    8908                 :             :     {
    8909                 :           3 :       if (cxx_dialect < cxx14)
    8910                 :           0 :         pedwarn (input_location, OPT_Wc__14_extensions,
    8911                 :             :                  "%<~auto%> only available with "
    8912                 :             :                  "%<-std=c++14%> or %<-std=gnu++14%>");
    8913                 :           3 :       cp_lexer_consume_token (parser->lexer);
    8914                 :           3 :       cp_lexer_consume_token (parser->lexer);
    8915                 :           3 :       *scope = NULL_TREE;
    8916                 :           3 :       *type = TREE_TYPE (object);
    8917                 :           3 :       return;
    8918                 :             :     }
    8919                 :             : 
    8920                 :             :   /* Assume that things will not work out.  */
    8921                 :    62667780 :   *type = error_mark_node;
    8922                 :             : 
    8923                 :             :   /* Look for the optional `::' operator.  */
    8924                 :    62667780 :   cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/true);
    8925                 :             :   /* Look for the optional nested-name-specifier.  */
    8926                 :    62667780 :   nested_name_specifier_p
    8927                 :    62667780 :     = (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                 :    62667780 :   if (nested_name_specifier_p
    8936                 :    62667780 :       && cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
    8937                 :             :     {
    8938                 :             :       /* Consume the `template' keyword.  */
    8939                 :          14 :       cp_lexer_consume_token (parser->lexer);
    8940                 :             :       /* Parse the template-id.  */
    8941                 :          14 :       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                 :          14 :       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                 :    62667766 :   else if (cp_lexer_next_token_is_not (parser->lexer, 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                 :    62390346 :       if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME
    8960                 :    62135281 :           || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE
    8961                 :    62390400 :           || cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_COMPL)
    8962                 :             :         {
    8963                 :    62390292 :           cp_parser_error (parser, "non-scalar type");
    8964                 :    62390292 :           return;
    8965                 :             :         }
    8966                 :             : 
    8967                 :             :       /* Look for the type-name.  */
    8968                 :          54 :       *scope = TREE_TYPE (cp_parser_nonclass_name (parser));
    8969                 :          54 :       if (*scope == error_mark_node)
    8970                 :             :         return;
    8971                 :             : 
    8972                 :             :       /* Look for the `::' token.  */
    8973                 :          50 :       cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
    8974                 :             :     }
    8975                 :             :   else
    8976                 :      277420 :     *scope = NULL_TREE;
    8977                 :             : 
    8978                 :             :   /* Look for the `~'.  */
    8979                 :      277484 :   cp_parser_require (parser, CPP_COMPL, RT_COMPL);
    8980                 :             : 
    8981                 :             :   /* Once we see the ~, this has to be a pseudo-destructor.  */
    8982                 :      277484 :   if (!processing_template_decl && !cp_parser_error_occurred (parser))
    8983                 :          96 :     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                 :      277484 :   *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                 :             : 
    9024                 :             : static cp_expr
    9025                 :   899126889 : cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
    9026                 :             :                             bool address_p, bool cast_p, bool decltype_p)
    9027                 :             : {
    9028                 :   899126889 :   cp_token *token;
    9029                 :   899126889 :   enum tree_code unary_operator;
    9030                 :             : 
    9031                 :             :   /* Peek at the next token.  */
    9032                 :   899126889 :   token = cp_lexer_peek_token (parser->lexer);
    9033                 :             :   /* Some keywords give away the kind of expression.  */
    9034                 :   899126889 :   if (token->type == CPP_KEYWORD)
    9035                 :             :     {
    9036                 :    97245558 :       enum rid keyword = token->keyword;
    9037                 :             : 
    9038                 :    97245558 :       switch (keyword)
    9039                 :             :         {
    9040                 :     4188998 :         case RID_ALIGNOF:
    9041                 :     4188998 :         case RID_SIZEOF:
    9042                 :     4188998 :           {
    9043                 :     4188998 :             tree operand, ret;
    9044                 :     4188998 :             enum tree_code op;
    9045                 :     4188998 :             location_t start_loc = token->location;
    9046                 :             : 
    9047                 :     4188998 :             op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
    9048                 :     4188998 :             bool std_alignof = id_equal (token->u.value, "alignof");
    9049                 :             : 
    9050                 :             :             /* Consume the token.  */
    9051                 :     4188998 :             cp_lexer_consume_token (parser->lexer);
    9052                 :             :             /* Parse the operand.  */
    9053                 :     4188998 :             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                 :     4188998 :             location_t compound_loc
    9061                 :     4188998 :               = make_location (start_loc, start_loc, parser->lexer);
    9062                 :             : 
    9063                 :     4188998 :             if (TYPE_P (operand))
    9064                 :     3677981 :               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                 :      511017 :                 if (std_alignof)
    9072                 :          26 :                   pedwarn (token->location, OPT_Wpedantic,
    9073                 :             :                            "ISO C++ does not allow %<alignof%> "
    9074                 :             :                            "with a non-type");
    9075                 :             : 
    9076                 :      511017 :                 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                 :     4188998 :             if (op == SIZEOF_EXPR && ret != error_mark_node)
    9082                 :             :               {
    9083                 :     3697731 :                 if (TREE_CODE (ret) != SIZEOF_EXPR || TYPE_P (operand))
    9084                 :             :                   {
    9085                 :     3491464 :                     if (!processing_template_decl && TYPE_P (operand))
    9086                 :             :                       {
    9087                 :      742619 :                         ret = build_min (SIZEOF_EXPR, size_type_node,
    9088                 :             :                                          build1 (NOP_EXPR, operand,
    9089                 :             :                                                  error_mark_node));
    9090                 :      742619 :                         SIZEOF_EXPR_TYPE_P (ret) = 1;
    9091                 :             :                       }
    9092                 :             :                     else
    9093                 :     2748845 :                       ret = build_min (SIZEOF_EXPR, size_type_node, operand);
    9094                 :     3491464 :                     TREE_SIDE_EFFECTS (ret) = 0;
    9095                 :     3491464 :                     TREE_READONLY (ret) = 1;
    9096                 :     3491464 :                     SET_EXPR_LOCATION (ret, compound_loc);
    9097                 :             :                   }
    9098                 :             :               }
    9099                 :             : 
    9100                 :     4188998 :             cp_expr ret_expr (ret, compound_loc);
    9101                 :     4188998 :             ret_expr = ret_expr.maybe_add_location_wrapper ();
    9102                 :     4188998 :             return ret_expr;
    9103                 :             :           }
    9104                 :             : 
    9105                 :        2806 :         case RID_BUILTIN_HAS_ATTRIBUTE:
    9106                 :        2806 :           return cp_parser_has_attribute_expression (parser);
    9107                 :             : 
    9108                 :      514556 :         case RID_NEW:
    9109                 :      514556 :           return cp_parser_new_expression (parser);
    9110                 :             : 
    9111                 :      489740 :         case RID_DELETE:
    9112                 :      489740 :           return cp_parser_delete_expression (parser);
    9113                 :             : 
    9114                 :       63049 :         case RID_EXTENSION:
    9115                 :       63049 :           {
    9116                 :             :             /* The saved value of the PEDANTIC flag.  */
    9117                 :       63049 :             int saved_pedantic;
    9118                 :       63049 :             tree expr;
    9119                 :             : 
    9120                 :             :             /* Save away the PEDANTIC flag.  */
    9121                 :       63049 :             cp_parser_extension_opt (parser, &saved_pedantic);
    9122                 :             :             /* Parse the cast-expression.  */
    9123                 :       63049 :             expr = cp_parser_simple_cast_expression (parser);
    9124                 :             :             /* Restore the PEDANTIC flag.  */
    9125                 :       63049 :             pedantic = saved_pedantic;
    9126                 :             : 
    9127                 :       63049 :             return expr;
    9128                 :             :           }
    9129                 :             : 
    9130                 :      162785 :         case RID_REALPART:
    9131                 :      162785 :         case RID_IMAGPART:
    9132                 :      162785 :           {
    9133                 :      162785 :             tree expression;
    9134                 :             : 
    9135                 :             :             /* Consume the `__real__' or `__imag__' token.  */
    9136                 :      162785 :             cp_lexer_consume_token (parser->lexer);
    9137                 :             :             /* Parse the cast-expression.  */
    9138                 :      162785 :             expression = cp_parser_simple_cast_expression (parser);
    9139                 :             :             /* Create the complete representation.  */
    9140                 :      162785 :             return build_x_unary_op (token->location,
    9141                 :             :                                      (keyword == RID_REALPART
    9142                 :             :                                       ? REALPART_EXPR : IMAGPART_EXPR),
    9143                 :             :                                      expression, NULL_TREE,
    9144                 :      244176 :                                      tf_warning_or_error);
    9145                 :             :           }
    9146                 :          89 :           break;
    9147                 :             : 
    9148                 :          89 :         case RID_TRANSACTION_ATOMIC:
    9149                 :          89 :         case RID_TRANSACTION_RELAXED:
    9150                 :          89 :           return cp_parser_transaction_expression (parser, keyword);
    9151                 :             : 
    9152                 :     1440781 :         case RID_NOEXCEPT:
    9153                 :     1440781 :           {
    9154                 :     1440781 :             tree expr;
    9155                 :     1440781 :             const char *saved_message;
    9156                 :     1440781 :             bool saved_integral_constant_expression_p;
    9157                 :     1440781 :             bool saved_non_integral_constant_expression_p;
    9158                 :     1440781 :             bool saved_greater_than_is_operator_p;
    9159                 :             : 
    9160                 :     1440781 :             location_t start_loc = token->location;
    9161                 :             : 
    9162                 :     1440781 :             cp_lexer_consume_token (parser->lexer);
    9163                 :     1440781 :             matching_parens parens;
    9164                 :     1440781 :             parens.require_open (parser);
    9165                 :             : 
    9166                 :     1440781 :             saved_message = parser->type_definition_forbidden_message;
    9167                 :     1440781 :             parser->type_definition_forbidden_message
    9168                 :     1440781 :               = G_("types may not be defined in %<noexcept%> expressions");
    9169                 :             : 
    9170                 :     1440781 :             saved_integral_constant_expression_p
    9171                 :     1440781 :               = parser->integral_constant_expression_p;
    9172                 :     1440781 :             saved_non_integral_constant_expression_p
    9173                 :     1440781 :               = parser->non_integral_constant_expression_p;
    9174                 :     1440781 :             parser->integral_constant_expression_p = false;
    9175                 :             : 
    9176                 :     1440781 :             saved_greater_than_is_operator_p
    9177                 :     1440781 :               = parser->greater_than_is_operator_p;
    9178                 :     1440781 :             parser->greater_than_is_operator_p = true;
    9179                 :             : 
    9180                 :     1440781 :             ++cp_unevaluated_operand;
    9181                 :     1440781 :             ++c_inhibit_evaluation_warnings;
    9182                 :     1440781 :             ++cp_noexcept_operand;
    9183                 :     1440781 :             expr = cp_parser_expression (parser);
    9184                 :     1440781 :             --cp_noexcept_operand;
    9185                 :     1440781 :             --c_inhibit_evaluation_warnings;
    9186                 :     1440781 :             --cp_unevaluated_operand;
    9187                 :             : 
    9188                 :     1440781 :             parser->greater_than_is_operator_p
    9189                 :     1440781 :               = saved_greater_than_is_operator_p;
    9190                 :             : 
    9191                 :     1440781 :             parser->integral_constant_expression_p
    9192                 :     1440781 :               = saved_integral_constant_expression_p;
    9193                 :     1440781 :             parser->non_integral_constant_expression_p
    9194                 :     1440781 :               = saved_non_integral_constant_expression_p;
    9195                 :             : 
    9196                 :     1440781 :             parser->type_definition_forbidden_message = saved_message;
    9197                 :             : 
    9198                 :     1440781 :             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                 :     1440781 :             location_t noexcept_loc
    9205                 :     1440781 :               = make_location (start_loc, start_loc, parser->lexer);
    9206                 :             : 
    9207                 :     1440781 :             return cp_expr (finish_noexcept_expr (expr, tf_warning_or_error),
    9208                 :     1440781 :                             noexcept_loc);
    9209                 :             :           }
    9210                 :             : 
    9211                 :         627 :         case RID_CO_AWAIT:
    9212                 :         627 :           {
    9213                 :         627 :             tree expr;
    9214                 :         627 :             location_t kw_loc = token->location;
    9215                 :             : 
    9216                 :             :             /* Consume the `co_await' token.  */
    9217                 :         627 :             cp_lexer_consume_token (parser->lexer);
    9218                 :             :             /* Parse its cast-expression.  */
    9219                 :         627 :             expr = cp_parser_simple_cast_expression (parser);
    9220                 :         627 :             if (expr == error_mark_node)
    9221                 :           1 :               return error_mark_node;
    9222                 :             : 
    9223                 :             :             /* Handle [expr.await].  */
    9224                 :         626 :             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                 :   892263458 :   if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
    9237                 :             :     {
    9238                 :      899934 :       enum rid keyword;
    9239                 :             : 
    9240                 :             :       /* See if the token after the `::' is one of the keywords in
    9241                 :             :          which we're interested.  */
    9242                 :      899934 :       keyword = cp_lexer_peek_nth_token (parser->lexer, 2)->keyword;
    9243                 :             :       /* If it's `new', we have a new-expression.  */
    9244                 :      899934 :       if (keyword == RID_NEW)
    9245                 :      311646 :         return cp_parser_new_expression (parser);
    9246                 :             :       /* Similarly, for `delete'.  */
    9247                 :      588288 :       else if (keyword == RID_DELETE)
    9248                 :          58 :         return cp_parser_delete_expression (parser);
    9249                 :             :     }
    9250                 :             : 
    9251                 :             :   /* Look for a unary operator.  */
    9252                 :  1783903531 :   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                 :    44106872 :   if (unary_operator == ERROR_MARK)
    9256                 :             :     {
    9257                 :   847844905 :       if (token->type == CPP_PLUS_PLUS)
    9258                 :             :         unary_operator = PREINCREMENT_EXPR;
    9259                 :   836513926 :       else if (token->type == CPP_MINUS_MINUS)
    9260                 :             :         unary_operator = PREDECREMENT_EXPR;
    9261                 :             :       /* Handle the GNU address-of-label extension.  */
    9262                 :   834520147 :       else if (cp_parser_allow_gnu_extensions_p (parser)
    9263                 :   834520147 :                && token->type == CPP_AND_AND)
    9264                 :             :         {
    9265                 :         279 :           tree identifier;
    9266                 :         279 :           tree expression;
    9267                 :         279 :           location_t start_loc = token->location;
    9268                 :             : 
    9269                 :             :           /* Consume the '&&' token.  */
    9270                 :         279 :           cp_lexer_consume_token (parser->lexer);
    9271                 :             :           /* Look for the identifier.  */
    9272                 :         279 :           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                 :         279 :           location_t combined_loc
    9278                 :         279 :             = make_location (start_loc, start_loc, parser->lexer);
    9279                 :             :           /* Create an expression representing the address.  */
    9280                 :         279 :           expression = finish_label_address_expr (identifier, combined_loc);
    9281                 :         279 :           if (TREE_CODE (expression) == ADDR_EXPR)
    9282                 :         267 :             mark_label_addressed (identifier);
    9283                 :         279 :           if (cp_parser_non_integral_constant_expression (parser,
    9284                 :             :                                                           NIC_ADDR_LABEL))
    9285                 :           2 :             expression = error_mark_node;
    9286                 :         279 :           return expression;
    9287                 :             :         }
    9288                 :             :     }
    9289                 :   834519868 :   if (unary_operator != ERROR_MARK)
    9290                 :             :     {
    9291                 :    57431607 :       cp_expr cast_expression;
    9292                 :    57431607 :       cp_expr expression = error_mark_node;
    9293                 :    57431607 :       non_integral_constant non_constant_p = NIC_NONE;
    9294                 :    57431607 :       location_t loc = token->location;
    9295                 :    57431607 :       tsubst_flags_t complain = complain_flags (decltype_p);
    9296                 :             : 
    9297                 :             :       /* Consume the operator token.  */
    9298                 :    57431607 :       token = cp_lexer_consume_token (parser->lexer);
    9299                 :    57431607 :       enum cpp_ttype op_ttype = cp_lexer_peek_token (parser->lexer)->type;
    9300                 :             : 
    9301                 :             :       /* Parse the cast-expression.  */
    9302                 :    57431607 :       cast_expression
    9303                 :    57431607 :         = 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                 :    57431607 :       loc = make_location (loc, loc, cast_expression.get_finish ());
    9315                 :             : 
    9316                 :             :       /* Now, build an appropriate representation.  */
    9317                 :    57431607 :       switch (unary_operator)
    9318                 :             :         {
    9319                 :    21658678 :         case INDIRECT_REF:
    9320                 :    21658678 :           non_constant_p = NIC_STAR;
    9321                 :    21658678 :           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                 :    21658678 :           expression.set_location (loc);
    9327                 :    21658678 :           break;
    9328                 :             : 
    9329                 :     4529965 :         case ADDR_EXPR:
    9330                 :     4529965 :            non_constant_p = NIC_ADDR;
    9331                 :             :           /* Fall through.  */
    9332                 :     5420416 :         case BIT_NOT_EXPR:
    9333                 :     5420416 :           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                 :     5420416 :           expression.set_location (loc);
    9339                 :     5420416 :           break;
    9340                 :             : 
    9341                 :    13324758 :         case PREINCREMENT_EXPR:
    9342                 :    13324758 :         case PREDECREMENT_EXPR:
    9343                 :    13324758 :           non_constant_p = unary_operator == PREINCREMENT_EXPR
    9344                 :    13324758 :                            ? NIC_PREINCREMENT : NIC_PREDECREMENT;
    9345                 :             :           /* Fall through.  */
    9346                 :    17986682 :         case NEGATE_EXPR:
    9347                 :             :           /* Immediately fold negation of a constant, unless the constant is 0
    9348                 :             :              (since -0 == 0) or it would overflow.  */
    9349                 :    17986682 :           if (unary_operator == NEGATE_EXPR && op_ttype == CPP_NUMBER)
    9350                 :             :             {
    9351                 :     2738316 :               tree stripped_expr
    9352                 :     2738316 :                 = tree_strip_any_location_wrapper (cast_expression);
    9353                 :     2738316 :               if (CONSTANT_CLASS_P (stripped_expr)
    9354                 :     2731516 :                   && !integer_zerop (stripped_expr)
    9355                 :     5469412 :                   && !TREE_OVERFLOW (stripped_expr))
    9356                 :             :                 {
    9357                 :     2731096 :                   tree folded = fold_build1 (unary_operator,
    9358                 :             :                                              TREE_TYPE (stripped_expr),
    9359                 :             :                                              stripped_expr);
    9360                 :     2731096 :                   if (CONSTANT_CLASS_P (folded) && !TREE_OVERFLOW (folded))
    9361                 :             :                     {
    9362                 :     2731096 :                       expression = maybe_wrap_with_location (folded, loc);
    9363                 :     2731096 :                       break;
    9364                 :             :                     }
    9365                 :             :                 }
    9366                 :             :             }
    9367                 :             :           /* Fall through.  */
    9368                 :    27621417 :         case UNARY_PLUS_EXPR:
    9369                 :    27621417 :         case TRUTH_NOT_EXPR:
    9370                 :    27621417 :           expression = finish_unary_op_expr (loc, unary_operator,
    9371                 :             :                                              cast_expression, complain);
    9372                 :    27621417 :           break;
    9373                 :             : 
    9374                 :           0 :         default:
    9375                 :           0 :           gcc_unreachable ();
    9376                 :             :         }
    9377                 :             : 
    9378                 :    21658678 :       if (non_constant_p != NIC_NONE
    9379                 :    57431607 :           && cp_parser_non_integral_constant_expression (parser,
    9380                 :             :                                                          non_constant_p))
    9381                 :          14 :         expression = error_mark_node;
    9382                 :             : 
    9383                 :    57431607 :       return expression;
    9384                 :             :     }
    9385                 :             : 
    9386                 :   834519868 :   return cp_parser_postfix_expression (parser, address_p, cast_p,
    9387                 :             :                                        /*member_access_only_p=*/false,
    9388                 :             :                                        decltype_p,
    9389                 :   834519847 :                                        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                 :             : 
    9395                 :             : static enum tree_code
    9396                 :   891951754 : cp_parser_unary_operator (cp_token* token)
    9397                 :             : {
    9398                 :   891951754 :   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                 :             : 
    9426                 :             : static tree
    9427                 :        2806 : cp_parser_has_attribute_expression (cp_parser *parser)
    9428                 :             : {
    9429                 :        2806 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
    9430                 :             : 
    9431                 :             :   /* Consume the __builtin_has_attribute token.  */
    9432                 :        2806 :   cp_lexer_consume_token (parser->lexer);
    9433                 :             : 
    9434                 :        2806 :   matching_parens parens;
    9435                 :        2806 :   if (!parens.require_open (parser))
    9436                 :           0 :     return error_mark_node;
    9437                 :             : 
    9438                 :             :   /* Types cannot be defined in a `sizeof' expression.  Save away the
    9439                 :             :      old message.  */
    9440                 :        2806 :   const char *saved_message = parser->type_definition_forbidden_message;
    9441                 :        2806 :   const char *saved_message_arg
    9442                 :             :     = parser->type_definition_forbidden_message_arg;
    9443                 :        2806 :   parser->type_definition_forbidden_message
    9444                 :        2806 :     = G_("types may not be defined in %qs expressions");
    9445                 :        2806 :   parser->type_definition_forbidden_message_arg
    9446                 :        2806 :     = IDENTIFIER_POINTER (ridpointers[RID_BUILTIN_HAS_ATTRIBUTE]);
    9447                 :             : 
    9448                 :             :   /* The restrictions on constant-expressions do not apply inside
    9449                 :             :      sizeof expressions.  */
    9450                 :        2806 :   bool saved_integral_constant_expression_p
    9451                 :             :     = parser->integral_constant_expression_p;
    9452                 :        2806 :   bool saved_non_integral_constant_expression_p
    9453                 :             :     = parser->non_integral_constant_expression_p;
    9454                 :        2806 :   parser->integral_constant_expression_p = false;
    9455                 :             : 
    9456                 :             :   /* Do not actually evaluate the expression.  */
    9457                 :        2806 :   ++cp_unevaluated_operand;
    9458                 :        2806 :   ++c_inhibit_evaluation_warnings;
    9459                 :             : 
    9460                 :        2806 :   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                 :        2806 :   cp_parser_parse_tentatively (parser);
    9465                 :             : 
    9466                 :        2806 :   bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
    9467                 :        2806 :   parser->in_type_id_in_expr_p = true;
    9468                 :             :   /* Look for the type-id.  */
    9469                 :        5612 :   oper = cp_parser_type_id (parser);
    9470                 :        2806 :   parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
    9471                 :             : 
    9472                 :        2806 :   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                 :        2806 :   if (!oper || oper == error_mark_node)
    9477                 :        2231 :     oper = cp_parser_assignment_expression (parser);
    9478                 :             : 
    9479                 :        2806 :   STRIP_ANY_LOCATION_WRAPPER (oper);
    9480                 :             : 
    9481                 :             :   /* Go back to evaluating expressions.  */
    9482                 :        2806 :   --cp_unevaluated_operand;
    9483                 :        2806 :   --c_inhibit_evaluation_warnings;
    9484                 :             : 
    9485                 :             :   /* And restore the old one.  */
    9486                 :        2806 :   parser->type_definition_forbidden_message = saved_message;
    9487                 :        2806 :   parser->type_definition_forbidden_message_arg = saved_message_arg;
    9488                 :        2806 :   parser->integral_constant_expression_p
    9489                 :        2806 :     = saved_integral_constant_expression_p;
    9490                 :        2806 :   parser->non_integral_constant_expression_p
    9491                 :        2806 :     = saved_non_integral_constant_expression_p;
    9492                 :             : 
    9493                 :             :   /* Consume the comma if it's there.  */
    9494                 :        2806 :   if (!cp_parser_require (parser, CPP_COMMA, RT_COMMA))
    9495                 :             :     {
    9496                 :          16 :       cp_parser_skip_to_closing_parenthesis (parser, false, false,
    9497                 :             :                                              /*consume_paren=*/true);
    9498                 :          16 :       return error_mark_node;
    9499                 :             :     }
    9500                 :             : 
    9501                 :             :   /* Parse the attribute specification.  */
    9502                 :        2790 :   bool ret = false;
    9503                 :        2790 :   location_t atloc = cp_lexer_peek_token (parser->lexer)->location;
    9504                 :        2790 :   if (tree attr = cp_parser_gnu_attribute_list (parser, /*exactly_one=*/true))
    9505                 :             :     {
    9506                 :        2778 :       if (oper == error_mark_node)
    9507                 :             :         /* Nothing.  */;
    9508                 :        2774 :       else if (processing_template_decl && uses_template_parms (oper))
    9509                 :           6 :         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                 :        2768 :           cp_check_const_attributes (attr);
    9515                 :             : 
    9516                 :             :           /* Finally, see if OPER has been declared with ATTR.  */
    9517                 :        2768 :           ret = has_attribute (atloc, oper, attr, default_conversion);
    9518                 :             :         }
    9519                 :             : 
    9520                 :        2778 :       parens.require_close (parser);
    9521                 :             :     }
    9522                 :             :   else
    9523                 :             :     {
    9524                 :          12 :       error_at (atloc, "expected identifier");
    9525                 :          12 :       cp_parser_skip_to_closing_parenthesis (parser, true, false, 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                 :        2790 :   location_t compound_loc
    9534                 :        2790 :     = make_location (start_loc, start_loc, parser->lexer);
    9535                 :             : 
    9536                 :        2790 :   cp_expr ret_expr (ret ? boolean_true_node : boolean_false_node);
    9537                 :        2790 :   ret_expr.set_location (compound_loc);
    9538                 :        2790 :   ret_expr = ret_expr.maybe_add_location_wrapper ();
    9539                 :        2790 :   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                 :             : 
    9550                 :             : static tree
    9551                 :      826202 : cp_parser_new_expression (cp_parser* parser)
    9552                 :             : {
    9553                 :      826202 :   bool global_scope_p;
    9554                 :      826202 :   vec<tree, va_gc> *placement;
    9555                 :      826202 :   tree type;
    9556                 :      826202 :   vec<tree, va_gc> *initializer;
    9557                 :      826202 :   tree nelts = NULL_TREE;
    9558                 :      826202 :   tree ret;
    9559                 :             : 
    9560                 :      826202 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
    9561                 :             : 
    9562                 :             :   /* Look for the optional `::' operator.  */
    9563                 :      826202 :   global_scope_p
    9564                 :      826202 :     = (cp_parser_global_scope_opt (parser,
    9565                 :             :                                    /*current_scope_valid_p=*/false)
    9566                 :             :        != NULL_TREE);
    9567                 :             :   /* Look for the `new' operator.  */
    9568                 :      826202 :   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                 :      826202 :   cp_parser_parse_tentatively (parser);
    9572                 :             :   /* Look for a new-placement.  */
    9573                 :      826202 :   placement = cp_parser_new_placement (parser);
    9574                 :             :   /* If that didn't work out, there's no new-placement.  */
    9575                 :      826202 :   if (!cp_parser_parse_definitely (parser))
    9576                 :             :     {
    9577                 :      416839 :       if (placement != NULL)
    9578                 :          96 :         release_tree_vector (placement);
    9579                 :      416839 :       placement = NULL;
    9580                 :             :     }
    9581                 :             : 
    9582                 :             :   /* If the next token is a `(', then we have a parenthesized
    9583                 :             :      type-id.  */
    9584                 :      826202 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    9585                 :             :     {
    9586                 :         121 :       cp_token *token;
    9587                 :         121 :       const char *saved_message = parser->type_definition_forbidden_message;
    9588                 :             : 
    9589                 :             :       /* Consume the `('.  */
    9590                 :         121 :       matching_parens parens;
    9591                 :         121 :       parens.consume_open (parser);
    9592                 :             : 
    9593                 :             :       /* Parse the type-id.  */
    9594                 :         121 :       parser->type_definition_forbidden_message
    9595                 :         121 :         = G_("types may not be defined in a new-expression");
    9596                 :         121 :       {
    9597                 :         121 :         type_id_in_expr_sentinel s (parser);
    9598                 :         242 :         type = cp_parser_type_id (parser);
    9599                 :         121 :       }
    9600                 :         121 :       parser->type_definition_forbidden_message = saved_message;
    9601                 :             : 
    9602                 :             :       /* Look for the closing `)'.  */
    9603                 :         121 :       parens.require_close (parser);
    9604                 :         121 :       token = cp_lexer_peek_token (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                 :         121 :       if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
    9609                 :             :         {
    9610                 :           4 :           error_at (token->location,
    9611                 :             :                     "array bound forbidden after parenthesized type-id");
    9612                 :           4 :           inform (token->location,
    9613                 :             :                   "try removing the parentheses around the type-id");
    9614                 :           4 :           cp_parser_direct_new_declarator (parser);
    9615                 :             :         }
    9616                 :             :     }
    9617                 :             :   /* Otherwise, there must be a new-type-id.  */
    9618                 :             :   else
    9619                 :      826081 :     type = cp_parser_new_type_id (parser, &nelts);
    9620                 :             : 
    9621                 :             :   /* If the next token is a `(' or '{', then we have a new-initializer.  */
    9622                 :      826202 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
    9623                 :      826202 :   if (token->type == CPP_OPEN_PAREN
    9624                 :      282622 :       || token->type == CPP_OPEN_BRACE)
    9625                 :      553667 :     initializer = cp_parser_new_initializer (parser);
    9626                 :             :   else
    9627                 :      272535 :     initializer = NULL;
    9628                 :             : 
    9629                 :             :   /* A new-expression may not appear in an integral constant
    9630                 :             :      expression.  */
    9631                 :      826202 :   if (cp_parser_non_integral_constant_expression (parser, NIC_NEW))
    9632                 :           0 :     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                 :      826202 :   else if ((ret = type_uses_auto (type))
    9639                 :          75 :            && !CLASS_PLACEHOLDER_TEMPLATE (ret)
    9640                 :      826251 :            && (vec_safe_length (initializer) != 1
    9641                 :          42 :                || (BRACE_ENCLOSED_INITIALIZER_P ((*initializer)[0])
    9642                 :          16 :                    && CONSTRUCTOR_NELTS ((*initializer)[0]) != 1)))
    9643                 :             :     {
    9644                 :          14 :       error_at (token->location,
    9645                 :             :                 "initialization of new-expression for type %<auto%> "
    9646                 :             :                 "requires exactly one element");
    9647                 :          14 :       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                 :      826188 :       location_t combined_loc = make_location (start_loc, start_loc,
    9657                 :             :                                                parser->lexer);
    9658                 :             :       /* Create a representation of the new-expression.  */
    9659                 :      826188 :       ret = build_new (combined_loc, &placement, type, nelts, &initializer,
    9660                 :             :                        global_scope_p, tf_warning_or_error);
    9661                 :             :     }
    9662                 :             : 
    9663                 :      826202 :   if (placement != NULL)
    9664                 :      546492 :     release_tree_vector (placement);
    9665                 :      826202 :   if (initializer != NULL)
    9666                 :      532533 :     release_tree_vector (initializer);
    9667                 :             : 
    9668                 :      826202 :   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                 :             : 
    9678                 :             : static vec<tree, va_gc> *
    9679                 :      826202 : cp_parser_new_placement (cp_parser* parser)
    9680                 :             : {
    9681                 :      826202 :   vec<tree, va_gc> *expression_list;
    9682                 :             : 
    9683                 :             :   /* Parse the expression-list.  */
    9684                 :      826202 :   expression_list = (cp_parser_parenthesized_expression_list
    9685                 :      826202 :                      (parser, non_attr, /*cast_p=*/false,
    9686                 :             :                       /*allow_expansion_p=*/true,
    9687                 :             :                       /*non_constant_p=*/NULL));
    9688                 :             : 
    9689                 :      826202 :   if (expression_list && expression_list->is_empty ())
    9690                 :           4 :     error ("expected expression-list or type-id");
    9691                 :             : 
    9692                 :      826202 :   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                 :             : 
    9704                 :             : static tree
    9705                 :      826081 : cp_parser_new_type_id (cp_parser* parser, tree *nelts)
    9706                 :             : {
    9707                 :      826081 :   cp_decl_specifier_seq type_specifier_seq;
    9708                 :      826081 :   cp_declarator *new_declarator;
    9709                 :      826081 :   cp_declarator *declarator;
    9710                 :      826081 :   cp_declarator *outer_declarator;
    9711                 :      826081 :   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                 :      826081 :   saved_message = parser->type_definition_forbidden_message;
    9718                 :      826081 :   parser->type_definition_forbidden_message
    9719                 :      826081 :     = G_("types may not be defined in a new-type-id");
    9720                 :             :   /* Parse the type-specifier-seq.  */
    9721                 :      826081 :   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                 :      826081 :   parser->type_definition_forbidden_message = saved_message;
    9727                 :             : 
    9728                 :      826081 :   if (type_specifier_seq.type == error_mark_node)
    9729                 :             :     return error_mark_node;
    9730                 :             : 
    9731                 :             :   /* Parse the new-declarator.  */
    9732                 :      826065 :   new_declarator = cp_parser_new_declarator_opt (parser);
    9733                 :             : 
    9734                 :             :   /* Determine the number of elements in the last array dimension, if
    9735                 :             :      any.  */
    9736                 :      826065 :   *nelts = NULL_TREE;
    9737                 :             :   /* Skip down to the last array dimension.  */
    9738                 :      826065 :   declarator = new_declarator;
    9739                 :      826065 :   outer_declarator = NULL;
    9740                 :      826148 :   while (declarator && (declarator->kind == cdk_pointer
    9741                 :      177507 :                         || declarator->kind == cdk_ptrmem))
    9742                 :             :     {
    9743                 :          83 :       outer_declarator = declarator;
    9744                 :          83 :       declarator = declarator->declarator;
    9745                 :             :     }
    9746                 :             :   while (declarator
    9747                 :      180067 :          && declarator->kind == cdk_array
    9748                 :      180055 :          && declarator->declarator
    9749                 :      828625 :          && declarator->declarator->kind == cdk_array)
    9750                 :             :     {
    9751                 :             :       outer_declarator = declarator;
    9752                 :             :       declarator = declarator->declarator;
    9753                 :             :     }
    9754                 :             : 
    9755                 :      826065 :   if (declarator && declarator->kind == cdk_array)
    9756                 :             :     {
    9757                 :      177495 :       *nelts = declarator->u.array.bounds;
    9758                 :      177495 :       if (*nelts == error_mark_node)
    9759                 :          24 :         *nelts = integer_one_node;
    9760                 :             : 
    9761                 :      177495 :       if (*nelts == NULL_TREE)
    9762                 :             :         /* Leave [] in the declarator.  */;
    9763                 :      177382 :       else if (outer_declarator)
    9764                 :        1620 :         outer_declarator->declarator = declarator->declarator;
    9765                 :             :       else
    9766                 :             :         new_declarator = NULL;
    9767                 :             :     }
    9768                 :             : 
    9769                 :      826065 :   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                 :             : 
    9780                 :             : static cp_declarator *
    9781                 :      826160 : cp_parser_new_declarator_opt (cp_parser* parser)
    9782                 :             : {
    9783                 :      826160 :   enum tree_code code;
    9784                 :      826160 :   tree type, std_attributes = NULL_TREE;
    9785                 :      826160 :   cp_cv_quals cv_quals;
    9786                 :             : 
    9787                 :             :   /* We don't know if there's a ptr-operator next, or not.  */
    9788                 :      826160 :   cp_parser_parse_tentatively (parser);
    9789                 :             :   /* Look for a ptr-operator.  */
    9790                 :      826160 :   code = cp_parser_ptr_operator (parser, &type, &cv_quals, &std_attributes);
    9791                 :             :   /* If that worked, look for more new-declarators.  */
    9792                 :      826160 :   if (cp_parser_parse_definitely (parser))
    9793                 :             :     {
    9794                 :          95 :       cp_declarator *declarator;
    9795                 :             : 
    9796                 :             :       /* Parse another optional declarator.  */
    9797                 :          95 :       declarator = cp_parser_new_declarator_opt (parser);
    9798                 :             : 
    9799                 :          95 :       declarator = cp_parser_make_indirect_declarator
    9800                 :          95 :         (code, type, cv_quals, declarator, std_attributes);
    9801                 :             : 
    9802                 :          95 :       return declarator;
    9803                 :             :     }
    9804                 :             : 
    9805                 :             :   /* If the next token is a `[', there is a direct-new-declarator.  */
    9806                 :      826065 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
    9807                 :      177503 :     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                 :             : 
    9820                 :             : static cp_declarator *
    9821                 :      177507 : cp_parser_direct_new_declarator (cp_parser* parser)
    9822                 :             : {
    9823                 :      177507 :   cp_declarator *declarator = NULL;
    9824                 :      177507 :   bool first_p = true;
    9825                 :             : 
    9826                 :      180067 :   while (true)
    9827                 :             :     {
    9828                 :      180067 :       tree expression;
    9829                 :      180067 :       cp_token *token;
    9830                 :             : 
    9831                 :             :       /* Look for the opening `['.  */
    9832                 :      180067 :       cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
    9833                 :             : 
    9834                 :      180067 :       token = cp_lexer_peek_token (parser->lexer);
    9835                 :      180067 :       if (token->type == CPP_CLOSE_SQUARE && first_p)
    9836                 :             :         expression = NULL_TREE;
    9837                 :             :       else
    9838                 :      179954 :         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                 :      179954 :       if (expression && !processing_template_decl)
    9846                 :             :         {
    9847                 :        7491 :           expression
    9848                 :        7491 :             = build_expr_type_conversion (WANT_INT | WANT_ENUM,
    9849                 :             :                                           expression,
    9850                 :             :                                           /*complain=*/true);
    9851                 :        7491 :           if (!expression)
    9852                 :             :             {
    9853                 :          20 :               error_at (token->location,
    9854                 :             :                         "expression in new-declarator must have integral "
    9855                 :             :                         "or enumeration type");
    9856                 :          20 :               expression = error_mark_node;
    9857                 :             :             }
    9858                 :             :         }
    9859                 :             : 
    9860                 :             :       /* Look for the closing `]'.  */
    9861                 :      180067 :       cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
    9862                 :             : 
    9863                 :             :       /* Add this bound to the declarator.  */
    9864                 :      180067 :       declarator = make_array_declarator (declarator, expression);
    9865                 :             : 
    9866                 :             :       /* If the next token is not a `[', then there are no more
    9867                 :             :          bounds.  */
    9868                 :      180067 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
    9869                 :             :         break;
    9870                 :             :       first_p = false;
    9871                 :             :     }
    9872                 :             : 
    9873                 :      177507 :   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                 :             : 
    9884                 :             : static vec<tree, va_gc> *
    9885                 :      553667 : cp_parser_new_initializer (cp_parser* parser)
    9886                 :             : {
    9887                 :      553667 :   vec<tree, va_gc> *expression_list;
    9888                 :             : 
    9889                 :      553667 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    9890                 :             :     {
    9891                 :       10087 :       cp_lexer_set_source_position (parser->lexer);
    9892                 :       10087 :       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
    9893                 :       10087 :       tree t = cp_parser_braced_list (parser);
    9894                 :       10087 :       CONSTRUCTOR_IS_DIRECT_INIT (t) = true;
    9895                 :       10087 :       expression_list = make_tree_vector_single (t);
    9896                 :             :     }
    9897                 :             :   else
    9898                 :      543580 :     expression_list = (cp_parser_parenthesized_expression_list
    9899                 :      543580 :                        (parser, non_attr, /*cast_p=*/false,
    9900                 :             :                         /*allow_expansion_p=*/true,
    9901                 :             :                         /*non_constant_p=*/NULL));
    9902                 :             : 
    9903                 :      553667 :   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                 :             : 
    9914                 :             : static tree
    9915                 :      489798 : cp_parser_delete_expression (cp_parser* parser)
    9916                 :             : {
    9917                 :      489798 :   bool global_scope_p;
    9918                 :      489798 :   bool array_p;
    9919                 :      489798 :   tree expression;
    9920                 :      489798 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
    9921                 :             : 
    9922                 :             :   /* Look for the optional `::' operator.  */
    9923                 :      489798 :   global_scope_p
    9924                 :      489798 :     = (cp_parser_global_scope_opt (parser,
    9925                 :             :                                    /*current_scope_valid_p=*/false)
    9926                 :             :        != NULL_TREE);
    9927                 :             :   /* Look for the `delete' keyword.  */
    9928                 :      489798 :   cp_parser_require_keyword (parser, RID_DELETE, RT_DELETE);
    9929                 :             :   /* See if the array syntax is in use.  */
    9930                 :      489798 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
    9931                 :             :     {
    9932                 :             :       /* Consume the `[' token.  */
    9933                 :      282968 :       cp_lexer_consume_token (parser->lexer);
    9934                 :             :       /* Look for the `]' token.  */
    9935                 :      282968 :       cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
    9936                 :             :       /* Remember that this is the `[]' construct.  */
    9937                 :      282968 :       array_p = true;
    9938                 :             :     }
    9939                 :             :   else
    9940                 :             :     array_p = false;
    9941                 :             : 
    9942                 :             :   /* Parse the cast-expression.  */
    9943                 :      489798 :   expression = cp_parser_simple_cast_expression (parser);
    9944                 :             : 
    9945                 :             :   /* A delete-expression may not appear in an integral constant
    9946                 :             :      expression.  */
    9947                 :      489798 :   if (cp_parser_non_integral_constant_expression (parser, NIC_DEL))
    9948                 :           0 :     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                 :      489798 :   location_t combined_loc = make_location (start_loc, start_loc,
    9956                 :             :                                            parser->lexer);
    9957                 :      489798 :   expression = delete_sanity (combined_loc, expression, NULL_TREE, array_p,
    9958                 :             :                               global_scope_p, tf_warning_or_error);
    9959                 :             : 
    9960                 :      489798 :   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                 :             : 
    9967                 :             : static int
    9968                 :    32738475 : cp_parser_tokens_start_cast_expression (cp_parser *parser)
    9969                 :             : {
    9970                 :    32738475 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
    9971                 :    32738475 :   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                 :     2392394 :     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                 :     2392394 :       return cp_lexer_peek_nth_token (parser->lexer, 2)->type
   10017                 :     2392394 :              != CPP_CLOSE_PAREN;
   10018                 :             : 
   10019                 :      161158 :     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                 :      161158 :       if (cxx_dialect >= cxx11)
   10023                 :             :         return -1;
   10024                 :        1037 :       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                 :     8450373 :     default:
   10040                 :     8450373 :       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                 :             : 
   10051                 :             : static const char *
   10052                 :          36 : get_cast_suggestion (tree dst_type, tree orig_expr)
   10053                 :             : {
   10054                 :          36 :   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                 :          36 :   if (processing_template_decl)
   10062                 :             :     return NULL;
   10063                 :             : 
   10064                 :             :   /* First try const_cast.  */
   10065                 :          32 :   trial = build_const_cast (input_location, dst_type, orig_expr, tf_none);
   10066                 :          32 :   if (trial != error_mark_node)
   10067                 :             :     return "const_cast";
   10068                 :             : 
   10069                 :             :   /* If that fails, try static_cast.  */
   10070                 :          24 :   trial = build_static_cast (input_location, dst_type, orig_expr, tf_none);
   10071                 :          24 :   if (trial != error_mark_node)
   10072                 :             :     return "static_cast";
   10073                 :             : 
   10074                 :             :   /* Finally, try reinterpret_cast.  */
   10075                 :          16 :   trial = build_reinterpret_cast (input_location, dst_type, orig_expr,
   10076                 :             :                                   tf_none);
   10077                 :          16 :   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                 :             : 
   10095                 :             : static void
   10096                 :          36 : maybe_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                 :          36 :   if (!warn_old_style_cast)
   10103                 :          12 :     return;
   10104                 :             : 
   10105                 :             :   /* Try to find a legal C++ cast, trying them in order:
   10106                 :             :      const_cast, static_cast, reinterpret_cast.  */
   10107                 :          36 :   const char *cast_suggestion = get_cast_suggestion (dst_type, orig_expr);
   10108                 :          36 :   if (!cast_suggestion)
   10109                 :             :     return;
   10110                 :             : 
   10111                 :             :   /* Replace the open paren with "CAST_SUGGESTION<".  */
   10112                 :          24 :   pretty_printer pp;
   10113                 :          24 :   pp_string (&pp, cast_suggestion);
   10114                 :          24 :   pp_less (&pp);
   10115                 :          24 :   rich_loc->add_fixit_replace (open_paren_loc, pp_formatted_text (&pp));
   10116                 :             : 
   10117                 :             :   /* Replace the close paren with "> (".  */
   10118                 :          24 :   rich_loc->add_fixit_replace (close_paren_loc, "> (");
   10119                 :             : 
   10120                 :             :   /* Add a closing paren after the expr (the primary range of RICH_LOC).  */
   10121                 :          24 :   rich_loc->add_fixit_insert_after (")");
   10122                 :          24 : }
   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                 :             : 
   10137                 :             : static cp_expr
   10138                 :   906285720 : cp_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                 :   906285720 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   10143                 :             :     {
   10144                 :    32738491 :       tree type = NULL_TREE;
   10145                 :    32738491 :       cp_expr expr (NULL_TREE);
   10146                 :    32738491 :       int cast_expression = 0;
   10147                 :    32738491 :       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                 :    32738491 :       cp_parser_parse_tentatively (parser);
   10153                 :             :       /* Types may not be defined in a cast.  */
   10154                 :    32738491 :       saved_message = parser->type_definition_forbidden_message;
   10155                 :    32738491 :       parser->type_definition_forbidden_message
   10156                 :    32738491 :         = G_("types may not be defined in casts");
   10157                 :             :       /* Consume the `('.  */
   10158                 :    32738491 :       matching_parens parens;
   10159                 :    32738491 :       cp_token *open_paren = parens.consume_open (parser);
   10160                 :    32738491 :       location_t open_paren_loc = open_paren->location;
   10161                 :    32738491 :       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                 :    32738491 :       cp_lexer_save_tokens (parser->lexer);
   10204                 :             : 
   10205                 :             :       /* We may be looking at a cast-expression.  */
   10206                 :    32738491 :       if (cp_parser_skip_to_closing_parenthesis (parser, false, false,
   10207                 :             :                                                  /*consume_paren=*/true))
   10208                 :    32738475 :         cast_expression
   10209                 :    32738475 :           = cp_parser_tokens_start_cast_expression (parser);
   10210                 :             : 
   10211                 :             :       /* Roll back the tokens we skipped.  */
   10212                 :    32738491 :       cp_lexer_rollback_tokens (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                 :    32738491 :       if (!cast_expression)
   10216                 :    54122526 :         cp_parser_simulate_error (parser);
   10217                 :             :       else
   10218                 :             :         {
   10219                 :    11354456 :           bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
   10220                 :    11354456 :           parser->in_type_id_in_expr_p = true;
   10221                 :             :           /* Look for the type-id.  */
   10222                 :    11354456 :           type = cp_parser_type_id (parser);
   10223                 :             :           /* Look for the closing `)'.  */
   10224                 :    11354456 :           cp_token *close_paren = parens.require_close (parser);
   10225                 :    11354456 :           if (close_paren)
   10226                 :     7737324 :             close_paren_loc = close_paren->location;
   10227                 :    11354456 :           parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
   10228                 :             :         }
   10229                 :             : 
   10230                 :             :       /* Restore the saved message.  */
   10231                 :    32738491 :       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                 :    65476982 :       if (!cp_parser_error_occurred (parser))
   10237                 :             :         {
   10238                 :             :           /* Only commit if the cast-expression doesn't start with
   10239                 :             :              '++', '--', or '[' in C++11.  */
   10240                 :     7737303 :           if (cast_expression > 0)
   10241                 :     7234073 :             cp_parser_commit_to_topmost_tentative_parse (parser);
   10242                 :             : 
   10243                 :     7737303 :           expr = cp_parser_cast_expression (parser,
   10244                 :             :                                             /*address_p=*/false,
   10245                 :             :                                             /*cast_p=*/true,
   10246                 :             :                                             /*decltype_p=*/false,
   10247                 :             :                                             pidk);
   10248                 :             : 
   10249                 :     7737303 :           if (cp_parser_parse_definitely (parser))
   10250                 :             :             {
   10251                 :             :               /* Warn about old-style casts, if so requested.  */
   10252                 :     7737292 :               if (warn_old_style_cast
   10253                 :          40 :                   && !in_system_header_at (input_location)
   10254                 :          40 :                   && !VOID_TYPE_P (type)
   10255                 :     7737328 :                   && current_lang_name != lang_name_c)
   10256                 :             :                 {
   10257                 :          36 :                   gcc_rich_location rich_loc (input_location);
   10258                 :          36 :                   maybe_add_cast_fixit (&rich_loc, open_paren_loc, close_paren_loc,
   10259                 :             :                                         expr, type);
   10260                 :          36 :                   warning_at (&rich_loc, OPT_Wold_style_cast,
   10261                 :             :                               "use of old-style cast to %q#T", type);
   10262                 :          36 :                 }
   10263                 :             : 
   10264                 :             :               /* Only type conversions to integral or enumeration types
   10265                 :             :                  can be used in constant-expressions.  */
   10266                 :     7737292 :               if (!cast_valid_in_integral_constant_expression_p (type)
   10267                 :     7737292 :                   && cp_parser_non_integral_constant_expression (parser,
   10268                 :             :                                                                  NIC_CAST))
   10269                 :          12 :                 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                 :     7737280 :               location_t cast_loc = make_location (open_paren_loc,
   10278                 :             :                                                    open_paren_loc,
   10279                 :             :                                                    expr.get_finish ());
   10280                 :     7737280 :               expr = build_c_cast (cast_loc, type, expr);
   10281                 :     7737280 :               return expr;
   10282                 :             :             }
   10283                 :             :         }
   10284                 :             :       else
   10285                 :    25001188 :         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                 :   898548428 :   return cp_parser_unary_expression (parser, pidk, address_p,
   10291                 :   898548407 :                                      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                 :             : 
   10373                 :             : static cp_expr
   10374                 :   728796068 : cp_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                 :  9474348884 :   cp_parser_expression_stack stack;
   10381                 :   728796068 :   cp_parser_expression_stack_entry *sp = &stack[0];
   10382                 :   728796068 :   cp_parser_expression_stack_entry *disable_warnings_sp = NULL;
   10383                 :   728796068 :   cp_parser_expression_stack_entry current;
   10384                 :   728796068 :   cp_expr rhs;
   10385                 :   728796068 :   cp_token *token;
   10386                 :   728796068 :   enum tree_code rhs_type;
   10387                 :   728796068 :   enum cp_parser_prec new_prec, lookahead_prec;
   10388                 :   728796068 :   tree overload;
   10389                 :             : 
   10390                 :             :   /* Parse the first expression.  */
   10391                 :  1457592136 :   current.lhs_type = (cp_lexer_next_token_is (parser->lexer, CPP_NOT)
   10392                 :   728796068 :                       ? TRUTH_NOT_EXPR : ERROR_MARK);
   10393                 :   728796068 :   current.lhs = cp_parser_cast_expression (parser, /*address_p=*/false,
   10394                 :             :                                            cast_p, decltype_p, pidk);
   10395                 :   728796047 :   current.prec = prec;
   10396                 :             : 
   10397                 :  1569182876 :   if (cp_parser_error_occurred (parser))
   10398                 :         478 :     return error_mark_node;
   10399                 :             : 
   10400                 :   840386351 :   for (;;)
   10401                 :             :     {
   10402                 :             :       /* Get an operator token.  */
   10403                 :   840386351 :       token = cp_lexer_peek_token (parser->lexer);
   10404                 :             : 
   10405                 :   840386351 :       if (warn_cxx11_compat
   10406                 :      802830 :           && token->type == CPP_RSHIFT
   10407                 :        2561 :           && !parser->greater_than_is_operator_p)
   10408                 :             :         {
   10409                 :           2 :           if (warning_at (token->location, OPT_Wc__11_compat,
   10410                 :             :                           "%<>>%> operator is treated"
   10411                 :             :                           " as two right angle brackets in C++11"))
   10412                 :           2 :             inform (token->location,
   10413                 :             :                     "suggest parentheses around %<>>%> expression");
   10414                 :             :         }
   10415                 :             : 
   10416                 :   840386351 :       new_prec = TOKEN_PRECEDENCE (token);
   10417                 :   824522152 :       if (new_prec != PREC_NOT_OPERATOR
   10418                 :   824522152 :           && cp_lexer_nth_token_is (parser->lexer, 2, 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                 :   840386351 :       if (new_prec <= current.prec)
   10430                 :             :         {
   10431                 :   738298418 :           if (sp == stack)
   10432                 :             :             break;
   10433                 :             :           else
   10434                 :     9502852 :             goto pop;
   10435                 :             :         }
   10436                 :             : 
   10437                 :   102087933 :      get_rhs:
   10438                 :   111590785 :       current.tree_type = binops_by_token[token->type].tree_type;
   10439                 :   111590785 :       current.loc = token->location;
   10440                 :   111590785 :       current.flags = token->flags;
   10441                 :             : 
   10442                 :             :       /* We used the operator token.  */
   10443                 :   111590785 :       cp_lexer_consume_token (parser->lexer);
   10444                 :             : 
   10445                 :             :       /* For "false && x" or "true || x", x will never be executed;
   10446                 :             :          disable warnings while evaluating it.  */
   10447                 :   111590785 :       if ((current.tree_type == TRUTH_ANDIF_EXPR
   10448                 :     8379722 :            && cp_fully_fold (current.lhs) == truthvalue_false_node)
   10449                 :   119970125 :           || (current.tree_type == TRUTH_ORIF_EXPR
   10450                 :     3170464 :               && cp_fully_fold (current.lhs) == truthvalue_true_node))
   10451                 :             :         {
   10452                 :        1975 :           disable_warnings_sp = sp;
   10453                 :        1975 :           ++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                 :   223181570 :       rhs_type = (cp_lexer_next_token_is (parser->lexer, CPP_NOT)
   10459                 :   111590785 :                   ? TRUTH_NOT_EXPR : ERROR_MARK);
   10460                 :   111590785 :       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                 :   111590785 :       token = cp_lexer_peek_token (parser->lexer);
   10466                 :   111590785 :       lookahead_prec = TOKEN_PRECEDENCE (token);
   10467                 :   111017325 :       if (lookahead_prec != PREC_NOT_OPERATOR
   10468                 :   111017325 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS))
   10469                 :             :         lookahead_prec = PREC_NOT_OPERATOR;
   10470                 :   111590785 :       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                 :     9502852 :           *sp = current;
   10477                 :     9502852 :           ++sp;
   10478                 :     9502852 :           current.lhs = rhs;
   10479                 :     9502852 :           current.lhs_type = rhs_type;
   10480                 :     9502852 :           current.prec = new_prec;
   10481                 :     9502852 :           new_prec = lookahead_prec;
   10482                 :     9502852 :           goto get_rhs;
   10483                 :             : 
   10484                 :     9502852 :          pop:
   10485                 :     9502852 :           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                 :     9502852 :           rhs = current.lhs;
   10494                 :     9502852 :           rhs_type = current.lhs_type;
   10495                 :     9502852 :           --sp;
   10496                 :     9502852 :           current = *sp;
   10497                 :             :         }
   10498                 :             : 
   10499                 :             :       /* Undo the disabling of warnings done above.  */
   10500                 :   111590785 :       if (sp == disable_warnings_sp)
   10501                 :             :         {
   10502                 :        1975 :           disable_warnings_sp = NULL;
   10503                 :        1975 :           --c_inhibit_evaluation_warnings;
   10504                 :             :         }
   10505                 :             : 
   10506                 :   111590785 :       if (warn_logical_not_paren
   10507                 :     1158153 :           && TREE_CODE_CLASS (current.tree_type) == tcc_comparison
   10508                 :      461701 :           && current.lhs_type == TRUTH_NOT_EXPR
   10509                 :             :           /* Avoid warning for !!x == y.  */
   10510                 :         540 :           && (TREE_CODE (current.lhs) != NE_EXPR
   10511                 :          60 :               || !integer_zerop (TREE_OPERAND (current.lhs, 1)))
   10512                 :         480 :           && (TREE_CODE (current.lhs) != TRUTH_NOT_EXPR
   10513                 :          96 :               || (TREE_CODE (TREE_OPERAND (current.lhs, 0)) != TRUTH_NOT_EXPR
   10514                 :             :                   /* Avoid warning for !b == y where b is boolean.  */
   10515                 :          88 :                   && (TREE_TYPE (TREE_OPERAND (current.lhs, 0)) == NULL_TREE
   10516                 :          84 :                       || (TREE_CODE (TREE_TYPE (TREE_OPERAND (current.lhs, 0)))
   10517                 :             :                           != BOOLEAN_TYPE))))
   10518                 :             :           /* Avoid warning for !!b == y where b is boolean.  */
   10519                 :   111591181 :           && (!(DECL_P (tree_strip_any_location_wrapper (current.lhs))
   10520                 :         396 :                 || (TREE_CODE (current.lhs) == NON_LVALUE_EXPR
   10521                 :          24 :                     && DECL_P (tree_strip_any_location_wrapper
   10522                 :             :                                             (TREE_OPERAND (current.lhs, 0)))))
   10523                 :          24 :               || TREE_TYPE (current.lhs) == NULL_TREE
   10524                 :          24 :               || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))
   10525                 :         372 :         warn_logical_not_parentheses (current.loc, current.tree_type,
   10526                 :             :                                       current.lhs, maybe_constant_value (rhs));
   10527                 :             : 
   10528                 :   111590785 :       if (warn_xor_used_as_pow
   10529                 :   111590785 :           && current.tree_type == BIT_XOR_EXPR
   10530                 :             :           /* Don't warn for named "xor" (as opposed to '^').  */
   10531                 :      481966 :           && !(current.flags & NAMED_OP)
   10532                 :      481950 :           && current.lhs.decimal_p ()
   10533                 :   111591353 :           && rhs.decimal_p ())
   10534                 :         269 :         check_for_xor_used_as_pow
   10535                 :         269 :           (current.lhs.get_location (),
   10536                 :             :            tree_strip_any_location_wrapper (current.lhs),
   10537                 :             :            current.loc,
   10538                 :             :            rhs.get_location (),
   10539                 :             :            tree_strip_any_location_wrapper (rhs));
   10540                 :             : 
   10541                 :   111590785 :       overload = NULL;
   10542                 :             : 
   10543                 :   111590785 :       location_t combined_loc = make_location (current.loc,
   10544                 :             :                                                current.lhs.get_start (),
   10545                 :             :                                                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                 :   111590785 :       if (no_toplevel_fold_p
   10555                 :      679978 :           && lookahead_prec <= current.prec
   10556                 :      340894 :           && sp == stack)
   10557                 :             :         {
   10558                 :      336940 :           if (current.lhs == error_mark_node || rhs == error_mark_node)
   10559                 :          11 :             current.lhs = error_mark_node;
   10560                 :             :           else
   10561                 :             :             {
   10562                 :      336929 :               current.lhs.maybe_add_location_wrapper ();
   10563                 :      336929 :               rhs.maybe_add_location_wrapper ();
   10564                 :      336929 :               current.lhs
   10565                 :      336929 :                 = build_min (current.tree_type,
   10566                 :      336929 :                              TREE_CODE_CLASS (current.tree_type)
   10567                 :             :                              == tcc_comparison
   10568                 :      309477 :                              ? boolean_type_node : TREE_TYPE (current.lhs),
   10569                 :             :                              current.lhs.get_value (), rhs.get_value ());
   10570                 :      336929 :               SET_EXPR_LOCATION (current.lhs, combined_loc);
   10571                 :             :             }
   10572                 :             :         }
   10573                 :             :       else
   10574                 :             :         {
   10575                 :   111253845 :           op_location_t op_loc (current.loc, combined_loc);
   10576                 :   111696723 :           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                 :   111253842 :           current.lhs.set_location (combined_loc);
   10582                 :             :         }
   10583                 :   111590782 :       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                 :   111590782 :       if (overload
   10592                 :   111590782 :           && cp_parser_non_integral_constant_expression (parser,
   10593                 :             :                                                          NIC_OVERLOADED))
   10594                 :           0 :         return error_mark_node;
   10595                 :             :     }
   10596                 :             : 
   10597                 :   728795566 :   return current.lhs;
   10598                 :             : }
   10599                 :             : 
   10600                 :             : static cp_expr
   10601                 :      602624 : cp_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                 :           0 :   return cp_parser_binary_expression (parser, cast_p, no_toplevel_fold_p,
   10607                 :           0 :                                       /*decltype*/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                 :             : 
   10624                 :             : static tree
   10625                 :     3565970 : cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
   10626                 :             : {
   10627                 :     3565970 :   tree expr, folded_logical_or_expr = cp_fully_fold (logical_or_expr);
   10628                 :     3565970 :   cp_expr assignment_expr;
   10629                 :     3565970 :   struct cp_token *token;
   10630                 :     3565970 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   10631                 :             : 
   10632                 :             :   /* Consume the `?' token.  */
   10633                 :     3565970 :   cp_lexer_consume_token (parser->lexer);
   10634                 :     3565970 :   token = cp_lexer_peek_token (parser->lexer);
   10635                 :     3565970 :   if (cp_parser_allow_gnu_extensions_p (parser)
   10636                 :     3565970 :       && token->type == CPP_COLON)
   10637                 :             :     {
   10638                 :         351 :       pedwarn (token->location, OPT_Wpedantic,
   10639                 :             :                "ISO C++ does not allow %<?:%> with omitted middle operand");
   10640                 :             :       /* Implicit true clause.  */
   10641                 :         351 :       expr = NULL_TREE;
   10642                 :         351 :       c_inhibit_evaluation_warnings +=
   10643                 :         351 :         folded_logical_or_expr == truthvalue_true_node;
   10644                 :         351 :       warn_for_omitted_condop (token->location, logical_or_expr);
   10645                 :             :     }
   10646                 :             :   else
   10647                 :             :     {
   10648                 :     3565619 :       bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   10649                 :     3565619 :       parser->colon_corrects_to_scope_p = false;
   10650                 :             :       /* Parse the expression.  */
   10651                 :     3565619 :       c_inhibit_evaluation_warnings +=
   10652                 :     3565619 :         folded_logical_or_expr == truthvalue_false_node;
   10653                 :     3565619 :       expr = cp_parser_expression (parser);
   10654                 :     3565619 :       c_inhibit_evaluation_warnings +=
   10655                 :     3565619 :         ((folded_logical_or_expr == truthvalue_true_node)
   10656                 :     3565619 :          - (folded_logical_or_expr == truthvalue_false_node));
   10657                 :     3565619 :       parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   10658                 :             :     }
   10659                 :             : 
   10660                 :             :   /* The next token should be a `:'.  */
   10661                 :     3565970 :   cp_parser_require (parser, CPP_COLON, RT_COLON);
   10662                 :             :   /* Parse the assignment-expression.  */
   10663                 :     3565970 :   assignment_expr = cp_parser_assignment_expression (parser);
   10664                 :     3565970 :   c_inhibit_evaluation_warnings -=
   10665                 :     3565970 :     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                 :     3565970 :   loc = make_location (loc,
   10673                 :             :                        logical_or_expr.get_start (),
   10674                 :             :                        assignment_expr.get_finish ());
   10675                 :             : 
   10676                 :             :   /* Build the conditional-expression.  */
   10677                 :     3565970 :   return build_x_conditional_expr (loc, logical_or_expr,
   10678                 :             :                                    expr,
   10679                 :             :                                    assignment_expr,
   10680                 :     3565970 :                                    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                 :             : 
   10693                 :             : static cp_expr
   10694                 :      359341 : cp_parser_conditional_expression (cp_parser *parser)
   10695                 :             : {
   10696                 :      359341 :   cp_expr expr = cp_parser_binary_expression (parser, false, false, false,
   10697                 :             :                                               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                 :      359341 :   if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
   10701                 :          38 :     return cp_parser_question_colon_clause (parser, expr);
   10702                 :      359303 :   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                 :             : 
   10718                 :             : static cp_expr
   10719                 :   729070872 : cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
   10720                 :             :                                  bool cast_p, bool decltype_p)
   10721                 :             : {
   10722                 :   729070872 :   cp_expr expr;
   10723                 :             : 
   10724                 :             :   /* If the next token is the `throw' keyword, then we're looking at
   10725                 :             :      a throw-expression.  */
   10726                 :   729070872 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THROW))
   10727                 :     1235410 :     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                 :   727835462 :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CO_YIELD))
   10731                 :        1359 :     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                 :   727834103 :       expr = cp_parser_binary_expression (parser, cast_p, false,
   10738                 :             :                                           decltype_p,
   10739                 :             :                                           PREC_NOT_OPERATOR, pidk);
   10740                 :             :       /* If the next token is a `?' then we're actually looking at a
   10741                 :             :          conditional-expression.  */
   10742                 :   727834079 :       if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
   10743                 :     3565932 :         return cp_parser_question_colon_clause (parser, expr);
   10744                 :             :       else
   10745                 :             :         {
   10746                 :   724268147 :           location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   10747                 :             : 
   10748                 :             :           /* If it's an assignment-operator, we're using the second
   10749                 :             :              production.  */
   10750                 :   724268147 :           enum tree_code assignment_operator
   10751                 :   724268147 :             = cp_parser_assignment_operator_opt (parser);
   10752                 :   724268147 :           if (assignment_operator != ERROR_MARK)
   10753                 :             :             {
   10754                 :             :               /* Parse the right-hand side of the assignment.  */
   10755                 :    37848663 :               cp_expr rhs = cp_parser_initializer_clause (parser);
   10756                 :             : 
   10757                 :    37848663 :               if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
   10758                 :       62640 :                 maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   10759                 :             : 
   10760                 :             :               /* An assignment may not appear in a
   10761                 :             :                  constant-expression.  */
   10762                 :    37848663 :               if (cp_parser_non_integral_constant_expression (parser,
   10763                 :             :                                                               NIC_ASSIGNMENT))
   10764                 :           1 :                 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                 :    37848662 :               loc = make_location (loc,
   10773                 :             :                                    expr.get_start (),
   10774                 :             :                                    rhs.get_finish ());
   10775                 :    37849026 :               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                 :    37848662 :               expr.set_location (loc);
   10782                 :             :             }
   10783                 :             :         }
   10784                 :             :     }
   10785                 :             : 
   10786                 :   725504915 :   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                 :             : 
   10806                 :             : static enum tree_code
   10807                 :   724268838 : cp_parser_assignment_operator_opt (cp_parser* parser)
   10808                 :             : {
   10809                 :   724268838 :   enum tree_code op;
   10810                 :   724268838 :   cp_token *token;
   10811                 :             : 
   10812                 :             :   /* Peek at the next token.  */
   10813                 :   724268838 :   token = cp_lexer_peek_token (parser->lexer);
   10814                 :             : 
   10815                 :   724268838 :   switch (token->type)
   10816                 :             :     {
   10817                 :             :     case CPP_EQ:
   10818                 :             :       op = NOP_EXPR;
   10819                 :             :       break;
   10820                 :             : 
   10821                 :     1006374 :     case CPP_MULT_EQ:
   10822                 :     1006374 :       op = MULT_EXPR;
   10823                 :     1006374 :       break;
   10824                 :             : 
   10825                 :      595083 :     case CPP_DIV_EQ:
   10826                 :      595083 :       op = TRUNC_DIV_EXPR;
   10827                 :      595083 :       break;
   10828                 :             : 
   10829                 :      165955 :     case CPP_MOD_EQ:
   10830                 :      165955 :       op = TRUNC_MOD_EXPR;
   10831                 :      165955 :       break;
   10832                 :             : 
   10833                 :     2689570 :     case CPP_PLUS_EQ:
   10834                 :     2689570 :       op = PLUS_EXPR;
   10835                 :     2689570 :       break;
   10836                 :             : 
   10837                 :      794839 :     case CPP_MINUS_EQ:
   10838                 :      794839 :       op = MINUS_EXPR;
   10839                 :      794839 :       break;
   10840                 :             : 
   10841                 :      273643 :     case CPP_RSHIFT_EQ:
   10842                 :      273643 :       op = RSHIFT_EXPR;
   10843                 :      273643 :       break;
   10844                 :             : 
   10845                 :      142917 :     case CPP_LSHIFT_EQ:
   10846                 :      142917 :       op = LSHIFT_EXPR;
   10847                 :      142917 :       break;
   10848                 :             : 
   10849                 :      290096 :     case CPP_AND_EQ:
   10850                 :      290096 :       op = BIT_AND_EXPR;
   10851                 :      290096 :       break;
   10852                 :             : 
   10853                 :      260486 :     case CPP_XOR_EQ:
   10854                 :      260486 :       op = BIT_XOR_EXPR;
   10855                 :      260486 :       break;
   10856                 :             : 
   10857                 :     1312661 :     case CPP_OR_EQ:
   10858                 :     1312661 :       op = BIT_IOR_EXPR;
   10859                 :     1312661 :       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                 :     7531624 :   if (op != ERROR_MARK
   10868                 :    37849528 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS))
   10869                 :             :     op = ERROR_MARK;
   10870                 :             : 
   10871                 :             :   /* If it was an assignment operator, consume it.  */
   10872                 :   724268664 :   if (op != ERROR_MARK)
   10873                 :    37849354 :     cp_lexer_consume_token (parser->lexer);
   10874                 :             : 
   10875                 :   724268838 :   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                 :             : 
   10891                 :             : static cp_expr
   10892                 :   265632230 : cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
   10893                 :             :                       bool cast_p, bool decltype_p, bool warn_comma_p)
   10894                 :             : {
   10895                 :   265632230 :   cp_expr expression = NULL_TREE;
   10896                 :   265632230 :   location_t loc = UNKNOWN_LOCATION;
   10897                 :             : 
   10898                 :   270409240 :   while (true)
   10899                 :             :     {
   10900                 :   268020735 :       cp_expr assignment_expression;
   10901                 :             : 
   10902                 :             :       /* Parse the next assignment-expression.  */
   10903                 :   268020735 :       assignment_expression
   10904                 :   268020735 :         = 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                 :     2490636 :       if (decltype_p && !processing_template_decl
   10910                 :      110794 :           && TREE_CODE (assignment_expression) == CALL_EXPR
   10911                 :        2999 :           && CLASS_TYPE_P (TREE_TYPE (assignment_expression))
   10912                 :   268021317 :           && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   10913                 :           6 :         assignment_expression
   10914                 :           6 :           = 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                 :   268020718 :       if (!expression)
   10920                 :   265632213 :         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                 :     2388505 :           loc = make_location (loc,
   10926                 :             :                                expression.get_start (),
   10927                 :             :                                assignment_expression.get_finish ());
   10928                 :     2420068 :           expression = build_x_compound_expr (loc, expression,
   10929                 :             :                                               assignment_expression, NULL_TREE,
   10930                 :             :                                               complain_flags (decltype_p));
   10931                 :     2388505 :           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                 :   268020718 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
   10936                 :   268020718 :           || cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS))
   10937                 :             :         break;
   10938                 :             :       /* Consume the `,'.  */
   10939                 :     2388505 :       loc = cp_lexer_peek_token (parser->lexer)->location;
   10940                 :     2388505 :       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                 :          43 :           warning_at (loc, OPT_Wcomma_subscript,
   10947                 :             :                       "top-level comma expression in array subscript "
   10948                 :             :                       "is deprecated");
   10949                 :          43 :           warn_comma_p = false;
   10950                 :             :         }
   10951                 :     2388505 :       cp_lexer_consume_token (parser->lexer);
   10952                 :             :       /* A comma operator cannot appear in a constant-expression.  */
   10953                 :     2388505 :       if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
   10954                 :           2 :         expression = error_mark_node;
   10955                 :     2388505 :     }
   10956                 :             : 
   10957                 :   265632213 :   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                 :             : 
   10974                 :             : static cp_expr
   10975                 :   155616686 : cp_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                 :   155616686 :   bool saved_integral_constant_expression_p
   10999                 :             :     = parser->integral_constant_expression_p;
   11000                 :   155616686 :   bool saved_allow_non_integral_constant_expression_p
   11001                 :             :     = parser->allow_non_integral_constant_expression_p;
   11002                 :   155616686 :   bool saved_non_integral_constant_expression_p
   11003                 :             :     = parser->non_integral_constant_expression_p;
   11004                 :             :   /* We are now parsing a constant-expression.  */
   11005                 :   155616686 :   parser->integral_constant_expression_p = true;
   11006                 :   155616686 :   parser->allow_non_integral_constant_expression_p
   11007                 :   155616686 :     = (allow_non_constant_p || cxx_dialect >= cxx11);
   11008                 :   155616686 :   parser->non_integral_constant_expression_p = false;
   11009                 :             : 
   11010                 :             :   /* A manifestly constant-evaluated expression is evaluated even in an
   11011                 :             :      unevaluated operand.  */
   11012                 :   155616686 :   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                 :   155616686 :   cp_expr expression;
   11024                 :   155616686 :   if (strict_p)
   11025                 :      337890 :     expression = cp_parser_conditional_expression (parser);
   11026                 :             :   else
   11027                 :   155278796 :     expression = cp_parser_assignment_expression (parser);
   11028                 :             :   /* Restore the old settings.  */
   11029                 :   155616679 :   parser->integral_constant_expression_p
   11030                 :   155616679 :     = saved_integral_constant_expression_p;
   11031                 :   155616679 :   parser->allow_non_integral_constant_expression_p
   11032                 :   155616679 :     = saved_allow_non_integral_constant_expression_p;
   11033                 :   155616679 :   if (cxx_dialect >= cxx11
   11034                 :   155049295 :       && (!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                 :    89190889 :       tree decay = expression;
   11040                 :    89190889 :       if (TREE_TYPE (expression)
   11041                 :    89190889 :           && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE)
   11042                 :     1470158 :         decay = build_address (expression);
   11043                 :    89190889 :       bool is_const = is_rvalue_constant_expression (decay);
   11044                 :    89190889 :       parser->non_integral_constant_expression_p = !is_const;
   11045                 :    89190889 :       if (!is_const && !allow_non_constant_p)
   11046                 :         267 :         require_rvalue_constant_expression (decay);
   11047                 :             :     }
   11048                 :   155616679 :   if (allow_non_constant_p && non_constant_p)
   11049                 :    83150564 :     *non_constant_p = parser->non_integral_constant_expression_p;
   11050                 :   155616679 :   parser->non_integral_constant_expression_p
   11051                 :   155616679 :     = saved_non_integral_constant_expression_p;
   11052                 :             : 
   11053                 :   155616679 :   return expression;
   11054                 :   155616679 : }
   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                 :             : 
   11067                 :             : static cp_expr
   11068                 :        2584 : cp_parser_builtin_offsetof (cp_parser *parser)
   11069                 :             : {
   11070                 :        2584 :   int save_ice_p, save_non_ice_p;
   11071                 :        2584 :   tree type;
   11072                 :        2584 :   cp_expr expr;
   11073                 :        2584 :   cp_id_kind dummy;
   11074                 :        2584 :   cp_token *token;
   11075                 :        2584 :   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                 :        2584 :   save_ice_p = parser->integral_constant_expression_p;
   11081                 :        2584 :   save_non_ice_p = parser->non_integral_constant_expression_p;
   11082                 :             : 
   11083                 :        2584 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   11084                 :             : 
   11085                 :             :   /* Consume the "__builtin_offsetof" token.  */
   11086                 :        2584 :   cp_lexer_consume_token (parser->lexer);
   11087                 :             :   /* Consume the opening `('.  */
   11088                 :        2584 :   matching_parens parens;
   11089                 :        2584 :   parens.require_open (parser);
   11090                 :             :   /* Parse the type-id.  */
   11091                 :        2584 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   11092                 :        2584 :   {
   11093                 :        2584 :     const char *saved_message = parser->type_definition_forbidden_message;
   11094                 :        2584 :     parser->type_definition_forbidden_message
   11095                 :        2584 :       = G_("types may not be defined within %<__builtin_offsetof%>");
   11096                 :        2584 :     type = cp_parser_type_id (parser);
   11097                 :        2584 :     parser->type_definition_forbidden_message = saved_message;
   11098                 :             :   }
   11099                 :             :   /* Look for the `,'.  */
   11100                 :        2584 :   cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   11101                 :        2584 :   token = cp_lexer_peek_token (parser->lexer);
   11102                 :             : 
   11103                 :             :   /* Build the (type *)null that begins the traditional offsetof macro.  */
   11104                 :        2584 :   tree object_ptr
   11105                 :        2584 :     = 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                 :        2584 :   expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, object_ptr,
   11110                 :             :                                                  true, &dummy, token->location);
   11111                 :        3820 :   while (true)
   11112                 :             :     {
   11113                 :        3820 :       token = cp_lexer_peek_token (parser->lexer);
   11114                 :        3820 :       switch (token->type)
   11115                 :             :         {
   11116                 :         912 :         case CPP_OPEN_SQUARE:
   11117                 :             :           /* offsetof-member-designator "[" expression "]" */
   11118                 :         912 :           expr = cp_parser_postfix_open_square_expression (parser, expr,
   11119                 :             :                                                            true, false);
   11120                 :         912 :           break;
   11121                 :             : 
   11122                 :          12 :         case CPP_DEREF:
   11123                 :             :           /* offsetof-member-designator "->" identifier */
   11124                 :          12 :           expr = grok_array_decl (token->location, expr, integer_zero_node,
   11125                 :             :                                   NULL, tf_warning_or_error);
   11126                 :             :           /* FALLTHRU */
   11127                 :             : 
   11128                 :         324 :         case CPP_DOT:
   11129                 :             :           /* offsetof-member-designator "." identifier */
   11130                 :         324 :           cp_lexer_consume_token (parser->lexer);
   11131                 :         324 :           expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT,
   11132                 :             :                                                          expr, true, &dummy,
   11133                 :             :                                                          token->location);
   11134                 :         324 :           break;
   11135                 :             : 
   11136                 :        2584 :         case CPP_CLOSE_PAREN:
   11137                 :             :           /* Consume the ")" token.  */
   11138                 :        2584 :           finish_loc = cp_lexer_peek_token (parser->lexer)->location;
   11139                 :        2584 :           cp_lexer_consume_token (parser->lexer);
   11140                 :        2584 :           goto success;
   11141                 :             : 
   11142                 :           0 :         default:
   11143                 :             :           /* Error.  We know the following require will fail, but
   11144                 :             :              that gives the proper error message.  */
   11145                 :           0 :           parens.require_close (parser);
   11146                 :           0 :           cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
   11147                 :           0 :           expr = error_mark_node;
   11148                 :           0 :           goto failure;
   11149                 :             :         }
   11150                 :             :     }
   11151                 :             : 
   11152                 :        2584 :  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                 :        2584 :   loc = make_location (loc, start_loc, finish_loc);
   11159                 :             :   /* The result will be an INTEGER_CST, so we need to explicitly
   11160                 :             :      preserve the location.  */
   11161                 :        2584 :   expr = cp_expr (finish_offsetof (object_ptr, expr, loc), loc);
   11162                 :             : 
   11163                 :        2584 :  failure:
   11164                 :        2584 :   parser->integral_constant_expression_p = save_ice_p;
   11165                 :        2584 :   parser->non_integral_constant_expression_p = save_non_ice_p;
   11166                 :             : 
   11167                 :        2584 :   expr = expr.maybe_add_location_wrapper ();
   11168                 :        2584 :   return expr;
   11169                 :             : }
   11170                 :             : 
   11171                 :             : /* Parse a builtin trait expression or type.  */
   11172                 :             : 
   11173                 :             : static cp_expr
   11174                 :     1911468 : cp_parser_trait (cp_parser* parser, const cp_trait* trait)
   11175                 :             : {
   11176                 :     1911468 :   const cp_trait_kind kind = trait->kind;
   11177                 :     1911468 :   tree type1, type2 = NULL_TREE;
   11178                 :     1911468 :   const bool binary = (trait->arity == 2);
   11179                 :     1911468 :   const bool variadic = (trait->arity == -1);
   11180                 :     1911468 :   const bool type = trait->type;
   11181                 :             : 
   11182                 :             :   /* Get location of initial token.  */
   11183                 :     1911468 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   11184                 :             : 
   11185                 :             :   /* Consume the token.  */
   11186                 :     1911468 :   cp_lexer_consume_token (parser->lexer);
   11187                 :             : 
   11188                 :     1911468 :   matching_parens parens;
   11189                 :     1911468 :   if (kind == CPTK_TYPE_PACK_ELEMENT)
   11190                 :       12975 :     cp_parser_require (parser, CPP_LESS, RT_LESS);
   11191                 :             :   else
   11192                 :     1898493 :     parens.require_open (parser);
   11193                 :             : 
   11194                 :     1911468 :   if (kind == CPTK_IS_DEDUCIBLE)
   11195                 :             :     {
   11196                 :           0 :       const cp_token* token = cp_lexer_peek_token (parser->lexer);
   11197                 :           0 :       type1 = cp_parser_id_expression (parser,
   11198                 :             :                                        /*template_keyword_p=*/false,
   11199                 :             :                                        /*check_dependency_p=*/true,
   11200                 :             :                                        nullptr,
   11201                 :             :                                        /*declarator_p=*/false,
   11202                 :             :                                        /*optional_p=*/false);
   11203                 :           0 :       type1 = cp_parser_lookup_name_simple (parser, type1, token->location);
   11204                 :             :     }
   11205                 :     1911468 :   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                 :       12975 :     type1 = cp_parser_constant_expression (parser);
   11211                 :             :   else
   11212                 :             :     {
   11213                 :     1898493 :       type_id_in_expr_sentinel s (parser);
   11214                 :     3796986 :       type1 = cp_parser_type_id (parser);
   11215                 :     1898493 :     }
   11216                 :             : 
   11217                 :     1911468 :   if (type1 == error_mark_node)
   11218                 :          20 :     return error_mark_node;
   11219                 :             : 
   11220                 :     1911448 :   if (kind == CPTK_TYPE_PACK_ELEMENT)
   11221                 :             :     {
   11222                 :       12975 :       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   11223                 :       12975 :       tree trailing = cp_parser_enclosed_template_argument_list (parser);
   11224                 :       25977 :       for (tree elt : tree_vec_range (trailing))
   11225                 :             :         {
   11226                 :       13002 :           if (!TYPE_P (elt))
   11227                 :             :             {
   11228                 :           0 :               error_at (cp_expr_loc_or_input_loc (elt),
   11229                 :             :                         "trailing argument to %<__type_pack_element%> "
   11230                 :             :                         "is not a type");
   11231                 :           0 :               return error_mark_node;
   11232                 :             :             }
   11233                 :             :         }
   11234                 :       12975 :       type2 = trailing;
   11235                 :             :     }
   11236                 :     1898473 :   else if (binary)
   11237                 :             :     {
   11238                 :      676124 :       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   11239                 :             : 
   11240                 :      676124 :       {
   11241                 :      676124 :         type_id_in_expr_sentinel s (parser);
   11242                 :     1352248 :         type2 = cp_parser_type_id (parser);
   11243                 :      676124 :       }
   11244                 :             : 
   11245                 :      676124 :       if (type2 == error_mark_node)
   11246                 :           3 :         return error_mark_node;
   11247                 :             :     }
   11248                 :     1222349 :   else if (variadic)
   11249                 :             :     {
   11250                 :      198803 :       auto_vec<tree, 4> trailing;
   11251                 :      358751 :       while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   11252                 :             :         {
   11253                 :      159948 :           cp_lexer_consume_token (parser->lexer);
   11254                 :      319896 :           tree elt = cp_parser_type_id (parser);
   11255                 :      159948 :           if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   11256                 :             :             {
   11257                 :       82143 :               cp_lexer_consume_token (parser->lexer);
   11258                 :       82143 :               elt = make_pack_expansion (elt);
   11259                 :             :             }
   11260                 :      159948 :           if (elt == error_mark_node)
   11261                 :           0 :             return error_mark_node;
   11262                 :      159948 :           trailing.safe_push (elt);
   11263                 :             :         }
   11264                 :      198803 :       type2 = make_tree_vec (trailing.length ());
   11265                 :      358751 :       for (int i = 0; i < TREE_VEC_LENGTH (type2); ++i)
   11266                 :      159948 :         TREE_VEC_ELT (type2, i) = trailing[i];
   11267                 :      198803 :     }
   11268                 :             : 
   11269                 :     1911445 :   location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
   11270                 :     1911445 :   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                 :     1898470 :     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                 :     1911445 :   location_t trait_loc = make_location (start_loc, start_loc, 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                 :     1911445 :   switch (kind)
   11285                 :             :     {
   11286                 :          14 :     case CPTK_BASES:
   11287                 :          14 :       return cp_expr (finish_bases (type1, false), trait_loc);
   11288                 :          14 :     case CPTK_DIRECT_BASES:
   11289                 :          14 :       return cp_expr (finish_bases (type1, true), trait_loc);
   11290                 :     1911417 :     default:
   11291                 :     1911417 :       if (type)
   11292                 :       70294 :         return finish_trait_type (kind, type1, type2, tf_warning_or_error);
   11293                 :             :       else
   11294                 :     1841123 :         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                 :             : 
   11307                 :             : static cp_expr
   11308                 :      528715 : cp_parser_lambda_expression (cp_parser* parser)
   11309                 :             : {
   11310                 :      528715 :   tree lambda_expr = build_lambda_expr ();
   11311                 :      528715 :   tree type;
   11312                 :      528715 :   bool ok = true;
   11313                 :      528715 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   11314                 :      528715 :   cp_token_position start = 0;
   11315                 :             : 
   11316                 :      528715 :   LAMBDA_EXPR_LOCATION (lambda_expr) = token->location;
   11317                 :             : 
   11318                 :      528715 :   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                 :      265367 :       if (processing_template_parmlist && !parser->local_variables_forbidden_p)
   11327                 :             :         {
   11328                 :           1 :           error_at (token->location,
   11329                 :             :                     "lambda-expression in template parameter type");
   11330                 :           1 :           token->error_reported = true;
   11331                 :           1 :           ok = false;
   11332                 :             :         }
   11333                 :             :     }
   11334                 :      263348 :   else if (cp_unevaluated_operand)
   11335                 :             :     {
   11336                 :           6 :       if (!token->error_reported)
   11337                 :             :         {
   11338                 :           6 :           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                 :           6 :           token->error_reported = true;
   11342                 :             :         }
   11343                 :             :       ok = false;
   11344                 :             :     }
   11345                 :      263342 :   else if (parser->in_template_argument_list_p || processing_template_parmlist)
   11346                 :             :     {
   11347                 :           9 :       if (!token->error_reported)
   11348                 :             :         {
   11349                 :           9 :           error_at (token->location, "lambda-expression in template-argument"
   11350                 :             :                     " only available with %<-std=c++20%> or %<-std=gnu++20%>");
   11351                 :           9 :           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                 :      528715 :   push_deferring_access_checks (dk_no_deferred);
   11359                 :             : 
   11360                 :      528715 :   cp_parser_lambda_introducer (parser, lambda_expr);
   11361                 :     1057430 :   if (cp_parser_error_occurred (parser))
   11362                 :           5 :     return error_mark_node;
   11363                 :             : 
   11364                 :      528710 :   type = begin_lambda_type (lambda_expr);
   11365                 :      528710 :   if (type == error_mark_node)
   11366                 :           0 :     return error_mark_node;
   11367                 :             : 
   11368                 :      528710 :   record_lambda_scope (lambda_expr);
   11369                 :      528710 :   record_lambda_scope_discriminator (lambda_expr);
   11370                 :             : 
   11371                 :             :   /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
   11372                 :      528710 :   determine_visibility (TYPE_NAME (type));
   11373                 :             : 
   11374                 :             :   /* Now that we've started the type, add the capture fields for any
   11375                 :             :      explicit captures.  */
   11376                 :      528710 :   register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
   11377                 :             : 
   11378                 :      528710 :   {
   11379                 :             :     /* Inside the class, surrounding template-parameter-lists do not apply.  */
   11380                 :      528710 :     unsigned int saved_num_template_parameter_lists
   11381                 :             :         = parser->num_template_parameter_lists;
   11382                 :      528710 :     unsigned char in_statement = parser->in_statement;
   11383                 :      528710 :     bool in_switch_statement_p = parser->in_switch_statement_p;
   11384                 :      528710 :     bool fully_implicit_function_template_p
   11385                 :             :         = parser->fully_implicit_function_template_p;
   11386                 :      528710 :     tree implicit_template_parms = parser->implicit_template_parms;
   11387                 :      528710 :     cp_binding_level* implicit_template_scope = parser->implicit_template_scope;
   11388                 :      528710 :     bool auto_is_implicit_function_template_parm_p
   11389                 :             :         = parser->auto_is_implicit_function_template_parm_p;
   11390                 :      528710 :     bool saved_omp_array_section_p = parser->omp_array_section_p;
   11391                 :             : 
   11392                 :      528710 :     parser->num_template_parameter_lists = 0;
   11393                 :      528710 :     parser->in_statement = 0;
   11394                 :      528710 :     parser->in_switch_statement_p = false;
   11395                 :      528710 :     parser->fully_implicit_function_template_p = false;
   11396                 :      528710 :     parser->implicit_template_parms = 0;
   11397                 :      528710 :     parser->implicit_template_scope = 0;
   11398                 :      528710 :     parser->auto_is_implicit_function_template_parm_p = false;
   11399                 :      528710 :     parser->omp_array_section_p = false;
   11400                 :             : 
   11401                 :             :     /* The body of a lambda in a discarded statement is not discarded.  */
   11402                 :      528710 :     bool discarded = in_discarded_stmt;
   11403                 :      528710 :     in_discarded_stmt = 0;
   11404                 :             : 
   11405                 :             :     /* Similarly the body of a lambda in immediate function context is not
   11406                 :             :        in immediate function context.  */
   11407                 :      528710 :     bool save_in_consteval_if_p = in_consteval_if_p;
   11408                 :      528710 :     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                 :      528710 :     if (cp_parser_start_tentative_firewall (parser))
   11414                 :       12840 :       start = token;
   11415                 :             : 
   11416                 :      528710 :     ok &= cp_parser_lambda_declarator_opt (parser, lambda_expr);
   11417                 :             : 
   11418                 :      528710 :     if (ok && cp_parser_error_occurred (parser))
   11419                 :             :       ok = false;
   11420                 :             : 
   11421                 :      528710 :     if (ok)
   11422                 :      528681 :       cp_parser_lambda_body (parser, lambda_expr);
   11423                 :          29 :     else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
   11424                 :             :       {
   11425                 :          24 :         if (cp_parser_skip_to_closing_brace (parser))
   11426                 :          24 :           cp_lexer_consume_token (parser->lexer);
   11427                 :             :       }
   11428                 :             : 
   11429                 :             :     /* The capture list was built up in reverse order; fix that now.  */
   11430                 :      528710 :     LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)
   11431                 :      528710 :       = nreverse (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));
   11432                 :             : 
   11433                 :      528710 :     if (ok)
   11434                 :      528681 :       maybe_add_lambda_conv_op (type);
   11435                 :             : 
   11436                 :      528710 :     finish_struct (type, /*attributes=*/NULL_TREE);
   11437                 :             : 
   11438                 :      528710 :     in_consteval_if_p = save_in_consteval_if_p;
   11439                 :      528710 :     in_discarded_stmt = discarded;
   11440                 :             : 
   11441                 :      528710 :     parser->num_template_parameter_lists = saved_num_template_parameter_lists;
   11442                 :      528710 :     parser->in_statement = in_statement;
   11443                 :      528710 :     parser->in_switch_statement_p = in_switch_statement_p;
   11444                 :      528710 :     parser->fully_implicit_function_template_p
   11445                 :      528710 :         = fully_implicit_function_template_p;
   11446                 :      528710 :     parser->implicit_template_parms = implicit_template_parms;
   11447                 :      528710 :     parser->implicit_template_scope = implicit_template_scope;
   11448                 :      528710 :     parser->auto_is_implicit_function_template_parm_p
   11449                 :      528710 :         = auto_is_implicit_function_template_parm_p;
   11450                 :      528710 :     parser->omp_array_section_p = saved_omp_array_section_p;
   11451                 :             :   }
   11452                 :             : 
   11453                 :             :   /* This field is only used during parsing of the lambda.  */
   11454                 :      528710 :   LAMBDA_EXPR_THIS_CAPTURE (lambda_expr) = NULL_TREE;
   11455                 :             : 
   11456                 :             :   /* This lambda shouldn't have any proxies left at this point.  */
   11457                 :      528710 :   gcc_assert (LAMBDA_EXPR_PENDING_PROXIES (lambda_expr) == NULL);
   11458                 :             :   /* And now that we're done, push proxies for an enclosing lambda.  */
   11459                 :      528710 :   insert_pending_capture_proxies ();
   11460                 :             : 
   11461                 :             :   /* Update the lambda expression to a range.  */
   11462                 :      528710 :   LAMBDA_EXPR_LOCATION (lambda_expr) = make_location (token->location,
   11463                 :             :                                                       token->location,
   11464                 :             :                                                       parser->lexer);
   11465                 :             : 
   11466                 :      528710 :   if (ok)
   11467                 :      528681 :     lambda_expr = build_lambda_object (lambda_expr);
   11468                 :             :   else
   11469                 :          29 :     lambda_expr = error_mark_node;
   11470                 :             : 
   11471                 :      528710 :   cp_parser_end_tentative_firewall (parser, start, lambda_expr);
   11472                 :             : 
   11473                 :      528710 :   pop_deferring_access_checks ();
   11474                 :             : 
   11475                 :      528710 :   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                 :             : 
   11485                 :             : static void
   11486                 :      528715 : cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
   11487                 :             : {
   11488                 :             :   /* Need commas after the first capture.  */
   11489                 :      528715 :   bool first = true;
   11490                 :             : 
   11491                 :             :   /* Eat the leading `['.  */
   11492                 :      528715 :   cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
   11493                 :             : 
   11494                 :             :   /* Record default capture mode.  "[&" "[=" "[&," "[=,"  */
   11495                 :      528715 :   if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
   11496                 :      241041 :       && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS)
   11497                 :      241039 :       && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)
   11498                 :      671112 :       && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
   11499                 :      142394 :     LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE;
   11500                 :      386321 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   11501                 :       37982 :     LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY;
   11502                 :             : 
   11503                 :      528715 :   if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE)
   11504                 :             :     {
   11505                 :      180376 :       cp_lexer_consume_token (parser->lexer);
   11506                 :      180376 :       first = false;
   11507                 :             : 
   11508                 :      180376 :       if (!(at_function_scope_p () || parsing_nsdmi ()))
   11509                 :          15 :         error ("non-local lambda expression cannot have a capture-default");
   11510                 :             :     }
   11511                 :             : 
   11512                 :      528715 :   hash_set<tree, true> ids;
   11513                 :      528715 :   tree first_capture_id = NULL_TREE;
   11514                 :      528715 :   unsigned name_independent_cnt = 0;
   11515                 :      937241 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE))
   11516                 :             :     {
   11517                 :      408545 :       cp_token* capture_token;
   11518                 :      408545 :       tree capture_id;
   11519                 :      408545 :       tree capture_init_expr;
   11520                 :      408545 :       cp_id_kind idk = CP_ID_KIND_NONE;
   11521                 :      408545 :       bool explicit_init_p = false;
   11522                 :             : 
   11523                 :      408545 :       enum capture_kind_type
   11524                 :             :       {
   11525                 :             :         BY_COPY,
   11526                 :             :         BY_REFERENCE
   11527                 :             :       };
   11528                 :      408545 :       enum capture_kind_type capture_kind = BY_COPY;
   11529                 :             : 
   11530                 :      408545 :       if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
   11531                 :             :         {
   11532                 :           3 :           error ("expected end of capture-list");
   11533                 :           3 :           return;
   11534                 :             :         }
   11535                 :             : 
   11536                 :      408542 :       if (first)
   11537                 :             :         first = false;
   11538                 :             :       else
   11539                 :      139372 :         cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   11540                 :             : 
   11541                 :             :       /* Possibly capture `this'.  */
   11542                 :      408542 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS))
   11543                 :             :         {
   11544                 :      119192 :           location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   11545                 :       57771 :           if (cxx_dialect < cxx20 && pedantic
   11546                 :      119384 :               && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY)
   11547                 :          16 :             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                 :      119192 :           cp_lexer_consume_token (parser->lexer);
   11552                 :      119192 :           if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
   11553                 :          18 :             pedwarn (input_location, 0,
   11554                 :             :                      "already captured %qD in lambda expression",
   11555                 :             :                      this_identifier);
   11556                 :             :           else
   11557                 :      119174 :             add_capture (lambda_expr, /*id=*/this_identifier,
   11558                 :             :                          /*initializer=*/finish_this_expr (),
   11559                 :             :                          /*by_reference_p=*/true, explicit_init_p, NULL);
   11560                 :      119357 :           continue;
   11561                 :      119192 :         }
   11562                 :             : 
   11563                 :             :       /* Possibly capture `*this'.  */
   11564                 :      289350 :       if (cp_lexer_next_token_is (parser->lexer, CPP_MULT)
   11565                 :      289350 :           && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
   11566                 :             :         {
   11567                 :         119 :           location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   11568                 :         119 :           if (cxx_dialect < cxx17)
   11569                 :          27 :             pedwarn (loc, OPT_Wc__17_extensions,
   11570                 :             :                      "%<*this%> capture only available with "
   11571                 :             :                      "%<-std=c++17%> or %<-std=gnu++17%>");
   11572                 :         119 :           cp_lexer_consume_token (parser->lexer);
   11573                 :         119 :           cp_lexer_consume_token (parser->lexer);
   11574                 :         119 :           if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
   11575                 :          15 :             pedwarn (input_location, 0,
   11576                 :             :                      "already captured %qD in lambda expression",
   11577                 :             :                      this_identifier);
   11578                 :             :           else
   11579                 :         104 :             add_capture (lambda_expr, /*id=*/this_identifier,
   11580                 :             :                          /*initializer=*/finish_this_expr (),
   11581                 :             :                          /*by_reference_p=*/false, explicit_init_p, NULL);
   11582                 :         119 :           continue;
   11583                 :         119 :         }
   11584                 :             : 
   11585                 :             :       /* But reject `&this'.  */
   11586                 :      289237 :       if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
   11587                 :      289231 :           && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
   11588                 :             :         {
   11589                 :           6 :           error_at (cp_lexer_peek_token (parser->lexer)->location,
   11590                 :             :                     "%<this%> cannot be captured by reference");
   11591                 :           6 :           cp_lexer_consume_token (parser->lexer);
   11592                 :           6 :           cp_lexer_consume_token (parser->lexer);
   11593                 :           6 :           continue;
   11594                 :             :         }
   11595                 :             : 
   11596                 :             :       /* Remember whether we want to capture as a reference or not.  */
   11597                 :      289225 :       if (cp_lexer_next_token_is (parser->lexer, CPP_AND))
   11598                 :             :         {
   11599                 :      214447 :           capture_kind = BY_REFERENCE;
   11600                 :      214447 :           cp_lexer_consume_token (parser->lexer);
   11601                 :             :         }
   11602                 :             : 
   11603                 :      289225 :       bool init_pack_expansion = false;
   11604                 :      289225 :       location_t ellipsis_loc = UNKNOWN_LOCATION;
   11605                 :      289225 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   11606                 :             :         {
   11607                 :          16 :           ellipsis_loc = cp_lexer_peek_token (parser->lexer)->location;
   11608                 :          16 :           if (cxx_dialect < cxx20)
   11609                 :           0 :             pedwarn (ellipsis_loc, OPT_Wc__20_extensions,
   11610                 :             :                      "pack init-capture only available with "
   11611                 :             :                      "%<-std=c++20%> or %<-std=gnu++20%>");
   11612                 :          16 :           cp_lexer_consume_token (parser->lexer);
   11613                 :          16 :           init_pack_expansion = true;
   11614                 :             :         }
   11615                 :             : 
   11616                 :             :       /* Early C++20 drafts had ...& instead of &...; be forgiving.  */
   11617                 :      289225 :       if (init_pack_expansion && capture_kind != BY_REFERENCE
   11618                 :      289225 :           && cp_lexer_next_token_is (parser->lexer, CPP_AND))
   11619                 :             :         {
   11620                 :           1 :           pedwarn (cp_lexer_peek_token (parser->lexer)->location,
   11621                 :             :                    0, "%<&%> should come before %<...%>");
   11622                 :           1 :           capture_kind = BY_REFERENCE;
   11623                 :           1 :           cp_lexer_consume_token (parser->lexer);
   11624                 :             :         }
   11625                 :             : 
   11626                 :             :       /* Get the identifier.  */
   11627                 :      289225 :       capture_token = cp_lexer_peek_token (parser->lexer);
   11628                 :      289225 :       capture_id = cp_parser_identifier (parser);
   11629                 :             : 
   11630                 :      289225 :       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                 :          16 :           cp_parser_skip_to_closing_parenthesis (parser,
   11637                 :             :                                                  /*recovering=*/true,
   11638                 :             :                                                  /*or_comma=*/true,
   11639                 :             :                                                  /*consume_paren=*/true);
   11640                 :          16 :           break;
   11641                 :             :         }
   11642                 :             : 
   11643                 :             :       /* Find the initializer for this capture.  */
   11644                 :      289209 :       if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
   11645                 :             :           || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
   11646                 :             :           || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   11647                 :             :         {
   11648                 :             :           /* An explicit initializer exists.  */
   11649                 :         493 :           if (cxx_dialect < cxx14)
   11650                 :           4 :             pedwarn (input_location, OPT_Wc__14_extensions,
   11651                 :             :                      "lambda capture initializers "
   11652                 :             :                      "only available with %<-std=c++14%> or %<-std=gnu++14%>");
   11653                 :         493 :           capture_init_expr = cp_parser_initializer (parser,
   11654                 :             :                                                      /*direct_init=*/nullptr,
   11655                 :             :                                                      /*non_constant=*/nullptr,
   11656                 :             :                                                      /*subexpression_p=*/true);
   11657                 :         493 :           explicit_init_p = true;
   11658                 :         493 :           if (capture_init_expr == NULL_TREE)
   11659                 :             :             {
   11660                 :           3 :               error ("empty initializer for lambda init-capture");
   11661                 :           3 :               capture_init_expr = error_mark_node;
   11662                 :             :             }
   11663                 :         493 :           if (init_pack_expansion)
   11664                 :          12 :             capture_init_expr = make_pack_expansion (capture_init_expr);
   11665                 :             :         }
   11666                 :             :       else
   11667                 :             :         {
   11668                 :      288716 :           const char* error_msg;
   11669                 :             : 
   11670                 :             :           /* Turn the identifier into an id-expression.  */
   11671                 :      288716 :           capture_init_expr
   11672                 :      288716 :             = cp_parser_lookup_name_simple (parser, capture_id,
   11673                 :             :                                             capture_token->location);
   11674                 :             : 
   11675                 :      288716 :           if (capture_init_expr == error_mark_node)
   11676                 :             :             {
   11677                 :          18 :               unqualified_name_lookup_error (capture_id);
   11678                 :          40 :               continue;
   11679                 :             :             }
   11680                 :      288698 :           else if (!VAR_P (capture_init_expr)
   11681                 :      165884 :                    && TREE_CODE (capture_init_expr) != PARM_DECL)
   11682                 :             :             {
   11683                 :          15 :               error_at (capture_token->location,
   11684                 :             :                         "capture of non-variable %qE",
   11685                 :             :                         capture_init_expr);
   11686                 :          15 :               if (DECL_P (capture_init_expr))
   11687                 :           6 :                 inform (DECL_SOURCE_LOCATION (capture_init_expr),
   11688                 :             :                         "%q#D declared here", capture_init_expr);
   11689                 :          15 :               continue;
   11690                 :             :             }
   11691                 :      288686 :           if (VAR_P (capture_init_expr)
   11692                 :      288683 :               && decl_storage_duration (capture_init_expr) != dk_auto)
   11693                 :             :             {
   11694                 :           3 :               if (pedwarn (capture_token->location, 0, "capture of variable "
   11695                 :             :                            "%qD with non-automatic storage duration",
   11696                 :             :                            capture_init_expr))
   11697                 :           3 :                 inform (DECL_SOURCE_LOCATION (capture_init_expr),
   11698                 :             :                         "%q#D declared here", capture_init_expr);
   11699                 :           3 :               continue;
   11700                 :             :             }
   11701                 :             : 
   11702                 :      288680 :           capture_init_expr
   11703                 :             :             = finish_id_expression
   11704                 :      288680 :                 (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                 :      288680 :           if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   11719                 :             :             {
   11720                 :          38 :               location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   11721                 :          38 :               cp_lexer_consume_token (parser->lexer);
   11722                 :          38 :               capture_init_expr = make_pack_expansion (capture_init_expr);
   11723                 :          38 :               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                 :           4 :                   if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
   11729                 :             :                       || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
   11730                 :             :                       || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   11731                 :             :                     ellipsis_loc = loc;
   11732                 :           4 :                   error_at (ellipsis_loc, "too many %<...%> in lambda capture");
   11733                 :           4 :                   continue;
   11734                 :             :                 }
   11735                 :             :             }
   11736                 :             :         }
   11737                 :             : 
   11738                 :      289169 :       if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
   11739                 :      289169 :           && !explicit_init_p)
   11740                 :             :         {
   11741                 :         135 :           if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY
   11742                 :         135 :               && capture_kind == BY_COPY)
   11743                 :          12 :             pedwarn (capture_token->location, 0, "explicit by-copy capture "
   11744                 :             :                      "of %qD redundant with by-copy capture default",
   11745                 :             :                      capture_id);
   11746                 :         135 :           if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_REFERENCE
   11747                 :         135 :               && capture_kind == BY_REFERENCE)
   11748                 :           6 :             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                 :      289169 :       bool found = false;
   11757                 :      289169 :       if (!ids.is_empty ())
   11758                 :        1700 :         found = ids.add (capture_id);
   11759                 :      287469 :       else if (first_capture_id == NULL_TREE)
   11760                 :      208543 :         first_capture_id = capture_id;
   11761                 :       78926 :       else if (capture_id == first_capture_id)
   11762                 :             :         found = true;
   11763                 :             :       else
   11764                 :             :         {
   11765                 :       78911 :           ids.add (first_capture_id);
   11766                 :       78911 :           ids.add (capture_id);
   11767                 :             :         }
   11768                 :      289169 :       if (found && explicit_init_p && id_equal (capture_id, "_"))
   11769                 :             :         found = false;
   11770                 :      289157 :       if (found)
   11771                 :           9 :         pedwarn (input_location, 0,
   11772                 :             :                  "already captured %qD in lambda expression", capture_id);
   11773                 :             :       else
   11774                 :      289160 :         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                 :      289169 :       parser->scope = NULL_TREE;
   11781                 :      289169 :       parser->qualifying_scope = NULL_TREE;
   11782                 :      289169 :       parser->object_scope = NULL_TREE;
   11783                 :             :     }
   11784                 :             : 
   11785                 :      528712 :   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
   11786                 :      528715 : }
   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                 :             : 
   11800                 :             : static bool
   11801                 :      528710 : cp_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                 :      528710 :   tree param_list = void_list_node;
   11809                 :      528710 :   tree std_attrs = NULL_TREE;
   11810                 :      528710 :   tree gnu_attrs = NULL_TREE;
   11811                 :      528710 :   tree exception_spec = NULL_TREE;
   11812                 :      528710 :   tree template_param_list = NULL_TREE;
   11813                 :      528710 :   tree tx_qual = NULL_TREE;
   11814                 :      528710 :   tree return_type = NULL_TREE;
   11815                 :      528710 :   tree trailing_requires_clause = NULL_TREE;
   11816                 :      528710 :   bool has_param_list = false;
   11817                 :      528710 :   location_t omitted_parms_loc = UNKNOWN_LOCATION;
   11818                 :      528710 :   cp_decl_specifier_seq lambda_specs;
   11819                 :      528710 :   clear_decl_specs (&lambda_specs);
   11820                 :             :   /* A lambda op() is const unless explicitly 'mutable'.  */
   11821                 :      528710 :   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                 :      528710 :   if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
   11826                 :             :     {
   11827                 :       41404 :       if (cxx_dialect < cxx20
   11828                 :          57 :           && (pedantic || cxx_dialect < cxx14))
   11829                 :          33 :         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                 :       41404 :       cp_lexer_consume_token (parser->lexer);
   11834                 :             : 
   11835                 :       41404 :       template_param_list = cp_parser_template_parameter_list (parser);
   11836                 :       41404 :       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                 :       41404 :       tree dreqs = cp_parser_requires_clause_opt (parser, true);
   11842                 :       41404 :       if (flag_concepts)
   11843                 :             :         {
   11844                 :       41347 :           tree reqs = get_shorthand_constraints (current_template_parms);
   11845                 :       41347 :           if (dreqs)
   11846                 :           8 :             reqs = combine_constraint_expressions (reqs, dreqs);
   11847                 :       41347 :           TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
   11848                 :             :         }
   11849                 :             : 
   11850                 :             :       /* We just processed one more parameter list.  */
   11851                 :       41404 :       ++parser->num_template_parameter_lists;
   11852                 :             :     }
   11853                 :             : 
   11854                 :             :   /* Committee discussion supports allowing attributes here.  */
   11855                 :      528710 :   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                 :      528710 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   11861                 :             :     {
   11862                 :      438784 :       matching_parens parens;
   11863                 :      438784 :       parens.consume_open (parser);
   11864                 :             : 
   11865                 :      438784 :       begin_scope (sk_function_parms, /*entity=*/NULL_TREE);
   11866                 :             : 
   11867                 :             :       /* Parse parameters.  */
   11868                 :      438784 :       param_list
   11869                 :             :         = cp_parser_parameter_declaration_clause
   11870                 :      438784 :             (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                 :      438784 :       if (pedantic && cxx_dialect < cxx14)
   11875                 :          70 :         for (tree t = param_list; t; t = TREE_CHAIN (t))
   11876                 :          48 :           if (TREE_PURPOSE (t) && DECL_P (TREE_VALUE (t)))
   11877                 :           1 :             pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)),
   11878                 :             :                      OPT_Wc__14_extensions,
   11879                 :             :                      "default argument specified for lambda parameter");
   11880                 :             : 
   11881                 :      438784 :       parens.require_close (parser);
   11882                 :      438784 :       has_param_list = true;
   11883                 :             :     }
   11884                 :       89926 :   else if (cxx_dialect < cxx23)
   11885                 :       55314 :     omitted_parms_loc = cp_lexer_peek_token (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                 :      528710 :   int declares_class_or_enum;
   11894                 :      528710 :   if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
   11895                 :      132536 :     cp_parser_decl_specifier_seq (parser,
   11896                 :             :                                   CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR,
   11897                 :             :                                   &lambda_specs, &declares_class_or_enum);
   11898                 :             : 
   11899                 :      528710 :   if (omitted_parms_loc && lambda_specs.any_specifiers_p)
   11900                 :             :     {
   11901                 :           6 :       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                 :           6 :       omitted_parms_loc = UNKNOWN_LOCATION;
   11906                 :             :     }
   11907                 :             :   /* Peek at the params, see if we have an xobj parameter.  */
   11908                 :     1057402 :   if (param_list && TREE_PURPOSE (param_list) == this_identifier)
   11909                 :             :     {
   11910                 :         274 :       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                 :         274 :       tree const xobj_param = TREE_VALUE (param_list);
   11914                 :         274 :       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                 :         274 :       bool const unrelated_with_captures
   11923                 :         274 :         = (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
   11924                 :         226 :            || 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                 :         394 :           && !WILDCARD_TYPE_P (non_reference (param_type));
   11929                 :           2 :       if (unrelated_with_captures)
   11930                 :             :         {
   11931                 :           2 :           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                 :           2 :           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                 :         274 :       if (lambda_specs.storage_class == sc_mutable)
   11942                 :             :         {
   11943                 :          16 :           auto_diagnostic_group d;
   11944                 :          16 :           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                 :          16 :           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                 :          16 :           else if (!TYPE_REF_P (param_type))
   11953                 :           4 :             inform (DECL_SOURCE_LOCATION (xobj_param),
   11954                 :             :                     "the passed in closure object will not be mutated because "
   11955                 :             :                     "it is taken by value");
   11956                 :          12 :           else if (TYPE_READONLY (TREE_TYPE (param_type)))
   11957                 :           4 :             inform (DECL_SOURCE_LOCATION (xobj_param),
   11958                 :             :                     "declare the explicit object parameter as non-const "
   11959                 :             :                     "reference instead");
   11960                 :             :           else
   11961                 :           8 :             inform (DECL_SOURCE_LOCATION (xobj_param),
   11962                 :             :                     "explicit object parameter is already a mutable "
   11963                 :             :                     "reference");
   11964                 :          16 :         }
   11965                 :         258 :       else if (lambda_specs.storage_class == sc_static)
   11966                 :             :         {
   11967                 :          16 :           auto_diagnostic_group d;
   11968                 :          16 :           error_at (lambda_specs.locations[ds_storage_class],
   11969                 :             :                     "%<static%> lambda specifier "
   11970                 :             :                     "with explicit object parameter");
   11971                 :          16 :           inform (DECL_SOURCE_LOCATION (xobj_param),
   11972                 :             :                   "explicit object parameter declared here");
   11973                 :          16 :         }
   11974                 :             :     }
   11975                 :      528436 :   else if (lambda_specs.storage_class == sc_mutable)
   11976                 :             :     {
   11977                 :             :       quals = TYPE_UNQUALIFIED;
   11978                 :             :     }
   11979                 :      397062 :   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                 :          33 :       if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
   11985                 :          33 :           || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr))
   11986                 :           9 :         error_at (lambda_specs.locations[ds_storage_class],
   11987                 :             :                   "%<static%> lambda specifier with lambda capture");
   11988                 :             :       else
   11989                 :             :         {
   11990                 :          24 :           LAMBDA_EXPR_STATIC_P (lambda_expr) = 1;
   11991                 :          24 :           quals = TYPE_UNQUALIFIED;
   11992                 :             :         }
   11993                 :             :     }
   11994                 :             : 
   11995                 :      528710 :   tx_qual = cp_parser_tx_qualifier_opt (parser);
   11996                 :      528710 :   if (omitted_parms_loc && tx_qual)
   11997                 :             :     {
   11998                 :           0 :       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                 :           0 :       omitted_parms_loc = UNKNOWN_LOCATION;
   12003                 :             :     }
   12004                 :             : 
   12005                 :             :   /* Parse optional exception specification.  */
   12006                 :      528710 :   exception_spec
   12007                 :      528710 :     = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE);
   12008                 :             : 
   12009                 :      528710 :   if (omitted_parms_loc && exception_spec)
   12010                 :             :     {
   12011                 :           6 :       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                 :           6 :       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                 :      528710 :   if (cp_next_tokens_can_be_gnu_attribute_p (parser))
   12021                 :        1833 :     gnu_attrs = cp_parser_gnu_attributes_opt (parser);
   12022                 :             :   else
   12023                 :      526877 :     std_attrs = cp_parser_std_attribute_spec_seq (parser);
   12024                 :             : 
   12025                 :             :   /* Parse optional trailing return type.  */
   12026                 :      528710 :   if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
   12027                 :             :     {
   12028                 :       69946 :       if (omitted_parms_loc)
   12029                 :           3 :         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                 :       69946 :       cp_lexer_consume_token (parser->lexer);
   12034                 :       69946 :       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                 :      528710 :   if (cp_next_tokens_can_be_gnu_attribute_p (parser))
   12040                 :           3 :     gnu_attrs = chainon (gnu_attrs, cp_parser_gnu_attributes_opt (parser));
   12041                 :             : 
   12042                 :      528710 :   if (has_param_list)
   12043                 :             :     {
   12044                 :             :       /* Parse optional trailing requires clause.  */
   12045                 :      438784 :       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                 :      438784 :       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                 :      528710 :   {
   12058                 :      528710 :     cp_decl_specifier_seq return_type_specs;
   12059                 :      528710 :     cp_declarator* declarator;
   12060                 :      528710 :     tree fco;
   12061                 :      528710 :     void *p;
   12062                 :             : 
   12063                 :      528710 :     clear_decl_specs (&return_type_specs);
   12064                 :      528710 :     return_type_specs.type = make_auto ();
   12065                 :             : 
   12066                 :      528710 :     if (lambda_specs.locations[ds_constexpr])
   12067                 :             :       {
   12068                 :        1094 :         if (cxx_dialect >= cxx17)
   12069                 :        1093 :           return_type_specs.locations[ds_constexpr]
   12070                 :        1093 :             = lambda_specs.locations[ds_constexpr];
   12071                 :             :         else
   12072                 :           1 :           error_at (lambda_specs.locations[ds_constexpr], "%<constexpr%> "
   12073                 :             :                     "lambda only available with %<-std=c++17%> or "
   12074                 :             :                     "%<-std=gnu++17%>");
   12075                 :             :       }
   12076                 :      528710 :     if (lambda_specs.locations[ds_consteval])
   12077                 :           6 :       return_type_specs.locations[ds_consteval]
   12078                 :           6 :         = lambda_specs.locations[ds_consteval];
   12079                 :      528710 :     if (LAMBDA_EXPR_STATIC_P (lambda_expr))
   12080                 :             :       {
   12081                 :          24 :         return_type_specs.storage_class = sc_static;
   12082                 :          24 :         return_type_specs.locations[ds_storage_class]
   12083                 :          24 :           = lambda_specs.locations[ds_storage_class];
   12084                 :             :       }
   12085                 :             : 
   12086                 :      528710 :     p = obstack_alloc (&declarator_obstack, 0);
   12087                 :             : 
   12088                 :      528710 :     declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none,
   12089                 :      528710 :                                      LAMBDA_EXPR_LOCATION (lambda_expr));
   12090                 :             : 
   12091                 :      528710 :     declarator = make_call_declarator (declarator, param_list, quals,
   12092                 :             :                                        VIRT_SPEC_UNSPECIFIED,
   12093                 :             :                                        REF_QUAL_NONE,
   12094                 :             :                                        tx_qual,
   12095                 :             :                                        exception_spec,
   12096                 :             :                                        return_type,
   12097                 :             :                                        trailing_requires_clause,
   12098                 :             :                                        std_attrs,
   12099                 :             :                                        UNKNOWN_LOCATION);
   12100                 :             : 
   12101                 :      528710 :     fco = grokmethod (&return_type_specs,
   12102                 :             :                       declarator,
   12103                 :             :                       chainon (gnu_attrs, lambda_specs.attributes));
   12104                 :      528710 :     if (fco != error_mark_node)
   12105                 :             :       {
   12106                 :      528697 :         DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
   12107                 :      528697 :         DECL_ARTIFICIAL (fco) = 1;
   12108                 :      528697 :         if (DECL_IOBJ_MEMBER_FUNCTION_P (fco))
   12109                 :             :           /* Give the object parameter a different name.  */
   12110                 :      528399 :           DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier;
   12111                 :      528697 :         DECL_SET_LAMBDA_FUNCTION (fco, true);
   12112                 :             :       }
   12113                 :      528710 :     if (template_param_list)
   12114                 :             :       {
   12115                 :       41404 :         fco = finish_member_template_decl (fco);
   12116                 :       41404 :         finish_template_decl (template_param_list);
   12117                 :       41404 :         --parser->num_template_parameter_lists;
   12118                 :             :       }
   12119                 :      487306 :     else if (parser->fully_implicit_function_template_p)
   12120                 :      182040 :       fco = finish_fully_implicit_template (parser, fco);
   12121                 :             : 
   12122                 :      528710 :     finish_member_declaration (fco);
   12123                 :      528710 :     record_lambda_scope_sig_discriminator (lambda_expr, fco);
   12124                 :             : 
   12125                 :      528710 :     obstack_free (&declarator_obstack, p);
   12126                 :             : 
   12127                 :      528710 :     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                 :             : 
   12138                 :             : static void
   12139                 :      528681 : cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
   12140                 :             : {
   12141                 :      528681 :   bool nested = (current_function_decl != NULL_TREE);
   12142                 :      528681 :   unsigned char local_variables_forbidden_p
   12143                 :             :     = parser->local_variables_forbidden_p;
   12144                 :      528681 :   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                 :      528681 :   cp_evaluated ev;
   12149                 :             : 
   12150                 :      528681 :   if (nested)
   12151                 :      527683 :     push_function_context ();
   12152                 :             :   else
   12153                 :             :     /* Still increment function_depth so that we don't GC in the
   12154                 :             :        middle of an expression.  */
   12155                 :         998 :     ++function_depth;
   12156                 :             : 
   12157                 :      528681 :   auto odsd = make_temp_override (parser->omp_declare_simd, NULL);
   12158                 :      528681 :   auto ord = make_temp_override (parser->oacc_routine, NULL);
   12159                 :      528681 :   auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false);
   12160                 :      528681 :   vec<tree> omp_privatization_save;
   12161                 :      528681 :   save_omp_privatization_clauses (omp_privatization_save);
   12162                 :             :   /* Clear this in case we're in the middle of a default argument.  */
   12163                 :      528681 :   parser->local_variables_forbidden_p = 0;
   12164                 :      528681 :   parser->in_function_body = true;
   12165                 :             : 
   12166                 :      528681 :   {
   12167                 :      528681 :     local_specialization_stack s (lss_copy);
   12168                 :      528681 :     tree fco = lambda_function (lambda_expr);
   12169                 :      528681 :     tree body = start_lambda_function (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                 :     1057362 :     cp_parser_function_body (parser, false);
   12175                 :             : 
   12176                 :      528681 :     finish_lambda_function (body);
   12177                 :      528681 :   }
   12178                 :             : 
   12179                 :      528681 :   restore_omp_privatization_clauses (omp_privatization_save);
   12180                 :      528681 :   parser->local_variables_forbidden_p = local_variables_forbidden_p;
   12181                 :      528681 :   parser->in_function_body = in_function_body;
   12182                 :      528681 :   if (nested)
   12183                 :      527683 :     pop_function_context();
   12184                 :             :   else
   12185                 :         998 :     --function_depth;
   12186                 :      528681 : }
   12187                 :             : 
   12188                 :             : /* Statements [gram.stmt.stmt]  */
   12189                 :             : 
   12190                 :             : /* Build and add a DEBUG_BEGIN_STMT statement with location LOC.  */
   12191                 :             : 
   12192                 :             : static void
   12193                 :   276598529 : add_debug_begin_stmt (location_t loc)
   12194                 :             : {
   12195                 :   276598529 :   if (!MAY_HAVE_DEBUG_MARKER_STMTS)
   12196                 :             :     return;
   12197                 :   266384474 :   if (DECL_DECLARED_CONCEPT_P (current_function_decl))
   12198                 :             :     /* A concept is never expanded normally.  */
   12199                 :             :     return;
   12200                 :             : 
   12201                 :   266384474 :   tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
   12202                 :   266384474 :   SET_EXPR_LOCATION (stmt, loc);
   12203                 :   266384474 :   add_stmt (stmt);
   12204                 :             : }
   12205                 :             : 
   12206                 :             : struct 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                 :             : 
   12216                 :             : static tree
   12217                 :        1419 : cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs)
   12218                 :             : {
   12219                 :        1419 :   if (!flag_openmp && !flag_openmp_simd)
   12220                 :           0 :     return attrs;
   12221                 :             : 
   12222                 :        1419 :   auto_vec<cp_omp_attribute_data, 16> vec;
   12223                 :        1419 :   int cnt = 0;
   12224                 :        1419 :   int tokens = 0;
   12225                 :        1419 :   bool bad = false;
   12226                 :        2856 :   for (tree *pa = &attrs; *pa; )
   12227                 :        1437 :     if (get_attribute_namespace (*pa) == omp_identifier
   12228                 :        1437 :         && is_attribute_p ("directive", get_attribute_name (*pa)))
   12229                 :             :       {
   12230                 :        1404 :         cnt++;
   12231                 :        2934 :         for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
   12232                 :             :           {
   12233                 :        1530 :             tree d = TREE_VALUE (a);
   12234                 :        1530 :             gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
   12235                 :        1530 :             cp_token *first = DEFPARSE_TOKENS (d)->first;
   12236                 :        1530 :             cp_token *last = DEFPARSE_TOKENS (d)->last;
   12237                 :        1530 :             if (parser->omp_attrs_forbidden_p)
   12238                 :             :               {
   12239                 :          39 :                 error_at (first->location,
   12240                 :             :                           "mixing OpenMP directives with attribute and pragma "
   12241                 :             :                           "syntax on the same statement");
   12242                 :          39 :                 parser->omp_attrs_forbidden_p = false;
   12243                 :          39 :                 bad = true;
   12244                 :             :               }
   12245                 :        1491 :             else if (TREE_PUBLIC (d))
   12246                 :             :               {
   12247                 :           9 :                 error_at (first->location,
   12248                 :             :                           "OpenMP %<omp::decl%> attribute on a statement");
   12249                 :           9 :                 bad = true;
   12250                 :             :               }
   12251                 :        1530 :             const char *directive[3] = {};
   12252                 :        4479 :             for (int i = 0; i < 3; i++)
   12253                 :             :               {
   12254                 :        3975 :                 tree id = NULL_TREE;
   12255                 :        3975 :                 if (first + i == last)
   12256                 :             :                   break;
   12257                 :        3495 :                 if (first[i].type == CPP_NAME)
   12258                 :        2678 :                   id = first[i].u.value;
   12259                 :         817 :                 else if (first[i].type == CPP_KEYWORD)
   12260                 :         271 :                   id = ridpointers[(int) first[i].keyword];
   12261                 :             :                 else
   12262                 :             :                   break;
   12263                 :        2949 :                 directive[i] = IDENTIFIER_POINTER (id);
   12264                 :             :               }
   12265                 :        1530 :             const c_omp_directive *dir = NULL;
   12266                 :        1530 :             if (directive[0])
   12267                 :        1530 :               dir = c_omp_categorize_directive (directive[0], directive[1],
   12268                 :             :                                                 directive[2]);
   12269                 :        1530 :             if (dir == NULL)
   12270                 :             :               {
   12271                 :           3 :                 error_at (first->location,
   12272                 :             :                           "unknown OpenMP directive name in %qs attribute "
   12273                 :             :                           "argument",
   12274                 :           3 :                           TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
   12275                 :           3 :                 continue;
   12276                 :             :               }
   12277                 :        1527 :             c_omp_directive_kind kind = dir->kind;
   12278                 :        1527 :             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                 :          24 :                 if (directive[1]
   12283                 :          12 :                     && (strcmp (directive[1], "depend") == 0
   12284                 :           6 :                         || strcmp (directive[1], "doacross") == 0))
   12285                 :             :                   kind = C_OMP_DIR_STANDALONE;
   12286                 :          18 :                 else if (first + 2 < last
   12287                 :          12 :                          && first[1].type == CPP_COMMA
   12288                 :          12 :                          && first[2].type == CPP_NAME
   12289                 :          30 :                          && (strcmp (IDENTIFIER_POINTER (first[2].u.value),
   12290                 :             :                                      "depend") == 0
   12291                 :           6 :                              || strcmp (IDENTIFIER_POINTER (first[2].u.value),
   12292                 :             :                                         "doacross") == 0))
   12293                 :             :                   kind = C_OMP_DIR_STANDALONE;
   12294                 :             :               }
   12295                 :        1503 :             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                 :         297 :                 for (int i = 1; first + i < last; i++)
   12300                 :         252 :                   if (first[i].type == CPP_OPEN_PAREN)
   12301                 :          54 :                     paren_depth++;
   12302                 :         198 :                   else if (first[i].type == CPP_CLOSE_PAREN)
   12303                 :          54 :                     paren_depth--;
   12304                 :         144 :                   else if (paren_depth == 0
   12305                 :          90 :                            && first + i + 2 < last
   12306                 :          90 :                            && first[i].type == CPP_NAME
   12307                 :          63 :                            && first[i + 1].type == CPP_OPEN_PAREN
   12308                 :          63 :                            && first[i + 2].type == CPP_NAME
   12309                 :          45 :                            && !strcmp (IDENTIFIER_POINTER (first[i].u.value),
   12310                 :             :                                        "at")
   12311                 :         171 :                            && !strcmp (IDENTIFIER_POINTER (first[i
   12312                 :             :                                                                  + 2].u.value),
   12313                 :             :                                        "execution"))
   12314                 :             :                     {
   12315                 :             :                       kind = C_OMP_DIR_STANDALONE;
   12316                 :             :                       break;
   12317                 :             :                     }
   12318                 :             :               }
   12319                 :        1527 :             cp_omp_attribute_data v = { DEFPARSE_TOKENS (d), dir, kind };
   12320                 :        1527 :             vec.safe_push (v);
   12321                 :        1527 :             if (flag_openmp || dir->simd)
   12322                 :        1527 :               tokens += (last - first) + 1;
   12323                 :             :           }
   12324                 :        1404 :         cp_omp_attribute_data v = {};
   12325                 :        1404 :         vec.safe_push (v);
   12326                 :        1404 :         *pa = TREE_CHAIN (*pa);
   12327                 :             :       }
   12328                 :             :     else
   12329                 :          33 :       pa = &TREE_CHAIN (*pa);
   12330                 :             : 
   12331                 :        1419 :   if (bad)
   12332                 :          48 :     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                 :        4203 :   FOR_EACH_VEC_ELT (vec, i, v)
   12340                 :        2832 :     if (v->tokens)
   12341                 :             :       {
   12342                 :        1476 :         if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
   12343                 :             :           construct_seen = v;
   12344                 :         687 :         else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
   12345                 :         219 :           standalone_seen = v;
   12346                 :             :       }
   12347                 :             :     else
   12348                 :             :       {
   12349                 :        1356 :         if (standalone_seen && !prev_standalone_seen)
   12350                 :             :           {
   12351                 :        2832 :             prev_standalone_seen = standalone_seen;
   12352                 :        2832 :             standalone_seen = nullptr;
   12353                 :             :           }
   12354                 :             :       }
   12355                 :             : 
   12356                 :        1371 :   if (cnt > 1 && construct_seen)
   12357                 :             :     {
   12358                 :           6 :       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                 :           6 :       return attrs;
   12363                 :             :     }
   12364                 :        1365 :   if (cnt > 1 && standalone_seen && prev_standalone_seen)
   12365                 :             :     {
   12366                 :           6 :       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                 :           6 :       return attrs;
   12371                 :             :     }
   12372                 :             : 
   12373                 :        1359 :   if (prev_standalone_seen)
   12374                 :             :     standalone_seen = prev_standalone_seen;
   12375                 :        1152 :   if (standalone_seen
   12376                 :        1359 :       && !cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   12377                 :             :     {
   12378                 :           6 :       error_at (standalone_seen->tokens->first->location,
   12379                 :             :                 "standalone OpenMP directives in %<omp::directive%> attribute"
   12380                 :             :                 " can only appear on an empty statement");
   12381                 :           6 :       return attrs;
   12382                 :             :     }
   12383                 :        1353 :   if (cnt && cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
   12384                 :             :     {
   12385                 :          12 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   12386                 :          12 :       enum pragma_kind kind = cp_parser_pragma_kind (token);
   12387                 :          12 :       if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
   12388                 :             :         {
   12389                 :          12 :           error_at (token->location,
   12390                 :             :                     "mixing OpenMP directives with attribute and pragma "
   12391                 :             :                     "syntax on the same statement");
   12392                 :          12 :           return attrs;
   12393                 :             :         }
   12394                 :             :     }
   12395                 :             : 
   12396                 :        1341 :   if (!tokens)
   12397                 :          48 :     return attrs;
   12398                 :        1293 :   tokens++;
   12399                 :        1293 :   cp_lexer *lexer = cp_lexer_alloc ();
   12400                 :        1293 :   lexer->debugging_p = parser->lexer->debugging_p;
   12401                 :        1293 :   vec_safe_reserve (lexer->buffer, tokens, true);
   12402                 :        4020 :   FOR_EACH_VEC_ELT (vec, i, v)
   12403                 :             :     {
   12404                 :        2727 :       if (!v->tokens)
   12405                 :        1293 :         continue;
   12406                 :        1434 :       if (!flag_openmp && !v->dir->simd)
   12407                 :           0 :         continue;
   12408                 :        1434 :       cp_token *first = v->tokens->first;
   12409                 :        1434 :       cp_token *last = v->tokens->last;
   12410                 :        1434 :       cp_token tok = {};
   12411                 :        1434 :       tok.type = CPP_PRAGMA;
   12412                 :        1434 :       tok.keyword = RID_MAX;
   12413                 :        1434 :       tok.u.value = build_int_cst (NULL, v->dir->id);
   12414                 :        1434 :       tok.location = first->location;
   12415                 :        1434 :       lexer->buffer->quick_push (tok);
   12416                 :       46728 :       while (++first < last)
   12417                 :       43860 :         lexer->buffer->quick_push (*first);
   12418                 :        1434 :       tok = {};
   12419                 :        1434 :       tok.type = CPP_PRAGMA_EOL;
   12420                 :        1434 :       tok.keyword = RID_MAX;
   12421                 :        1434 :       tok.location = last->location;
   12422                 :        1434 :       lexer->buffer->quick_push (tok);
   12423                 :             :     }
   12424                 :        1293 :   cp_token tok = {};
   12425                 :        1293 :   tok.type = CPP_EOF;
   12426                 :        1293 :   tok.keyword = RID_MAX;
   12427                 :        1293 :   tok.location = lexer->buffer->last ().location;
   12428                 :        1293 :   lexer->buffer->quick_push (tok);
   12429                 :        1293 :   lexer->next = parser->lexer;
   12430                 :        1293 :   lexer->next_token = lexer->buffer->address ();
   12431                 :        1293 :   lexer->last_token = lexer->next_token
   12432                 :        1293 :                       + lexer->buffer->length ()
   12433                 :        1293 :                       - 1;
   12434                 :        1293 :   lexer->in_omp_attribute_pragma = true;
   12435                 :        1293 :   parser->lexer = lexer;
   12436                 :             :   /* Move the current source position to that of the first token in the
   12437                 :             :      new lexer.  */
   12438                 :        1293 :   cp_lexer_set_source_position_from_token (lexer->next_token);
   12439                 :        1293 :   return attrs;
   12440                 :        1419 : }
   12441                 :             : 
   12442                 :             : /* True if and only if the name is one of the contract types.  */
   12443                 :             : 
   12444                 :             : static bool
   12445                 :    10898991 : contract_attribute_p (const_tree id)
   12446                 :             : {
   12447                 :    10898991 :   return is_attribute_p ("assert", id)
   12448                 :    10898679 :     || is_attribute_p ("pre", id)
   12449                 :    21796566 :     || is_attribute_p ("post", 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                 :             : 
   12455                 :             : static void
   12456                 :       16727 : cp_parser_handle_directive_omp_attributes (cp_parser *parser, tree *pattrs,
   12457                 :             :                                            cp_omp_declare_simd_data *data,
   12458                 :             :                                            bool start)
   12459                 :             : {
   12460                 :       16727 :   if (!flag_openmp && !flag_openmp_simd)
   12461                 :             :     return;
   12462                 :             : 
   12463                 :       16727 :   int cnt = 0;
   12464                 :       16727 :   bool bad = false;
   12465                 :       16727 :   bool variant_p = false;
   12466                 :       16727 :   location_t loc = UNKNOWN_LOCATION;
   12467                 :       44283 :   for (tree pa = *pattrs; pa; pa = TREE_CHAIN (pa))
   12468                 :       27556 :     if (get_attribute_namespace (pa) == omp_identifier
   12469                 :       27556 :         && is_attribute_p ("directive", get_attribute_name (pa)))
   12470                 :             :       {
   12471                 :         942 :         for (tree a = TREE_VALUE (pa); a; a = TREE_CHAIN (a))
   12472                 :             :           {
   12473                 :         477 :             tree d = TREE_VALUE (a);
   12474                 :         477 :             gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
   12475                 :         477 :             cp_token *first = DEFPARSE_TOKENS (d)->first;
   12476                 :         477 :             cp_token *last = DEFPARSE_TOKENS (d)->last;
   12477                 :         477 :             const char *directive[3] = {};
   12478                 :        1419 :             for (int i = 0; i < 3; i++)
   12479                 :             :               {
   12480                 :        1308 :                 tree id = NULL_TREE;
   12481                 :        1308 :                 if (first + i == last)
   12482                 :             :                   break;
   12483                 :        1137 :                 if (first[i].type == CPP_NAME)
   12484                 :         939 :                   id = first[i].u.value;
   12485                 :         198 :                 else if (first[i].type == CPP_KEYWORD)
   12486                 :           3 :                   id = ridpointers[(int) first[i].keyword];
   12487                 :             :                 else
   12488                 :             :                   break;
   12489                 :         942 :                 directive[i] = IDENTIFIER_POINTER (id);
   12490                 :             :               }
   12491                 :         477 :             const c_omp_directive *dir = NULL;
   12492                 :         477 :             if (directive[0])
   12493                 :         477 :               dir = c_omp_categorize_directive (directive[0], directive[1],
   12494                 :             :                                                 directive[2]);
   12495                 :         477 :             if (dir == NULL)
   12496                 :          27 :               continue;
   12497                 :         450 :             if (dir->id == PRAGMA_OMP_DECLARE
   12498                 :         327 :                 && (strcmp (directive[1], "simd") == 0
   12499                 :          54 :                     || strcmp (directive[1], "variant") == 0))
   12500                 :             :               {
   12501                 :         297 :                 if (cnt++ == 0)
   12502                 :             :                   {
   12503                 :         237 :                     variant_p = strcmp (directive[1], "variant") == 0;
   12504                 :         237 :                     loc = first->location;
   12505                 :             :                   }
   12506                 :         297 :                 if (start && parser->omp_declare_simd && !bad)
   12507                 :             :                   {
   12508                 :           6 :                     error_at (first->location,
   12509                 :             :                               "mixing OpenMP directives with attribute and "
   12510                 :             :                               "pragma syntax on the same declaration");
   12511                 :           6 :                     bad = true;
   12512                 :             :                   }
   12513                 :             :               }
   12514                 :             :           }
   12515                 :             :       }
   12516                 :             : 
   12517                 :       16727 :   if (bad)
   12518                 :             :     {
   12519                 :          12 :       for (tree *pa = pattrs; *pa; )
   12520                 :           6 :         if (get_attribute_namespace (*pa) == omp_identifier
   12521                 :           6 :             && is_attribute_p ("directive", get_attribute_name (*pa)))
   12522                 :           6 :           *pa = TREE_CHAIN (*pa);
   12523                 :             :         else
   12524                 :           0 :           pa = &TREE_CHAIN (*pa);
   12525                 :             :       return;
   12526                 :             :     }
   12527                 :       16721 :   if (cnt == 0)
   12528                 :             :     return;
   12529                 :             : 
   12530                 :         231 :   if (parser->omp_declare_simd == NULL)
   12531                 :             :     {
   12532                 :         213 :       data->error_seen = false;
   12533                 :         213 :       data->fndecl_seen = false;
   12534                 :         213 :       data->variant_p = variant_p;
   12535                 :         213 :       data->loc = loc;
   12536                 :         213 :       data->tokens = vNULL;
   12537                 :         213 :       data->attribs[0] = NULL;
   12538                 :         213 :       data->attribs[1] = NULL;
   12539                 :         213 :       parser->omp_declare_simd = data;
   12540                 :             :     }
   12541                 :         231 :   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                 :             : 
   12590                 :             : static void
   12591                 :   275068711 : cp_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                 :   275068711 :   tree statement, std_attrs = NULL_TREE;
   12596                 :   275068711 :   cp_token *token;
   12597                 :   275068711 :   location_t statement_location, attrs_loc;
   12598                 :   275068711 :   bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
   12599                 :   275068711 :   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                 :   275068711 :   bool in_compound_for_pragma = in_compound;
   12603                 :             : 
   12604                 :   276598529 :  restart:
   12605                 :   276598529 :   if (if_p != NULL)
   12606                 :    26000680 :     *if_p = false;
   12607                 :             :   /* There is no statement yet.  */
   12608                 :   276598529 :   statement = NULL_TREE;
   12609                 :             : 
   12610                 :   498102982 :   saved_token_sentinel saved_tokens (parser->lexer);
   12611                 :   276598529 :   token = cp_lexer_peek_token (parser->lexer);
   12612                 :   276598529 :   attrs_loc = token->location;
   12613                 :   276598529 :   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                 :           0 :     cp_parser_parse_tentatively (parser);
   12618                 :   276598529 :   std_attrs = cp_parser_std_attribute_spec_seq (parser);
   12619                 :   276598529 :   if (std_attrs)
   12620                 :      439331 :     attrs_loc = make_location (attrs_loc, attrs_loc, parser->lexer);
   12621                 :   276598529 :   if (c_dialect_objc ())
   12622                 :             :     {
   12623                 :           0 :       if (!cp_parser_parse_definitely (parser))
   12624                 :   276598529 :         std_attrs = NULL_TREE;
   12625                 :             :     }
   12626                 :   276598529 :   has_std_attrs = cp_lexer_peek_token (parser->lexer) != token;
   12627                 :             : 
   12628                 :             :   /* Peek at the next token.  */
   12629                 :   276598529 :   token = cp_lexer_peek_token (parser->lexer);
   12630                 :             : 
   12631                 :             :   /* If we have contracts, check that they're valid in this context.  */
   12632                 :   276598529 :   if (std_attrs != error_mark_node)
   12633                 :             :     {
   12634                 :   276598511 :       if (tree pre = lookup_attribute ("pre", std_attrs))
   12635                 :           0 :         error_at (EXPR_LOCATION (TREE_VALUE (pre)),
   12636                 :             :                   "preconditions cannot be statements");
   12637                 :   276598511 :       else if (tree post = lookup_attribute ("post", std_attrs))
   12638                 :           0 :         error_at (EXPR_LOCATION (TREE_VALUE (post)),
   12639                 :             :                   "postconditions cannot be statements");
   12640                 :             : 
   12641                 :             :     /* Check that assertions are null statements.  */
   12642                 :   276598511 :     if (cp_contract_assertion_p (std_attrs))
   12643                 :         155 :       if (token->type != CPP_SEMICOLON)
   12644                 :           0 :         error_at (token->location, "assertions must be followed by %<;%>");
   12645                 :             :     }
   12646                 :             : 
   12647                 :   276598529 :   bool omp_attrs_forbidden_p;
   12648                 :   276598529 :   omp_attrs_forbidden_p = parser->omp_attrs_forbidden_p;
   12649                 :             : 
   12650                 :   276598529 :   if (std_attrs && (flag_openmp || flag_openmp_simd))
   12651                 :             :     {
   12652                 :        1215 :       bool handle_omp_attribs = false;
   12653                 :        1215 :       if (token->type == CPP_KEYWORD)
   12654                 :         648 :         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                 :         567 :       else if (token->type == CPP_SEMICOLON
   12684                 :         123 :                || token->type == CPP_OPEN_BRACE
   12685                 :          81 :                || token->type == CPP_PRAGMA)
   12686                 :             :         handle_omp_attribs = true;
   12687                 :             :       if (handle_omp_attribs)
   12688                 :             :         {
   12689                 :        1011 :           std_attrs = cp_parser_handle_statement_omp_attributes (parser,
   12690                 :             :                                                                  std_attrs);
   12691                 :        1011 :           token = cp_lexer_peek_token (parser->lexer);
   12692                 :             :         }
   12693                 :             :     }
   12694                 :   276598529 :   parser->omp_attrs_forbidden_p = false;
   12695                 :             : 
   12696                 :             :   /* Remember the location of the first token in the statement.  */
   12697                 :   276598529 :   cp_token *statement_token = token;
   12698                 :   276598529 :   statement_location = token->location;
   12699                 :   276598529 :   add_debug_begin_stmt (statement_location);
   12700                 :             :   /* If this is a keyword, then that will often determine what kind of
   12701                 :             :      statement we have.  */
   12702                 :   276598529 :   if (token->type == CPP_KEYWORD)
   12703                 :             :     {
   12704                 :   174963347 :       enum rid keyword = token->keyword;
   12705                 :             : 
   12706                 :   174963347 :       switch (keyword)
   12707                 :             :         {
   12708                 :     1527709 :         case RID_CASE:
   12709                 :     1527709 :         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                 :     1527709 :           cp_parser_label_for_labeled_statement (parser, std_attrs);
   12714                 :     1527709 :           in_compound_for_pragma = false;
   12715                 :     1527709 :           in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
   12716                 :     1529818 :           goto restart;
   12717                 :             : 
   12718                 :    37456025 :         case RID_IF:
   12719                 :    37456025 :         case RID_SWITCH:
   12720                 :    37456025 :           std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12721                 :    37456025 :           statement = cp_parser_selection_statement (parser, if_p, chain);
   12722                 :    37456025 :           break;
   12723                 :             : 
   12724                 :    11688163 :         case RID_WHILE:
   12725                 :    11688163 :         case RID_DO:
   12726                 :    11688163 :         case RID_FOR:
   12727                 :    11688163 :           std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12728                 :    11688163 :           statement = cp_parser_iteration_statement (parser, if_p, false,
   12729                 :             :                                                      NULL_TREE, false);
   12730                 :    11688163 :           break;
   12731                 :             : 
   12732                 :    80670163 :         case RID_BREAK:
   12733                 :    80670163 :         case RID_CONTINUE:
   12734                 :    80670163 :         case RID_RETURN:
   12735                 :    80670163 :         case RID_CO_RETURN:
   12736                 :    80670163 :         case RID_GOTO:
   12737                 :    80670163 :           std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12738                 :    80670163 :           statement = cp_parser_jump_statement (parser);
   12739                 :    80670163 :           break;
   12740                 :             : 
   12741                 :             :           /* Objective-C++ exception-handling constructs.  */
   12742                 :           0 :         case RID_AT_TRY:
   12743                 :           0 :         case RID_AT_CATCH:
   12744                 :           0 :         case RID_AT_FINALLY:
   12745                 :           0 :         case RID_AT_SYNCHRONIZED:
   12746                 :           0 :         case RID_AT_THROW:
   12747                 :           0 :           std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12748                 :           0 :           statement = cp_parser_objc_statement (parser);
   12749                 :           0 :           break;
   12750                 :             : 
   12751                 :     1194399 :         case RID_TRY:
   12752                 :     1194399 :           std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12753                 :     1194399 :           statement = cp_parser_try_block (parser);
   12754                 :     1194399 :           break;
   12755                 :             : 
   12756                 :       40874 :         case RID_NAMESPACE:
   12757                 :             :           /* This must be a namespace alias definition.  */
   12758                 :       40874 :           if (has_std_attrs)
   12759                 :             :             {
   12760                 :             :               /* Attributes should be parsed as part of the
   12761                 :             :                  declaration, so let's un-parse them.  */
   12762                 :           9 :               saved_tokens.rollback();
   12763                 :           9 :               std_attrs = NULL_TREE;
   12764                 :             :             }
   12765                 :       40874 :           cp_parser_declaration_statement (parser);
   12766                 :    53605107 :           return;
   12767                 :             : 
   12768                 :         297 :         case RID_TRANSACTION_ATOMIC:
   12769                 :         297 :         case RID_TRANSACTION_RELAXED:
   12770                 :         297 :         case RID_SYNCHRONIZED:
   12771                 :         297 :         case RID_ATOMIC_NOEXCEPT:
   12772                 :         297 :         case RID_ATOMIC_CANCEL:
   12773                 :         297 :           std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12774                 :         297 :           statement = cp_parser_transaction (parser, token);
   12775                 :         297 :           break;
   12776                 :          16 :         case RID_TRANSACTION_CANCEL:
   12777                 :          16 :           std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12778                 :          16 :           statement = cp_parser_transaction_cancel (parser);
   12779                 :          16 :           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                 :    86640912 :       token = cp_lexer_peek_nth_token (parser->lexer, 2);
   12792                 :    86640912 :       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                 :        2017 :           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                 :        2017 :           if (in_compound
   12804                 :        2017 :               && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   12805                 :             :             {
   12806                 :          39 :               location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   12807                 :          39 :               if (cxx_dialect < cxx23)
   12808                 :          39 :                 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                 :          39 :               return;
   12812                 :             :             }
   12813                 :        1978 :           in_compound_for_pragma = false;
   12814                 :        1978 :           in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
   12815                 :        1978 :           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                 :      341942 :       std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12822                 :      341942 :       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                 :      137983 :      do_pragma:;
   12829                 :      137983 :       cp_lexer *lexer = parser->lexer;
   12830                 :      137983 :       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                 :      137983 :       if (in_compound_for_pragma)
   12837                 :             :         {
   12838                 :      132794 :           if (cp_parser_pragma (parser, pragma_compound, if_p)
   12839                 :      132794 :               && parser->omp_for_parse_state)
   12840                 :           8 :             check_omp_intervening_code (parser);
   12841                 :             :         }
   12842                 :        5189 :       else if (!cp_parser_pragma (parser, pragma_stmt, if_p))
   12843                 :             :         do_restart = true;
   12844                 :        5058 :       else if (parser->omp_for_parse_state)
   12845                 :           0 :         check_omp_intervening_code (parser);
   12846                 :      137983 :       if (parser->lexer != lexer
   12847                 :        1077 :           && lexer->in_omp_attribute_pragma
   12848                 :        1077 :           && (!in_omp_attribute_pragma || lexer->orphan_p))
   12849                 :             :         {
   12850                 :         954 :           if (saved_tokens.lexer == lexer)
   12851                 :             :             {
   12852                 :          12 :               if (saved_tokens.mode == STS_COMMIT)
   12853                 :          12 :                 cp_lexer_commit_tokens (lexer);
   12854                 :          24 :               gcc_assert (lexer->saved_tokens.length () == saved_tokens.len);
   12855                 :          12 :               saved_tokens.lexer = parser->lexer;
   12856                 :          12 :               saved_tokens.mode = STS_DONOTHING;
   12857                 :          24 :               saved_tokens.len = parser->lexer->saved_tokens.length ();
   12858                 :             :             }
   12859                 :         954 :           cp_lexer_destroy (lexer);
   12860                 :         954 :           lexer = parser->lexer;
   12861                 :             :         }
   12862                 :      137983 :       if (do_restart)
   12863                 :         131 :         goto restart;
   12864                 :      137852 :       if (parser->lexer == lexer
   12865                 :      137732 :           && lexer->in_omp_attribute_pragma
   12866                 :           9 :           && !in_omp_attribute_pragma)
   12867                 :           9 :         parser->lexer->orphan_p = true;
   12868                 :      137852 :       return;
   12869                 :             :     }
   12870                 :             :   else if (token->type == CPP_EOF)
   12871                 :             :     {
   12872                 :           8 :       cp_parser_error (parser, "expected statement");
   12873                 :           8 :       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                 :   131351004 :   if (!statement)
   12881                 :             :     {
   12882                 :   143538981 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   12883                 :             :         {
   12884                 :   138707714 :           if (has_std_attrs)
   12885                 :             :             /* Attributes should be parsed as part of the declaration,
   12886                 :             :                so let's un-parse them.  */
   12887                 :      206604 :             saved_tokens.rollback();
   12888                 :             : 
   12889                 :   138707714 :           parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p;
   12890                 :   138707714 :           cp_parser_parse_tentatively (parser);
   12891                 :             :           /* Try to parse the declaration-statement.  */
   12892                 :   138707714 :           cp_parser_declaration_statement (parser);
   12893                 :   138707710 :           parser->omp_attrs_forbidden_p = false;
   12894                 :             :           /* If that worked, we're done.  */
   12895                 :   138707710 :           if (cp_parser_parse_definitely (parser))
   12896                 :             :             return;
   12897                 :             :           /* It didn't work, restore the post-attribute position.  */
   12898                 :    85322250 :           if (has_std_attrs)
   12899                 :             :             {
   12900                 :      154926 :               cp_lexer_set_token_position (parser->lexer, statement_token);
   12901                 :      154926 :               if (flag_openmp || flag_openmp_simd)
   12902                 :             :                 {
   12903                 :             :                   size_t i = 1;
   12904                 :          84 :                   bool handle_omp_attribs = true;
   12905                 :         168 :                   while (cp_lexer_peek_nth_token (parser->lexer, i)->keyword
   12906                 :          84 :                          == RID_EXTENSION)
   12907                 :           3 :                     i++;
   12908                 :          81 :                   switch (cp_lexer_peek_nth_token (parser->lexer, 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                 :          69 :                   if (handle_omp_attribs)
   12927                 :             :                     {
   12928                 :          69 :                       parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p;
   12929                 :          69 :                       std_attrs
   12930                 :             :                         = cp_parser_handle_statement_omp_attributes
   12931                 :          69 :                                         (parser, std_attrs);
   12932                 :          69 :                       parser->omp_attrs_forbidden_p = false;
   12933                 :          69 :                       token = cp_lexer_peek_token (parser->lexer);
   12934                 :          69 :                       if (token->type == CPP_PRAGMA)
   12935                 :          48 :                         goto do_pragma;
   12936                 :             :                     }
   12937                 :             :                 }
   12938                 :             :             }
   12939                 :             :         }
   12940                 :             :       /* All preceding labels have been parsed at this point.  */
   12941                 :    90153469 :       if (loc_after_labels != NULL)
   12942                 :    20250298 :         *loc_after_labels = statement_location;
   12943                 :             : 
   12944                 :    90153469 :       std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
   12945                 :             : 
   12946                 :             :       /* Look for an expression-statement instead.  */
   12947                 :    90153469 :       statement = cp_parser_expression_statement (parser, in_statement_expr);
   12948                 :             : 
   12949                 :    90153449 :       std_attrs = process_stmt_assume_attribute (std_attrs, statement,
   12950                 :             :                                                  attrs_loc);
   12951                 :             : 
   12952                 :             :       /* Handle [[fallthrough]];.  */
   12953                 :    90153449 :       if (attribute_fallthrough_p (std_attrs))
   12954                 :             :         {
   12955                 :             :           /* The next token after the fallthrough attribute is ';'.  */
   12956                 :       11994 :           if (statement == NULL_TREE)
   12957                 :             :             {
   12958                 :             :               /* Turn [[fallthrough]]; into FALLTHROUGH ();.  */
   12959                 :       11994 :               statement = build_call_expr_internal_loc (statement_location,
   12960                 :             :                                                         IFN_FALLTHROUGH,
   12961                 :             :                                                         void_type_node, 0);
   12962                 :       11994 :               finish_expr_stmt (statement);
   12963                 :             :             }
   12964                 :             :           else
   12965                 :           0 :             warning_at (statement_location, OPT_Wattributes,
   12966                 :             :                         "%<fallthrough%> attribute not followed by %<;%>");
   12967                 :             :           std_attrs = NULL_TREE;
   12968                 :             :         }
   12969                 :             : 
   12970                 :             :       /* Handle [[assert: ...]];  */
   12971                 :    90153449 :       if (cp_contract_assertion_p (std_attrs))
   12972                 :             :         {
   12973                 :             :           /* Add the assertion as a statement in the current block.  */
   12974                 :         155 :           gcc_assert (!statement || statement == error_mark_node);
   12975                 :         155 :           emit_assertion (std_attrs);
   12976                 :         155 :           std_attrs = NULL_TREE;
   12977                 :             :         }
   12978                 :             :     }
   12979                 :             : 
   12980                 :             :   /* Set the line number for the statement.  */
   12981                 :   221504453 :   if (statement && STATEMENT_CODE_P (TREE_CODE (statement)))
   12982                 :   130336709 :     SET_EXPR_LOCATION (statement, statement_location);
   12983                 :             : 
   12984                 :             :   /* Allow "[[fallthrough]];" or "[[assume(cond)]];", but warn otherwise.  */
   12985                 :   221504453 :   if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs))
   12986                 :          84 :     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                 :             : 
   12992                 :             : tree
   12993                 :   516494803 : attr_chainon (tree attrs, tree attr)
   12994                 :             : {
   12995                 :   516494803 :   if (attrs == error_mark_node)
   12996                 :             :     return error_mark_node;
   12997                 :   516494785 :   if (attr == error_mark_node)
   12998                 :             :     return error_mark_node;
   12999                 :   516494716 :   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                 :             : 
   13019                 :             : static void
   13020                 :     1529726 : cp_parser_label_for_labeled_statement (cp_parser* parser, tree attributes)
   13021                 :             : {
   13022                 :     1529726 :   cp_token *token;
   13023                 :     1529726 :   tree label = NULL_TREE;
   13024                 :     1529726 :   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   13025                 :             : 
   13026                 :             :   /* The next token should be an identifier.  */
   13027                 :     1529726 :   token = cp_lexer_peek_token (parser->lexer);
   13028                 :     1529726 :   if (token->type != CPP_NAME
   13029                 :     1527709 :       && token->type != CPP_KEYWORD)
   13030                 :             :     {
   13031                 :           0 :       cp_parser_error (parser, "expected labeled-statement");
   13032                 :           0 :       return;
   13033                 :             :     }
   13034                 :             : 
   13035                 :             :   /* Remember whether this case or a user-defined label is allowed to fall
   13036                 :             :      through to.  */
   13037                 :     1529726 :   bool fallthrough_p = token->flags & PREV_FALLTHROUGH;
   13038                 :             : 
   13039                 :     1529726 :   parser->colon_corrects_to_scope_p = false;
   13040                 :     1529726 :   switch (token->keyword)
   13041                 :             :     {
   13042                 :     1417944 :     case RID_CASE:
   13043                 :     1417944 :       {
   13044                 :     1417944 :         tree expr, expr_hi;
   13045                 :     1417944 :         cp_token *ellipsis;
   13046                 :             : 
   13047                 :             :         /* Consume the `case' token.  */
   13048                 :     1417944 :         cp_lexer_consume_token (parser->lexer);
   13049                 :             :         /* Parse the constant-expression.  */
   13050                 :     1417944 :         expr = cp_parser_constant_expression (parser);
   13051                 :     1417944 :         if (check_for_bare_parameter_packs (expr))
   13052                 :           3 :           expr = error_mark_node;
   13053                 :             : 
   13054                 :     1417944 :         ellipsis = cp_lexer_peek_token (parser->lexer);
   13055                 :     1417944 :         if (ellipsis->type == CPP_ELLIPSIS)
   13056                 :             :           {
   13057                 :             :             /* Consume the `...' token.  */
   13058                 :         161 :             cp_lexer_consume_token (parser->lexer);
   13059                 :         161 :             expr_hi = cp_parser_constant_expression (parser);
   13060                 :         161 :             if (check_for_bare_parameter_packs (expr_hi))
   13061                 :           3 :               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                 :     1417944 :         if (parser->in_switch_statement_p)
   13070                 :             :           {
   13071                 :     1417938 :             tree l = finish_case_label (token->location, expr, expr_hi);
   13072                 :     1417938 :             if (l && TREE_CODE (l) == CASE_LABEL_EXPR)
   13073                 :             :               {
   13074                 :     1417738 :                 label = CASE_LABEL (l);
   13075                 :     1417738 :                 FALLTHROUGH_LABEL_P (label) = fallthrough_p;
   13076                 :             :               }
   13077                 :             :           }
   13078                 :             :         else
   13079                 :           6 :           error_at (token->location,
   13080                 :             :                     "case label %qE not within a switch statement",
   13081                 :             :                     expr);
   13082                 :             :       }
   13083                 :             :       break;
   13084                 :             : 
   13085                 :      109765 :     case RID_DEFAULT:
   13086                 :             :       /* Consume the `default' token.  */
   13087                 :      109765 :       cp_lexer_consume_token (parser->lexer);
   13088                 :             : 
   13089                 :      109765 :       if (parser->in_switch_statement_p)
   13090                 :             :         {
   13091                 :      109765 :           tree l = finish_case_label (token->location, NULL_TREE, NULL_TREE);
   13092                 :      109765 :           if (l && TREE_CODE (l) == CASE_LABEL_EXPR)
   13093                 :             :               {
   13094                 :      109733 :                 label = CASE_LABEL (l);
   13095                 :      109733 :                 FALLTHROUGH_LABEL_P (label) = fallthrough_p;
   13096                 :             :               }
   13097                 :             :         }
   13098                 :             :       else
   13099                 :           0 :         error_at (token->location, "case label not within a switch statement");
   13100                 :             :       break;
   13101                 :             : 
   13102                 :        2017 :     default:
   13103                 :             :       /* Anything else must be an ordinary label.  */
   13104                 :        2017 :       label = finish_label_stmt (cp_parser_identifier (parser));
   13105                 :        2017 :       if (label && TREE_CODE (label) == LABEL_DECL)
   13106                 :        2009 :         FALLTHROUGH_LABEL_P (label) = fallthrough_p;
   13107                 :             :       break;
   13108                 :             :     }
   13109                 :             : 
   13110                 :             :   /* Require the `:' token.  */
   13111                 :     1529726 :   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                 :     1529726 :   if (label != NULL_TREE
   13120                 :     1529726 :       && cp_next_tokens_can_be_gnu_attribute_p (parser))
   13121                 :             :     {
   13122                 :          62 :       tree attrs;
   13123                 :          62 :       cp_parser_parse_tentatively (parser);
   13124                 :          62 :       attrs = cp_parser_gnu_attributes_opt (parser);
   13125                 :          62 :       if (attrs == NULL_TREE
   13126                 :             :           /* And fallthrough always binds to the expression-statement.  */
   13127                 :          62 :           || attribute_fallthrough_p (attrs)
   13128                 :         108 :           || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   13129                 :          24 :         cp_parser_abort_tentative_parse (parser);
   13130                 :          38 :       else if (!cp_parser_parse_definitely (parser))
   13131                 :             :         ;
   13132                 :             :       else
   13133                 :          38 :         attributes = attr_chainon (attributes, attrs);
   13134                 :             :     }
   13135                 :             : 
   13136                 :     1529726 :   if (attributes != NULL_TREE)
   13137                 :          73 :     cplus_decl_attributes (&label, attributes, 0);
   13138                 :             : 
   13139                 :     1529726 :   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                 :             : 
   13152                 :             : static tree
   13153                 :    92018611 : cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
   13154                 :             : {
   13155                 :    92018611 :   tree statement = NULL_TREE;
   13156                 :    92018611 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   13157                 :    92018611 :   location_t loc = token->location;
   13158                 :             : 
   13159                 :             :   /* There might be attribute fallthrough.  */
   13160                 :    92018611 :   tree attr = cp_parser_gnu_attributes_opt (parser);
   13161                 :             : 
   13162                 :             :   /* If the next token is a ';', then there is no expression
   13163                 :             :      statement.  */
   13164                 :    92018611 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   13165                 :             :     {
   13166                 :    85624416 :       statement = cp_parser_expression (parser);
   13167                 :    85624400 :       if (statement == error_mark_node
   13168                 :    85624400 :           && !cp_parser_uncommitted_to_tentative_parse_p (parser))
   13169                 :             :         {
   13170                 :             :           /* If we ran into a problem, make sure we complained.  */
   13171                 :       11364 :           gcc_assert (seen_error ());
   13172                 :             : 
   13173                 :       11364 :           cp_parser_skip_to_end_of_block_or_statement (parser);
   13174                 :       11364 :           return error_mark_node;
   13175                 :             :         }
   13176                 :             :     }
   13177                 :             : 
   13178                 :    92007231 :   attr = process_stmt_assume_attribute (attr, statement, loc);
   13179                 :             : 
   13180                 :             :   /* Handle [[fallthrough]];.  */
   13181                 :    92007231 :   if (attribute_fallthrough_p (attr))
   13182                 :             :     {
   13183                 :             :       /* The next token after the fallthrough attribute is ';'.  */
   13184                 :         239 :       if (statement == NULL_TREE)
   13185                 :             :         /* Turn [[fallthrough]]; into FALLTHROUGH ();.  */
   13186                 :         235 :         statement = build_call_expr_internal_loc (loc, IFN_FALLTHROUGH,
   13187                 :             :                                                   void_type_node, 0);
   13188                 :             :       else
   13189                 :           4 :         warning_at (loc, OPT_Wattributes,
   13190                 :             :                     "%<fallthrough%> attribute not followed by %<;%>");
   13191                 :             :       attr = NULL_TREE;
   13192                 :             :     }
   13193                 :             : 
   13194                 :             :   /* Allow "[[fallthrough]];", but warn otherwise.  */
   13195                 :    92006992 :   if (attr != NULL_TREE && any_nonignored_attribute_p (attr))
   13196                 :          12 :     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                 :    92007231 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
   13201                 :    92007231 :       && !cp_parser_uncommitted_to_tentative_parse_p (parser))
   13202                 :             :     {
   13203                 :          93 :       if (TREE_CODE (statement) == SCOPE_REF)
   13204                 :          18 :         error_at (token->location, "need %<typename%> before %qE because "
   13205                 :             :                   "%qT is a dependent scope",
   13206                 :          18 :                   statement, TREE_OPERAND (statement, 0));
   13207                 :          75 :       else if (is_overloaded_fn (statement)
   13208                 :          83 :                && DECL_CONSTRUCTOR_P (get_first_fn (statement)))
   13209                 :             :         {
   13210                 :             :           /* A::A a; */
   13211                 :           4 :           tree fn = get_first_fn (statement);
   13212                 :           4 :           error_at (token->location,
   13213                 :             :                     "%<%T::%D%> names the constructor, not the type",
   13214                 :           4 :                     DECL_CONTEXT (fn), DECL_NAME (fn));
   13215                 :             :         }
   13216                 :             :     }
   13217                 :             : 
   13218                 :             :   /* Consume the final `;'.  */
   13219                 :    92007231 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   13220                 :             : 
   13221                 :    92007231 :   if (in_statement_expr
   13222                 :    92007231 :       && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   13223                 :             :     /* This is the final expression statement of a statement
   13224                 :             :        expression.  */
   13225                 :       15932 :     statement = finish_stmt_expr_expr (statement, in_statement_expr);
   13226                 :    91991299 :   else if (statement)
   13227                 :    85597359 :     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                 :             : 
   13252                 :             : static tree
   13253                 :   119350854 : cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
   13254                 :             :                               int bcs_flags, bool function_body)
   13255                 :             : {
   13256                 :   119350854 :   tree compound_stmt;
   13257                 :   119350854 :   matching_braces braces;
   13258                 :             : 
   13259                 :             :   /* Consume the `{'.  */
   13260                 :   119350854 :   if (!braces.require_open (parser))
   13261                 :          60 :     return error_mark_node;
   13262                 :   119350794 :   if (DECL_DECLARED_CONSTEXPR_P (current_function_decl)
   13263                 :   119350794 :       && !function_body && cxx_dialect < cxx14)
   13264                 :          33 :     pedwarn (input_location, OPT_Wpedantic,
   13265                 :             :              "compound-statement in %<constexpr%> function");
   13266                 :             :   /* Begin the compound-statement.  */
   13267                 :   119350794 :   compound_stmt = begin_compound_stmt (bcs_flags);
   13268                 :             :   /* If the next keyword is `__label__' we have a label declaration.  */
   13269                 :   238701704 :   while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
   13270                 :         116 :     cp_parser_label_declaration (parser);
   13271                 :             :   /* Parse an (optional) statement-seq.  */
   13272                 :   119350794 :   cp_parser_statement_seq_opt (parser, in_statement_expr);
   13273                 :             : 
   13274                 :             :   /* Consume the `}'.  */
   13275                 :   119350769 :   braces.require_close (parser);
   13276                 :             : 
   13277                 :             :   /* Finish the compound-statement.  */
   13278                 :   119350769 :   finish_compound_stmt (compound_stmt);
   13279                 :             : 
   13280                 :   119350769 :   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                 :             : 
   13291                 :             : static void
   13292                 :         931 : check_omp_intervening_code (cp_parser *parser)
   13293                 :             : {
   13294                 :         931 :   struct omp_for_parse_data *omp_for_parse_state
   13295                 :             :     = parser->omp_for_parse_state;
   13296                 :         931 :   gcc_assert (omp_for_parse_state);
   13297                 :             : 
   13298                 :         931 :   if (!omp_for_parse_state->in_intervening_code)
   13299                 :             :     return;
   13300                 :         825 :   omp_for_parse_state->saw_intervening_code = true;
   13301                 :             : 
   13302                 :             :   /* Only diagnose errors related to perfect nesting once.  */
   13303                 :         825 :   if (!omp_for_parse_state->perfect_nesting_fail)
   13304                 :             :     {
   13305                 :         763 :       if (omp_for_parse_state->code == OACC_LOOP)
   13306                 :             :         {
   13307                 :           0 :           error_at (omp_for_parse_state->for_loc,
   13308                 :             :                     "inner loops must be perfectly nested in "
   13309                 :             :                     "%<#pragma acc loop%>");
   13310                 :           0 :           omp_for_parse_state->perfect_nesting_fail = true;
   13311                 :             :         }
   13312                 :         763 :       else if (omp_for_parse_state->ordered)
   13313                 :             :         {
   13314                 :          49 :           error_at (omp_for_parse_state->for_loc,
   13315                 :             :                     "inner loops must be perfectly nested with "
   13316                 :             :                     "%<ordered%> clause");
   13317                 :          49 :           omp_for_parse_state->perfect_nesting_fail = true;
   13318                 :             :         }
   13319                 :         714 :       else if (omp_for_parse_state->inscan)
   13320                 :             :         {
   13321                 :          11 :           error_at (omp_for_parse_state->for_loc,
   13322                 :             :                     "inner loops must be perfectly nested with "
   13323                 :             :                     "%<reduction%> %<inscan%> clause");
   13324                 :          11 :           omp_for_parse_state->perfect_nesting_fail = true;
   13325                 :             :         }
   13326                 :             :       /* TODO: Also reject loops with TILE directive.  */
   13327                 :         763 :       if (omp_for_parse_state->perfect_nesting_fail)
   13328                 :          60 :         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                 :             : 
   13338                 :             : static void
   13339                 :   123417268 : cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
   13340                 :             : {
   13341                 :   123417268 :   struct omp_for_parse_data *omp_for_parse_state
   13342                 :             :     = parser->omp_for_parse_state;
   13343                 :   123417268 :   bool in_omp_loop_block
   13344                 :   123417268 :     = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
   13345                 :             : 
   13346                 :             :   /* Scan statements until there aren't any more.  */
   13347                 :   358925992 :   while (true)
   13348                 :             :     {
   13349                 :   358925992 :       cp_token *token = cp_lexer_peek_token (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                 :   358925992 :       if (token->type == CPP_CLOSE_BRACE
   13355                 :             :           || token->type == CPP_EOF
   13356                 :             :           || token->type == CPP_PRAGMA_EOL
   13357                 :   235508753 :           || (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                 :   235508753 :       else if (token->type == CPP_KEYWORD && token->keyword == RID_ELSE)
   13363                 :             :         {
   13364                 :           8 :           if (parser->in_statement & IN_IF_STMT)
   13365                 :             :             break;
   13366                 :             :           else
   13367                 :             :             {
   13368                 :           4 :               token = cp_lexer_consume_token (parser->lexer);
   13369                 :           4 :               error_at (token->location, "%<else%> without a previous %<if%>");
   13370                 :             :             }
   13371                 :             :         }
   13372                 :             : 
   13373                 :             :       /* Handle special cases for OMP FOR canonical loop syntax.  */
   13374                 :   235508745 :       else if (in_omp_loop_block)
   13375                 :             :         {
   13376                 :        1399 :           bool want_nested_loop = omp_for_parse_state->want_nested_loop;
   13377                 :        1399 :           if (want_nested_loop
   13378                 :        1050 :               && token->type == CPP_KEYWORD && token->keyword == RID_FOR)
   13379                 :             :             {
   13380                 :             :               /* Found the nested loop.  */
   13381                 :         382 :               omp_for_parse_state->depth++;
   13382                 :         382 :               add_stmt (cp_parser_omp_loop_nest (parser, NULL));
   13383                 :         382 :               omp_for_parse_state->depth--;
   13384                 :             :             }
   13385                 :        1017 :           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                 :          22 :               cp_lexer_consume_token (parser->lexer);
   13393                 :             :             }
   13394                 :         995 :           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                 :          71 :               cp_parser_statement (parser, in_statement_expr, true, NULL);
   13399                 :          71 :               if (omp_for_parse_state->want_nested_loop)
   13400                 :          31 :                 check_omp_intervening_code (parser);
   13401                 :             :             }
   13402                 :             :           else
   13403                 :             :             {
   13404                 :             :               /* This must be intervening code.  */
   13405                 :         924 :               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                 :         924 :               if (token->type != CPP_PRAGMA)
   13410                 :         892 :                 check_omp_intervening_code (parser);
   13411                 :         924 :               cp_parser_statement (parser, in_statement_expr, true, NULL);
   13412                 :         924 :               omp_for_parse_state->want_nested_loop = want_nested_loop;
   13413                 :             :             }
   13414                 :        1399 :           continue;
   13415                 :        1399 :         }
   13416                 :             : 
   13417                 :             :       /* Parse the statement.  */
   13418                 :   235507350 :       cp_parser_statement (parser, in_statement_expr, true, NULL);
   13419                 :             :     }
   13420                 :   123417243 : }
   13421                 :             : 
   13422                 :             : /* Return true if this is the C++20 version of range-based-for with
   13423                 :             :    init-statement.  */
   13424                 :             : 
   13425                 :             : static bool
   13426                 :     5402446 : cp_parser_range_based_for_with_init_p (cp_parser *parser)
   13427                 :             : {
   13428                 :     5402446 :   bool r = false;
   13429                 :             : 
   13430                 :             :   /* Save tokens so that we can put them back.  */
   13431                 :     5402446 :   cp_lexer_save_tokens (parser->lexer);
   13432                 :             : 
   13433                 :             :   /* There has to be an unnested ; followed by an unnested :.  */
   13434                 :     5402446 :   if (cp_parser_skip_to_closing_parenthesis_1 (parser,
   13435                 :             :                                                /*recovering=*/false,
   13436                 :             :                                                CPP_SEMICOLON,
   13437                 :             :                                                /*consume_paren=*/false) != -1)
   13438                 :      189013 :     goto out;
   13439                 :             : 
   13440                 :             :   /* We found the semicolon, eat it now.  */
   13441                 :     5213433 :   cp_lexer_consume_token (parser->lexer);
   13442                 :             : 
   13443                 :             :   /* Now look for ':' that is not nested in () or {}.  */
   13444                 :     5213433 :   r = (cp_parser_skip_to_closing_parenthesis_1 (parser,
   13445                 :             :                                                 /*recovering=*/false,
   13446                 :             :                                                 CPP_COLON,
   13447                 :             :                                                 /*consume_paren=*/false) == -1);
   13448                 :             : 
   13449                 :     5402446 : out:
   13450                 :             :   /* Roll back the tokens we skipped.  */
   13451                 :     5402446 :   cp_lexer_rollback_tokens (parser->lexer);
   13452                 :             : 
   13453                 :     5402446 :   return r;
   13454                 :             : }
   13455                 :             : 
   13456                 :             : /* Return true if we're looking at (init; cond), false otherwise.  */
   13457                 :             : 
   13458                 :             : static bool
   13459                 :    37452081 : cp_parser_init_statement_p (cp_parser *parser)
   13460                 :             : {
   13461                 :             :   /* Save tokens so that we can put them back.  */
   13462                 :    37452081 :   cp_lexer_save_tokens (parser->lexer);
   13463                 :             : 
   13464                 :             :   /* Look for ';' that is not nested in () or {}.  */
   13465                 :    37452081 :   int ret = cp_parser_skip_to_closing_parenthesis_1 (parser,
   13466                 :             :                                                      /*recovering=*/false,
   13467                 :             :                                                      CPP_SEMICOLON,
   13468                 :             :                                                      /*consume_paren=*/false);
   13469                 :             : 
   13470                 :             :   /* Roll back the tokens we skipped.  */
   13471                 :    37452081 :   cp_lexer_rollback_tokens (parser->lexer);
   13472                 :             : 
   13473                 :    37452081 :   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                 :             : 
   13493                 :             : static tree
   13494                 :    37456025 : cp_parser_selection_statement (cp_parser* parser, bool *if_p,
   13495                 :             :                                vec<tree> *chain)
   13496                 :             : {
   13497                 :    37456025 :   cp_token *token;
   13498                 :    37456025 :   enum rid keyword;
   13499                 :    37456025 :   token_indent_info guard_tinfo;
   13500                 :             : 
   13501                 :    37456025 :   if (if_p != NULL)
   13502                 :     2639482 :     *if_p = false;
   13503                 :             : 
   13504                 :             :   /* Peek at the next token.  */
   13505                 :    37456025 :   token = cp_parser_require (parser, CPP_KEYWORD, RT_SELECT);
   13506                 :    37456025 :   guard_tinfo = get_token_indent_info (token);
   13507                 :             : 
   13508                 :             :   /* See what kind of keyword it is.  */
   13509                 :    37456025 :   keyword = token->keyword;
   13510                 :    37456025 :   switch (keyword)
   13511                 :             :     {
   13512                 :    37456025 :     case RID_IF:
   13513                 :    37456025 :     case RID_SWITCH:
   13514                 :    37456025 :       {
   13515                 :    37456025 :         tree statement;
   13516                 :    37456025 :         tree condition;
   13517                 :             : 
   13518                 :    37456025 :         bool cx = false;
   13519                 :    37456025 :         if (keyword == RID_IF
   13520                 :    37456025 :             && cp_lexer_next_token_is_keyword (parser->lexer,
   13521                 :             :                                                RID_CONSTEXPR))
   13522                 :             :           {
   13523                 :     3216558 :             cx = true;
   13524                 :     3216558 :             cp_token *tok = cp_lexer_consume_token (parser->lexer);
   13525                 :     3216558 :             if (cxx_dialect < cxx17)
   13526                 :        6578 :               pedwarn (tok->location, OPT_Wc__17_extensions,
   13527                 :             :                        "%<if constexpr%> only available with "
   13528                 :             :                        "%<-std=c++17%> or %<-std=gnu++17%>");
   13529                 :             :           }
   13530                 :    37456025 :         int ce = 0;
   13531                 :    37456025 :         if (keyword == RID_IF && !cx)
   13532                 :             :           {
   13533                 :    34071226 :             if (cp_lexer_next_token_is_keyword (parser->lexer,
   13534                 :             :                                                 RID_CONSTEVAL))
   13535                 :             :               ce = 1;
   13536                 :    34068561 :             else if (cp_lexer_next_token_is (parser->lexer, CPP_NOT)
   13537                 :    34068561 :                      && cp_lexer_nth_token_is_keyword (parser->lexer, 2,
   13538                 :             :                                                        RID_CONSTEVAL))
   13539                 :             :               {
   13540                 :        1271 :                 ce = -1;
   13541                 :        1271 :                 cp_lexer_consume_token (parser->lexer);
   13542                 :             :               }
   13543                 :             :           }
   13544                 :        1271 :         if (ce)
   13545                 :             :           {
   13546                 :        3936 :             cp_token *tok = cp_lexer_consume_token (parser->lexer);
   13547                 :        3936 :             if (cxx_dialect < cxx23)
   13548                 :          48 :               pedwarn (tok->location, OPT_Wc__23_extensions,
   13549                 :             :                        "%<if consteval%> only available with "
   13550                 :             :                        "%<-std=c++2b%> or %<-std=gnu++2b%>");
   13551                 :             : 
   13552                 :        3936 :             bool save_in_consteval_if_p = in_consteval_if_p;
   13553                 :        3936 :             statement = begin_if_stmt ();
   13554                 :        3936 :             IF_STMT_CONSTEVAL_P (statement) = true;
   13555                 :        3936 :             condition = finish_if_stmt_cond (boolean_false_node, statement);
   13556                 :             : 
   13557                 :        3936 :             gcc_rich_location richloc (tok->location);
   13558                 :        3936 :             bool non_compound_stmt_p = false;
   13559                 :        3936 :             if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
   13560                 :             :               {
   13561                 :           3 :                 non_compound_stmt_p = true;
   13562                 :           3 :                 richloc.add_fixit_insert_after (tok->location, "{");
   13563                 :             :               }
   13564                 :             : 
   13565                 :        3936 :             in_consteval_if_p |= ce > 0;
   13566                 :        3936 :             cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);
   13567                 :             : 
   13568                 :        3936 :             if (non_compound_stmt_p)
   13569                 :             :               {
   13570                 :           3 :                 location_t before_loc
   13571                 :           3 :                   = cp_lexer_peek_token (parser->lexer)->location;
   13572                 :           3 :                 richloc.add_fixit_insert_before (before_loc, "}");
   13573                 :           3 :                 error_at (&richloc,
   13574                 :             :                           "%<if consteval%> requires compound statement");
   13575                 :           3 :                 non_compound_stmt_p = false;
   13576                 :             :               }
   13577                 :             : 
   13578                 :        3936 :             finish_then_clause (statement);
   13579                 :             : 
   13580                 :             :             /* If the next token is `else', parse the else-clause.  */
   13581                 :        3936 :             if (cp_lexer_next_token_is_keyword (parser->lexer,
   13582                 :             :                                                 RID_ELSE))
   13583                 :             :               {
   13584                 :        2659 :                 cp_token *else_tok = cp_lexer_peek_token (parser->lexer);
   13585                 :        2659 :                 gcc_rich_location else_richloc (else_tok->location);
   13586                 :        2659 :                 guard_tinfo = get_token_indent_info (else_tok);
   13587                 :             :                 /* Consume the `else' keyword.  */
   13588                 :        2659 :                 cp_lexer_consume_token (parser->lexer);
   13589                 :             : 
   13590                 :        2659 :                 begin_else_clause (statement);
   13591                 :             : 
   13592                 :        2659 :                 if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
   13593                 :             :                   {
   13594                 :           3 :                     non_compound_stmt_p = true;
   13595                 :           3 :                     else_richloc.add_fixit_insert_after (else_tok->location,
   13596                 :             :                                                          "{");
   13597                 :             :                   }
   13598                 :             : 
   13599                 :        2659 :                 in_consteval_if_p = save_in_consteval_if_p | (ce < 0);
   13600                 :        2659 :                 cp_parser_implicitly_scoped_statement (parser, NULL,
   13601                 :             :                                                        guard_tinfo);
   13602                 :             : 
   13603                 :        2659 :                 if (non_compound_stmt_p)
   13604                 :             :                   {
   13605                 :           3 :                     location_t before_loc
   13606                 :           3 :                       = cp_lexer_peek_token (parser->lexer)->location;
   13607                 :           3 :                     else_richloc.add_fixit_insert_before (before_loc, "}");
   13608                 :           3 :                     error_at (&else_richloc,
   13609                 :             :                               "%<if consteval%> requires compound statement");
   13610                 :             :                   }
   13611                 :             : 
   13612                 :        2659 :                 finish_else_clause (statement);
   13613                 :        2659 :               }
   13614                 :             : 
   13615                 :        3936 :             in_consteval_if_p = save_in_consteval_if_p;
   13616                 :        3936 :             if (ce < 0)
   13617                 :             :               {
   13618                 :        1271 :                 std::swap (THEN_CLAUSE (statement), ELSE_CLAUSE (statement));
   13619                 :        1271 :                 if (THEN_CLAUSE (statement) == NULL_TREE)
   13620                 :        1260 :                   THEN_CLAUSE (statement) = build_empty_stmt (tok->location);
   13621                 :             :               }
   13622                 :             : 
   13623                 :        3936 :             finish_if_stmt (statement);
   13624                 :        3936 :             return statement;
   13625                 :        3936 :           }
   13626                 :             : 
   13627                 :             :         /* Look for the `('.  */
   13628                 :    37452089 :         matching_parens parens;
   13629                 :    37452089 :         if (!parens.require_open (parser))
   13630                 :             :           {
   13631                 :           8 :             cp_parser_skip_to_end_of_statement (parser);
   13632                 :           8 :             return error_mark_node;
   13633                 :             :           }
   13634                 :             : 
   13635                 :             :         /* Begin the selection-statement.  */
   13636                 :    37452081 :         if (keyword == RID_IF)
   13637                 :             :           {
   13638                 :    37283840 :             statement = begin_if_stmt ();
   13639                 :    37283840 :             IF_STMT_CONSTEXPR_P (statement) = cx;
   13640                 :             :           }
   13641                 :             :         else
   13642                 :      168241 :           statement = begin_switch_stmt ();
   13643                 :             : 
   13644                 :             :         /* Parse the optional init-statement.  */
   13645                 :    37452081 :         if (cp_parser_init_statement_p (parser))
   13646                 :             :           {
   13647                 :       29318 :             tree decl;
   13648                 :       29318 :             if (cxx_dialect < cxx17)
   13649                 :           3 :               pedwarn (cp_lexer_peek_token (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                 :       29318 :             if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   13654                 :             :               /* A non-empty init-statement can have arbitrary side
   13655                 :             :                  effects.  */
   13656                 :       29316 :               vec_free (chain);
   13657                 :       29318 :             cp_parser_init_statement (parser, &decl);
   13658                 :             :           }
   13659                 :             : 
   13660                 :             :         /* Parse the condition.  */
   13661                 :    37452081 :         condition = cp_parser_condition (parser);
   13662                 :             :         /* Look for the `)'.  */
   13663                 :    37452081 :         if (!parens.require_close (parser))
   13664                 :          12 :           cp_parser_skip_to_closing_parenthesis (parser, true, false,
   13665                 :             :                                                  /*consume_paren=*/true);
   13666                 :             : 
   13667                 :    37452081 :         if (keyword == RID_IF)
   13668                 :             :           {
   13669                 :    37283840 :             bool nested_if;
   13670                 :    37283840 :             unsigned char in_statement;
   13671                 :             : 
   13672                 :             :             /* Add the condition.  */
   13673                 :    37283840 :             condition = finish_if_stmt_cond (condition, statement);
   13674                 :             : 
   13675                 :    37283840 :             if (warn_duplicated_cond)
   13676                 :         324 :               warn_duplicated_cond_add_or_warn (token->location, condition,
   13677                 :             :                                                 &chain);
   13678                 :             : 
   13679                 :             :             /* Parse the then-clause.  */
   13680                 :    37283840 :             in_statement = parser->in_statement;
   13681                 :    37283840 :             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                 :    37283840 :             bool was_discarded = in_discarded_stmt;
   13686                 :     3216558 :             bool discard_then = (cx && !processing_template_decl
   13687                 :    37315348 :                                  && integer_zerop (condition));
   13688                 :         107 :             if (discard_then)
   13689                 :             :               {
   13690                 :         107 :                 in_discarded_stmt = true;
   13691                 :         107 :                 ++c_inhibit_evaluation_warnings;
   13692                 :             :               }
   13693                 :             : 
   13694                 :    37283840 :             cp_parser_implicitly_scoped_statement (parser, &nested_if,
   13695                 :             :                                                    guard_tinfo);
   13696                 :             : 
   13697                 :    37283840 :             parser->in_statement = in_statement;
   13698                 :             : 
   13699                 :    37283840 :             finish_then_clause (statement);
   13700                 :             : 
   13701                 :    37283840 :             if (discard_then)
   13702                 :             :               {
   13703                 :         107 :                 THEN_CLAUSE (statement) = NULL_TREE;
   13704                 :         107 :                 in_discarded_stmt = was_discarded;
   13705                 :         107 :                 --c_inhibit_evaluation_warnings;
   13706                 :             :               }
   13707                 :             : 
   13708                 :             :             /* If the next token is `else', parse the else-clause.  */
   13709                 :    37283840 :             if (cp_lexer_next_token_is_keyword (parser->lexer,
   13710                 :             :                                                 RID_ELSE))
   13711                 :             :               {
   13712                 :     2235516 :                 bool discard_else = (cx && !processing_template_decl
   13713                 :    12081882 :                                      && integer_nonzerop (condition));
   13714                 :       31346 :                 if (discard_else)
   13715                 :             :                   {
   13716                 :       31346 :                     in_discarded_stmt = true;
   13717                 :       31346 :                     ++c_inhibit_evaluation_warnings;
   13718                 :             :                   }
   13719                 :             : 
   13720                 :    12050464 :                 guard_tinfo
   13721                 :    12050464 :                   = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
   13722                 :             :                 /* Consume the `else' keyword.  */
   13723                 :    12050464 :                 cp_lexer_consume_token (parser->lexer);
   13724                 :    12050464 :                 if (warn_duplicated_cond)
   13725                 :             :                   {
   13726                 :         214 :                     if (cp_lexer_next_token_is_keyword (parser->lexer,
   13727                 :             :                                                         RID_IF)
   13728                 :         214 :                         && 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                 :         112 :                         chain = new vec<tree> ();
   13734                 :         112 :                         if (!CONSTANT_CLASS_P (condition)
   13735                 :         112 :                             && !TREE_SIDE_EFFECTS (condition))
   13736                 :             :                         {
   13737                 :             :                           /* Wrap it in a NOP_EXPR so that we can set the
   13738                 :             :                              location of the condition.  */
   13739                 :          88 :                           tree e = build1 (NOP_EXPR, TREE_TYPE (condition),
   13740                 :          88 :                                            condition);
   13741                 :          88 :                           SET_EXPR_LOCATION (e, token->location);
   13742                 :          88 :                           chain->safe_push (e);
   13743                 :             :                         }
   13744                 :             :                       }
   13745                 :         102 :                     else if (!cp_lexer_next_token_is_keyword (parser->lexer,
   13746                 :             :                                                               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                 :          16 :                       vec_free (chain);
   13751                 :             :                   }
   13752                 :    12050464 :                 begin_else_clause (statement);
   13753                 :             :                 /* Parse the else-clause.  */
   13754                 :    12050464 :                 cp_parser_implicitly_scoped_statement (parser, NULL,
   13755                 :             :                                                        guard_tinfo, chain);
   13756                 :             : 
   13757                 :    12050464 :                 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                 :    12050464 :                 if (if_p != NULL)
   13765                 :       77420 :                   *if_p = true;
   13766                 :             : 
   13767                 :    12050464 :                 if (discard_else)
   13768                 :             :                   {
   13769                 :       31346 :                     ELSE_CLAUSE (statement) = NULL_TREE;
   13770                 :       31346 :                     in_discarded_stmt = was_discarded;
   13771                 :       31346 :                     --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                 :    25233376 :                 if (nested_if)
   13781                 :         450 :                   warning_at (EXPR_LOCATION (statement), OPT_Wdangling_else,
   13782                 :             :                               "suggest explicit braces to avoid ambiguous"
   13783                 :             :                               " %<else%>");
   13784                 :    25233376 :                 if (warn_duplicated_cond)
   13785                 :             :                   /* We don't need the condition chain anymore.  */
   13786                 :         110 :                   vec_free (chain);
   13787                 :             :               }
   13788                 :             : 
   13789                 :             :             /* Now we're all done with the if-statement.  */
   13790                 :    37283840 :             finish_if_stmt (statement);
   13791                 :             :           }
   13792                 :             :         else
   13793                 :             :           {
   13794                 :      168241 :             bool in_switch_statement_p;
   13795                 :      168241 :             unsigned char in_statement;
   13796                 :             : 
   13797                 :             :             /* Add the condition.  */
   13798                 :      168241 :             finish_switch_cond (condition, statement);
   13799                 :             : 
   13800                 :             :             /* Parse the body of the switch-statement.  */
   13801                 :      168241 :             in_switch_statement_p = parser->in_switch_statement_p;
   13802                 :      168241 :             in_statement = parser->in_statement;
   13803                 :      168241 :             parser->in_switch_statement_p = true;
   13804                 :      168241 :             parser->in_statement |= IN_SWITCH_STMT;
   13805                 :      168241 :             cp_parser_implicitly_scoped_statement (parser, if_p,
   13806                 :             :                                                    guard_tinfo);
   13807                 :      168241 :             parser->in_switch_statement_p = in_switch_statement_p;
   13808                 :      168241 :             parser->in_statement = in_statement;
   13809                 :             : 
   13810                 :             :             /* Now we're all done with the switch-statement.  */
   13811                 :      168241 :             finish_switch_stmt (statement);
   13812                 :             :           }
   13813                 :             : 
   13814                 :             :         return statement;
   13815                 :             :       }
   13816                 :           0 :       break;
   13817                 :             : 
   13818                 :           0 :     default:
   13819                 :           0 :       cp_parser_error (parser, "expected selection-statement");
   13820                 :           0 :       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                 :             : 
   13830                 :             : static void
   13831                 :   147664876 : cp_parser_maybe_commit_to_declaration (cp_parser* parser,
   13832                 :             :                                        cp_decl_specifier_seq *decl_specs)
   13833                 :             : {
   13834                 :   147664876 :   if (decl_specs->any_specifiers_p
   13835                 :   147658012 :       && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
   13836                 :   136158073 :       && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
   13837                 :   249723289 :       && !cp_parser_error_occurred (parser)
   13838                 :   294812896 :       && !(decl_specs->type
   13839                 :   100638167 :            && TREE_CODE (decl_specs->type) == TYPE_DECL
   13840                 :    45089607 :            && is_constrained_auto (TREE_TYPE (decl_specs->type))))
   13841                 :   102058242 :     cp_parser_commit_to_tentative_parse (parser);
   13842                 :   147664876 : }
   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                 :             : 
   13848                 :             : static bool
   13849                 :      455592 : cp_parser_check_condition_declarator (cp_parser* parser,
   13850                 :             :                                      cp_declarator *declarator,
   13851                 :             :                                      location_t loc)
   13852                 :             : {
   13853                 :      455592 :   if (declarator == cp_error_declarator
   13854                 :      455569 :       || function_declarator_p (declarator)
   13855                 :      911109 :       || declarator->kind == cdk_array)
   13856                 :             :     {
   13857                 :         100 :       if (declarator == cp_error_declarator)
   13858                 :             :         /* Already complained.  */;
   13859                 :          77 :       else if (declarator->kind == cdk_array)
   13860                 :          25 :        error_at (loc, "condition declares an array");
   13861                 :             :       else
   13862                 :          52 :        error_at (loc, "condition declares a function");
   13863                 :         100 :       if (parser->fully_implicit_function_template_p)
   13864                 :          27 :        abort_fully_implicit_template (parser);
   13865                 :         100 :       cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   13866                 :             :                                             /*or_comma=*/false,
   13867                 :             :                                             /*consume_paren=*/false);
   13868                 :         100 :       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                 :             : 
   13889                 :             : static tree
   13890                 :    45626601 : cp_parser_condition (cp_parser* parser)
   13891                 :             : {
   13892                 :    45626601 :   cp_decl_specifier_seq type_specifiers;
   13893                 :    45626601 :   const char *saved_message;
   13894                 :    45626601 :   int declares_class_or_enum;
   13895                 :             : 
   13896                 :             :   /* Try the declaration first.  */
   13897                 :    45626601 :   cp_parser_parse_tentatively (parser);
   13898                 :             :   /* New types are not allowed in the type-specifier-seq for a
   13899                 :             :      condition.  */
   13900                 :    45626601 :   saved_message = parser->type_definition_forbidden_message;
   13901                 :    45626601 :   parser->type_definition_forbidden_message
   13902                 :    45626601 :     = G_("types may not be defined in conditions");
   13903                 :             :   /* Parse the type-specifier-seq.  */
   13904                 :    45626601 :   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                 :    45626601 :   parser->type_definition_forbidden_message = saved_message;
   13910                 :             : 
   13911                 :             :   /* Gather the attributes that were provided with the
   13912                 :             :      decl-specifiers.  */
   13913                 :    45626601 :   tree prefix_attributes = type_specifiers.attributes;
   13914                 :             : 
   13915                 :    45626601 :   cp_parser_maybe_commit_to_declaration (parser, &type_specifiers);
   13916                 :             : 
   13917                 :             :   /* If all is well, we might be looking at a declaration.  */
   13918                 :    91253202 :   if (!cp_parser_error_occurred (parser))
   13919                 :             :     {
   13920                 :      709145 :       tree decl;
   13921                 :      709145 :       tree asm_specification;
   13922                 :      709145 :       tree attributes;
   13923                 :      709145 :       cp_declarator *declarator;
   13924                 :      709145 :       tree initializer = NULL_TREE;
   13925                 :      709145 :       location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   13926                 :             : 
   13927                 :             :       /* Parse the declarator.  */
   13928                 :      709145 :       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                 :      709145 :       attributes = cp_parser_attributes_opt (parser);
   13937                 :             :       /* Parse the asm-specification.  */
   13938                 :      709145 :       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                 :      709145 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
   13947                 :      709145 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
   13948                 :      942599 :         cp_parser_simulate_error (parser);
   13949                 :             : 
   13950                 :             :       /* If we did see an `=' or '{', then we are looking at a declaration
   13951                 :             :          for sure.  */
   13952                 :      709145 :       if (cp_parser_parse_definitely (parser))
   13953                 :             :         {
   13954                 :      455592 :           tree pushed_scope;
   13955                 :      455592 :           bool non_constant_p = false;
   13956                 :      455592 :           int flags = LOOKUP_ONLYCONVERTING;
   13957                 :             : 
   13958                 :      455592 :           if (!cp_parser_check_condition_declarator (parser, declarator, loc))
   13959                 :         100 :             return error_mark_node;
   13960                 :             : 
   13961                 :             :           /* Create the declaration.  */
   13962                 :      455492 :           decl = start_decl (declarator, &type_specifiers,
   13963                 :             :                              /*initialized_p=*/true,
   13964                 :             :                              attributes, prefix_attributes,
   13965                 :             :                              &pushed_scope);
   13966                 :             : 
   13967                 :      455492 :           declarator->init_loc = cp_lexer_peek_token (parser->lexer)->location;
   13968                 :             :           /* Parse the initializer.  */
   13969                 :      455492 :           if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   13970                 :             :             {
   13971                 :       18323 :               initializer = cp_parser_braced_list (parser, &non_constant_p);
   13972                 :       18323 :               CONSTRUCTOR_IS_DIRECT_INIT (initializer) = 1;
   13973                 :       18323 :               flags = 0;
   13974                 :             :             }
   13975                 :      437169 :           else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   13976                 :             :             {
   13977                 :             :               /* Consume the `='.  */
   13978                 :      437153 :               cp_lexer_consume_token (parser->lexer);
   13979                 :      437153 :               initializer = cp_parser_initializer_clause (parser,
   13980                 :             :                                                           &non_constant_p);
   13981                 :             :             }
   13982                 :             :           else
   13983                 :             :             {
   13984                 :          16 :               cp_parser_error (parser, "expected initializer");
   13985                 :          16 :               initializer = error_mark_node;
   13986                 :             :             }
   13987                 :      455492 :           if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
   13988                 :       18326 :             maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   13989                 :             : 
   13990                 :             :           /* Process the initializer.  */
   13991                 :      455492 :           cp_finish_decl (decl,
   13992                 :      455492 :                           initializer, !non_constant_p,
   13993                 :             :                           asm_specification,
   13994                 :             :                           flags);
   13995                 :             : 
   13996                 :      455492 :           if (pushed_scope)
   13997                 :           0 :             pop_scope (pushed_scope);
   13998                 :             : 
   13999                 :      455492 :           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                 :    44917456 :     cp_parser_abort_tentative_parse (parser);
   14006                 :             : 
   14007                 :             :   /* Otherwise, we are looking at an expression.  */
   14008                 :    45171009 :   return cp_parser_expression (parser);
   14009                 :             : }
   14010                 :             : 
   14011                 :             : /* Parses a for-statement or range-for-statement until the closing ')',
   14012                 :             :    not included. */
   14013                 :             : 
   14014                 :             : static tree
   14015                 :     5402446 : cp_parser_for (cp_parser *parser, bool ivdep, tree unroll, bool novector)
   14016                 :             : {
   14017                 :     5402446 :   tree init, scope, decl;
   14018                 :     5402446 :   bool is_range_for;
   14019                 :             : 
   14020                 :             :   /* Begin the for-statement.  */
   14021                 :     5402446 :   scope = begin_for_scope (&init);
   14022                 :             : 
   14023                 :             :   /* Maybe parse the optional init-statement in a range-based for loop.  */
   14024                 :     5402446 :   if (cp_parser_range_based_for_with_init_p (parser)
   14025                 :             :       /* Checked for diagnostic purposes only.  */
   14026                 :     5402446 :       && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   14027                 :             :     {
   14028                 :          66 :       tree dummy;
   14029                 :          66 :       cp_parser_init_statement (parser, &dummy);
   14030                 :          66 :       if (cxx_dialect < cxx20)
   14031                 :             :         {
   14032                 :           4 :           pedwarn (cp_lexer_peek_token (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                 :           4 :           decl = error_mark_node;
   14037                 :             :         }
   14038                 :             :     }
   14039                 :             : 
   14040                 :             :   /* Parse the initialization.  */
   14041                 :     5402446 :   is_range_for = cp_parser_init_statement (parser, &decl);
   14042                 :             : 
   14043                 :     5402446 :   if (is_range_for)
   14044                 :      189073 :     return cp_parser_range_for (parser, scope, init, decl, ivdep, unroll,
   14045                 :      189073 :                                 novector, false);
   14046                 :             :   else
   14047                 :     5213373 :     return cp_parser_c_for (parser, scope, init, ivdep, unroll, novector);
   14048                 :             : }
   14049                 :             : 
   14050                 :             : static tree
   14051                 :     5213373 : cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep,
   14052                 :             :                  tree unroll, bool novector)
   14053                 :             : {
   14054                 :             :   /* Normal for loop */
   14055                 :     5213373 :   tree condition = NULL_TREE;
   14056                 :     5213373 :   tree expression = NULL_TREE;
   14057                 :     5213373 :   tree stmt;
   14058                 :             : 
   14059                 :     5213373 :   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                 :     5213373 :   finish_init_stmt (stmt);
   14063                 :             : 
   14064                 :             :   /* If there's a condition, process it.  */
   14065                 :     5213373 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   14066                 :     5005380 :     condition = cp_parser_condition (parser);
   14067                 :      207993 :   else if (ivdep)
   14068                 :             :     {
   14069                 :           4 :       cp_parser_error (parser, "missing loop condition in loop with "
   14070                 :             :                        "%<GCC ivdep%> pragma");
   14071                 :           4 :       condition = error_mark_node;
   14072                 :             :     }
   14073                 :      207989 :   else if (unroll)
   14074                 :             :     {
   14075                 :           0 :       cp_parser_error (parser, "missing loop condition in loop with "
   14076                 :             :                        "%<GCC unroll%> pragma");
   14077                 :           0 :       condition = error_mark_node;
   14078                 :             :     }
   14079                 :     5213373 :   finish_for_cond (condition, stmt, ivdep, unroll, novector);
   14080                 :             :   /* Look for the `;'.  */
   14081                 :     5213373 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   14082                 :             : 
   14083                 :             :   /* If there's an expression, process it.  */
   14084                 :     5213373 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
   14085                 :     4919748 :     expression = cp_parser_expression (parser);
   14086                 :     5213373 :   finish_for_expr (expression, stmt);
   14087                 :             : 
   14088                 :     5213373 :   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                 :             : 
   14101                 :             : static tree
   14102                 :      189218 : cp_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                 :      189218 :   tree stmt, range_expr;
   14106                 :      189218 :   auto_vec <cxx_binding *, 16> bindings;
   14107                 :      189218 :   auto_vec <tree, 16> names;
   14108                 :      189218 :   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                 :      189218 :   if (range_decl != error_mark_node)
   14113                 :             :     {
   14114                 :      189204 :       if (DECL_HAS_VALUE_EXPR_P (range_decl))
   14115                 :             :         {
   14116                 :         131 :           tree v = DECL_VALUE_EXPR (range_decl);
   14117                 :             :           /* For decomposition declaration get all of the corresponding
   14118                 :             :              declarations out of the way.  */
   14119                 :         131 :           if (TREE_CODE (v) == ARRAY_REF
   14120                 :         131 :               && VAR_P (TREE_OPERAND (v, 0))
   14121                 :         262 :               && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
   14122                 :             :             {
   14123                 :         131 :               tree d = range_decl;
   14124                 :         131 :               range_decl = TREE_OPERAND (v, 0);
   14125                 :         131 :               decomp = &decomp_d;
   14126                 :         131 :               decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
   14127                 :         131 :               decomp->decl = d;
   14128                 :         522 :               for (unsigned int i = 0; i < decomp->count;
   14129                 :         391 :                    i++, d = DECL_CHAIN (d))
   14130                 :             :                 {
   14131                 :         391 :                   tree name = DECL_NAME (d);
   14132                 :         391 :                   names.safe_push (name);
   14133                 :         391 :                   bindings.safe_push (IDENTIFIER_BINDING (name));
   14134                 :         782 :                   IDENTIFIER_BINDING (name)
   14135                 :         391 :                     = IDENTIFIER_BINDING (name)->previous;
   14136                 :             :                 }
   14137                 :             :             }
   14138                 :             :         }
   14139                 :      189204 :       if (names.is_empty ())
   14140                 :             :         {
   14141                 :      189073 :           tree name = DECL_NAME (range_decl);
   14142                 :      189073 :           names.safe_push (name);
   14143                 :      189073 :           bindings.safe_push (IDENTIFIER_BINDING (name));
   14144                 :      189073 :           IDENTIFIER_BINDING (name) = IDENTIFIER_BINDING (name)->previous;
   14145                 :             :         }
   14146                 :             :     }
   14147                 :             : 
   14148                 :      189218 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   14149                 :         144 :     range_expr = cp_parser_braced_list (parser);
   14150                 :             :   else
   14151                 :      189074 :     range_expr = cp_parser_expression (parser);
   14152                 :             : 
   14153                 :             :   /* Put the range declaration(s) back into scope. */
   14154                 :      757364 :   for (unsigned int i = 0; i < names.length (); i++)
   14155                 :             :     {
   14156                 :      189464 :       cxx_binding *binding = bindings[i];
   14157                 :      189464 :       binding->previous = IDENTIFIER_BINDING (names[i]);
   14158                 :      189464 :       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                 :      189218 :   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                 :      189073 :   if (processing_template_decl)
   14169                 :             :     {
   14170                 :      186714 :       if (check_for_bare_parameter_packs (range_expr))
   14171                 :           3 :         range_expr = error_mark_node;
   14172                 :      186714 :       stmt = begin_range_for_stmt (scope, init);
   14173                 :      186714 :       if (ivdep)
   14174                 :           1 :         RANGE_FOR_IVDEP (stmt) = 1;
   14175                 :      186714 :       if (unroll)
   14176                 :          57 :         RANGE_FOR_UNROLL (stmt) = unroll;
   14177                 :      186714 :       if (novector)
   14178                 :           0 :         RANGE_FOR_NOVECTOR (stmt) = 1;
   14179                 :      186714 :       finish_range_for_decl (stmt, range_decl, range_expr);
   14180                 :      186714 :       if (!type_dependent_expression_p (range_expr)
   14181                 :             :           /* do_auto_deduction doesn't mess with template init-lists.  */
   14182                 :      186714 :           && !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
   14183                 :       45965 :         do_range_for_auto_deduction (range_decl, range_expr, decomp);
   14184                 :             :     }
   14185                 :             :   else
   14186                 :             :     {
   14187                 :        2359 :       stmt = begin_for_stmt (scope, init);
   14188                 :        2359 :       stmt = cp_convert_range_for (stmt, range_decl, range_expr, decomp,
   14189                 :             :                                    ivdep, unroll, novector);
   14190                 :             :     }
   14191                 :             :   return stmt;
   14192                 :      189218 : }
   14193                 :             : 
   14194                 :             : /* Subroutine of cp_convert_range_for: given the initializer expression,
   14195                 :             :    builds up the range temporary.  */
   14196                 :             : 
   14197                 :             : static tree
   14198                 :       91888 : build_range_temp (tree range_expr)
   14199                 :             : {
   14200                 :             :   /* Find out the type deduced by the declaration
   14201                 :             :      `auto &&__range = range_expr'.  */
   14202                 :       91888 :   tree auto_node = make_auto ();
   14203                 :       91888 :   tree range_type = cp_build_reference_type (auto_node, true);
   14204                 :       91888 :   range_type = do_auto_deduction (range_type, range_expr, auto_node);
   14205                 :             : 
   14206                 :             :   /* Create the __range variable.  */
   14207                 :       91888 :   tree range_temp = build_decl (input_location, VAR_DECL,
   14208                 :             :                                 for_range__identifier, range_type);
   14209                 :       91888 :   TREE_USED (range_temp) = 1;
   14210                 :       91888 :   DECL_ARTIFICIAL (range_temp) = 1;
   14211                 :             : 
   14212                 :       91888 :   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                 :             : 
   14220                 :             : static void
   14221                 :       46013 : do_range_for_auto_deduction (tree decl, tree range_expr, cp_decomp *decomp)
   14222                 :             : {
   14223                 :       46013 :   tree auto_node = type_uses_auto (TREE_TYPE (decl));
   14224                 :       46013 :   if (auto_node)
   14225                 :             :     {
   14226                 :       45948 :       tree begin_dummy, end_dummy, range_temp, iter_type, iter_decl;
   14227                 :       45948 :       range_temp = convert_from_reference (build_range_temp (range_expr));
   14228                 :       45948 :       iter_type = (cp_parser_perform_range_for_lookup
   14229                 :       45948 :                    (range_temp, &begin_dummy, &end_dummy));
   14230                 :       45948 :       if (iter_type)
   14231                 :             :         {
   14232                 :       45942 :           iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE,
   14233                 :             :                                   iter_type);
   14234                 :       45942 :           iter_decl = build_x_indirect_ref (input_location, iter_decl,
   14235                 :             :                                             RO_UNARY_STAR, NULL_TREE,
   14236                 :             :                                             tf_warning_or_error);
   14237                 :       45942 :           TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
   14238                 :             :                                                 iter_decl, auto_node,
   14239                 :             :                                                 tf_warning_or_error,
   14240                 :             :                                                 adc_variable_type);
   14241                 :       45942 :           if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
   14242                 :          42 :             cp_finish_decomp (decl, decomp);
   14243                 :             :         }
   14244                 :             :     }
   14245                 :       46013 : }
   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                 :             : 
   14267                 :             : static void
   14268                 :       45821 : warn_for_range_copy (tree decl, tree expr)
   14269                 :             : {
   14270                 :       45821 :   if (!warn_range_loop_construct
   14271                 :        1773 :       || decl == error_mark_node)
   14272                 :             :     return;
   14273                 :             : 
   14274                 :        1773 :   location_t loc = DECL_SOURCE_LOCATION (decl);
   14275                 :        1773 :   tree type = TREE_TYPE (decl);
   14276                 :             : 
   14277                 :        1773 :   if (from_macro_expansion_at (loc))
   14278                 :             :     return;
   14279                 :             : 
   14280                 :        1285 :   if (TYPE_REF_P (type))
   14281                 :             :     {
   14282                 :         948 :       if (glvalue_p (expr)
   14283                 :         948 :           && ref_conv_binds_to_temporary (type, expr).is_true ())
   14284                 :             :         {
   14285                 :          78 :           auto_diagnostic_group d;
   14286                 :          78 :           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                 :          78 :                           TREE_TYPE (expr)))
   14290                 :             :             {
   14291                 :          78 :               tree ref = cp_build_qualified_type (TREE_TYPE (expr),
   14292                 :             :                                                   TYPE_QUAL_CONST);
   14293                 :          78 :               ref = cp_build_reference_type (ref, /*rval*/false);
   14294                 :          78 :               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                 :          78 :         }
   14299                 :         948 :       return;
   14300                 :             :     }
   14301                 :         337 :   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                 :         158 :   if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
   14307                 :         158 :       || (tree_to_uhwi (TYPE_SIZE_UNIT (type)) <= 64
   14308                 :          77 :           && trivially_copyable_p (type)))
   14309                 :          77 :     return;
   14310                 :             : 
   14311                 :             :   /* If we can initialize a reference directly, suggest that to avoid the
   14312                 :             :      copy.  */
   14313                 :          81 :   tree rtype = cp_build_reference_type (type, /*rval*/false);
   14314                 :          81 :   if (ref_conv_binds_to_temporary (rtype, expr).is_false ())
   14315                 :             :     {
   14316                 :          36 :       auto_diagnostic_group d;
   14317                 :          36 :       if (warning_at (loc, OPT_Wrange_loop_construct,
   14318                 :             :                       "loop variable %qD creates a copy from type %qT",
   14319                 :             :                       decl, type))
   14320                 :             :         {
   14321                 :          36 :           gcc_rich_location richloc (loc);
   14322                 :          36 :           richloc.add_fixit_insert_before ("&");
   14323                 :          36 :           inform (&richloc, "use reference type to prevent copying");
   14324                 :          36 :         }
   14325                 :          36 :     }
   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                 :             : 
   14363                 :             : tree
   14364                 :       45821 : cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
   14365                 :             :                       cp_decomp *decomp, bool ivdep, tree unroll,
   14366                 :             :                       bool novector)
   14367                 :             : {
   14368                 :       45821 :   tree begin, end;
   14369                 :       45821 :   tree iter_type, begin_expr, end_expr;
   14370                 :       45821 :   tree condition, expression;
   14371                 :             : 
   14372                 :       45821 :   range_expr = mark_lvalue_use (range_expr);
   14373                 :             : 
   14374                 :       45821 :   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                 :          20 :     begin_expr = end_expr = iter_type = error_mark_node;
   14378                 :             :   else
   14379                 :             :     {
   14380                 :       45801 :       tree range_temp;
   14381                 :             : 
   14382                 :       45801 :       if (VAR_P (range_expr)
   14383                 :       45801 :           && 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                 :       45801 :           range_temp = build_range_temp (range_expr);
   14389                 :       45801 :           pushdecl (range_temp);
   14390                 :       45801 :           cp_finish_decl (range_temp, range_expr,
   14391                 :             :                           /*is_constant_init*/false, NULL_TREE,
   14392                 :             :                           LOOKUP_ONLYCONVERTING);
   14393                 :       45801 :           range_temp = convert_from_reference (range_temp);
   14394                 :             :         }
   14395                 :       45801 :       iter_type = cp_parser_perform_range_for_lookup (range_temp,
   14396                 :             :                                                       &begin_expr, &end_expr);
   14397                 :             :     }
   14398                 :             : 
   14399                 :             :   /* The new for initialization statement.  */
   14400                 :       45821 :   begin = build_decl (input_location, VAR_DECL, for_begin__identifier,
   14401                 :             :                       iter_type);
   14402                 :       45821 :   TREE_USED (begin) = 1;
   14403                 :       45821 :   DECL_ARTIFICIAL (begin) = 1;
   14404                 :       45821 :   pushdecl (begin);
   14405                 :       45821 :   cp_finish_decl (begin, begin_expr,
   14406                 :             :                   /*is_constant_init*/false, NULL_TREE,
   14407                 :             :                   LOOKUP_ONLYCONVERTING);
   14408                 :             : 
   14409                 :       45821 :   if (cxx_dialect >= cxx17)
   14410                 :       44405 :     iter_type = cv_unqualified (TREE_TYPE (end_expr));
   14411                 :       45821 :   end = build_decl (input_location, VAR_DECL, for_end__identifier, iter_type);
   14412                 :       45821 :   TREE_USED (end) = 1;
   14413                 :       45821 :   DECL_ARTIFICIAL (end) = 1;
   14414                 :       45821 :   pushdecl (end);
   14415                 :       45821 :   cp_finish_decl (end, end_expr,
   14416                 :             :                   /*is_constant_init*/false, NULL_TREE,
   14417                 :             :                   LOOKUP_ONLYCONVERTING);
   14418                 :             : 
   14419                 :       45821 :   finish_init_stmt (statement);
   14420                 :             : 
   14421                 :             :   /* The new for condition.  */
   14422                 :       45821 :   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                 :       45821 :   finish_for_cond (condition, statement, ivdep, unroll, novector);
   14427                 :             : 
   14428                 :             :   /* The new increment expression.  */
   14429                 :       45821 :   expression = finish_unary_op_expr (input_location,
   14430                 :             :                                      PREINCREMENT_EXPR, begin,
   14431                 :             :                                      tf_warning_or_error);
   14432                 :       45821 :   finish_for_expr (expression, statement);
   14433                 :             : 
   14434                 :             :   /* The declaration is initialized with *__begin inside the loop body.  */
   14435                 :       45821 :   tree deref_begin = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
   14436                 :             :                                            NULL_TREE, tf_warning_or_error);
   14437                 :       45821 :   cp_finish_decl (range_decl, deref_begin,
   14438                 :             :                   /*is_constant_init*/false, NULL_TREE,
   14439                 :             :                   LOOKUP_ONLYCONVERTING, decomp);
   14440                 :       45821 :   if (VAR_P (range_decl) && DECL_DECOMPOSITION_P (range_decl))
   14441                 :          88 :     cp_finish_decomp (range_decl, decomp);
   14442                 :             : 
   14443                 :       45821 :   warn_for_range_copy (range_decl, deref_begin);
   14444                 :             : 
   14445                 :       45821 :   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                 :             : 
   14453                 :             : static tree
   14454                 :       91888 : cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
   14455                 :             : {
   14456                 :       91888 :   if (error_operand_p (range))
   14457                 :             :     {
   14458                 :           4 :       *begin = *end = error_mark_node;
   14459                 :           4 :       return error_mark_node;
   14460                 :             :     }
   14461                 :             : 
   14462                 :       91884 :   if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (range))))
   14463                 :             :     {
   14464                 :          12 :       error ("range-based %<for%> expression of type %qT "
   14465                 :          12 :              "has incomplete type", TREE_TYPE (range));
   14466                 :          12 :       *begin = *end = error_mark_node;
   14467                 :          12 :       return error_mark_node;
   14468                 :             :     }
   14469                 :       91872 :   if (TREE_CODE (TREE_TYPE (range)) == ARRAY_TYPE)
   14470                 :             :     {
   14471                 :             :       /* If RANGE is an array, we will use pointer arithmetic.  */
   14472                 :       13089 :       *begin = decay_conversion (range, tf_warning_or_error);
   14473                 :       13089 :       *end = build_binary_op (input_location, PLUS_EXPR,
   14474                 :             :                               range,
   14475                 :       13089 :                               array_type_nelts_top (TREE_TYPE (range)),
   14476                 :             :                               false);
   14477                 :       13089 :       return TREE_TYPE (*begin);
   14478                 :             :     }
   14479                 :             :   else
   14480                 :             :     {
   14481                 :             :       /* If it is not an array, we must do a bit of magic.  */
   14482                 :       78783 :       tree id_begin, id_end;
   14483                 :       78783 :       tree member_begin, member_end;
   14484                 :             : 
   14485                 :       78783 :       *begin = *end = error_mark_node;
   14486                 :             : 
   14487                 :       78783 :       id_begin = get_identifier ("begin");
   14488                 :       78783 :       id_end = get_identifier ("end");
   14489                 :       78783 :       member_begin = lookup_member (TREE_TYPE (range), id_begin,
   14490                 :             :                                     /*protect=*/2, /*want_type=*/false,
   14491                 :             :                                     tf_warning_or_error);
   14492                 :       78783 :       member_end = lookup_member (TREE_TYPE (range), id_end,
   14493                 :             :                                   /*protect=*/2, /*want_type=*/false,
   14494                 :             :                                   tf_warning_or_error);
   14495                 :             : 
   14496                 :       78783 :       if (member_begin != NULL_TREE && member_end != NULL_TREE)
   14497                 :             :         {
   14498                 :             :           /* Use the member functions.  */
   14499                 :       78708 :           *begin = cp_parser_range_for_member_function (range, id_begin);
   14500                 :       78708 :           *end = cp_parser_range_for_member_function (range, id_end);
   14501                 :             :         }
   14502                 :             :       else
   14503                 :             :         {
   14504                 :             :           /* Use global functions with ADL.  */
   14505                 :          75 :           releasing_vec vec;
   14506                 :             : 
   14507                 :          75 :           vec_safe_push (vec, range);
   14508                 :             : 
   14509                 :          75 :           member_begin = perform_koenig_lookup (id_begin, vec,
   14510                 :             :                                                 tf_warning_or_error);
   14511                 :          75 :           *begin = finish_call_expr (member_begin, &vec, false, true,
   14512                 :             :                                      tf_warning_or_error);
   14513                 :          75 :           member_end = perform_koenig_lookup (id_end, vec,
   14514                 :             :                                               tf_warning_or_error);
   14515                 :          75 :           *end = finish_call_expr (member_end, &vec, false, true,
   14516                 :             :                                    tf_warning_or_error);
   14517                 :          75 :         }
   14518                 :             : 
   14519                 :             :       /* Last common checks.  */
   14520                 :       78783 :       if (*begin == error_mark_node || *end == error_mark_node)
   14521                 :             :         {
   14522                 :             :           /* If one of the expressions is an error do no more checks.  */
   14523                 :          27 :           *begin = *end = error_mark_node;
   14524                 :          27 :           return error_mark_node;
   14525                 :             :         }
   14526                 :       78756 :       else if (type_dependent_expression_p (*begin)
   14527                 :       78756 :                || 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                 :           6 :         return NULL_TREE;
   14531                 :             :       else
   14532                 :             :         {
   14533                 :       78750 :           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                 :       78750 :           if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (*end))))
   14537                 :             :             {
   14538                 :          46 :               if (cxx_dialect >= cxx17
   14539                 :          89 :                   && (build_x_binary_op (input_location, NE_EXPR,
   14540                 :             :                                          *begin, ERROR_MARK,
   14541                 :             :                                          *end, ERROR_MARK,
   14542                 :             :                                          NULL_TREE, NULL, tf_none)
   14543                 :          45 :                       != 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                 :           3 :                 error ("inconsistent begin/end types in range-based %<for%> "
   14549                 :             :                        "statement: %qT and %qT",
   14550                 :           3 :                        TREE_TYPE (*begin), TREE_TYPE (*end));
   14551                 :             :             }
   14552                 :       78750 :           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                 :             : 
   14560                 :             : static tree
   14561                 :      157416 : cp_parser_range_for_member_function (tree range, tree identifier)
   14562                 :             : {
   14563                 :      157416 :   tree member, res;
   14564                 :             : 
   14565                 :      157416 :   member = finish_class_member_access_expr (range, identifier,
   14566                 :             :                                             false, tf_warning_or_error);
   14567                 :      157416 :   if (member == error_mark_node)
   14568                 :             :     return error_mark_node;
   14569                 :             : 
   14570                 :      157407 :   releasing_vec vec;
   14571                 :      157407 :   res = finish_call_expr (member, &vec,
   14572                 :             :                           /*disallow_virtual=*/false,
   14573                 :             :                           /*koenig_p=*/false,
   14574                 :             :                           tf_warning_or_error);
   14575                 :      157407 :   return res;
   14576                 :      157407 : }
   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                 :             : 
   14588                 :             : static tree
   14589                 :    11688682 : cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep,
   14590                 :             :                                tree unroll, bool novector)
   14591                 :             : {
   14592                 :    11688682 :   cp_token *token;
   14593                 :    11688682 :   enum rid keyword;
   14594                 :    11688682 :   tree statement;
   14595                 :    11688682 :   unsigned char in_statement;
   14596                 :    11688682 :   token_indent_info guard_tinfo;
   14597                 :             : 
   14598                 :             :   /* Peek at the next token.  */
   14599                 :    11688682 :   token = cp_parser_require (parser, CPP_KEYWORD, RT_ITERATION);
   14600                 :    11688682 :   if (!token)
   14601                 :           0 :     return error_mark_node;
   14602                 :             : 
   14603                 :    11688682 :   guard_tinfo = get_token_indent_info (token);
   14604                 :             : 
   14605                 :             :   /* Remember whether or not we are already within an iteration
   14606                 :             :      statement.  */
   14607                 :    11688682 :   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                 :    11688682 :   if (parser->omp_for_parse_state)
   14612                 :             :     {
   14613                 :          63 :       error_at (token->location,
   14614                 :             :                 "loop not permitted in intervening code in OpenMP loop body");
   14615                 :          63 :       parser->omp_for_parse_state->fail = true;
   14616                 :             :     }
   14617                 :             : 
   14618                 :             :   /* See what kind of keyword it is.  */
   14619                 :    11688682 :   keyword = token->keyword;
   14620                 :    11688682 :   switch (keyword)
   14621                 :             :     {
   14622                 :     3169140 :     case RID_WHILE:
   14623                 :     3169140 :       {
   14624                 :     3169140 :         tree condition;
   14625                 :             : 
   14626                 :             :         /* Begin the while-statement.  */
   14627                 :     3169140 :         statement = begin_while_stmt ();
   14628                 :             :         /* Look for the `('.  */
   14629                 :     3169140 :         matching_parens parens;
   14630                 :     3169140 :         parens.require_open (parser);
   14631                 :             :         /* Parse the condition.  */
   14632                 :     3169140 :         condition = cp_parser_condition (parser);
   14633                 :     3169140 :         finish_while_stmt_cond (condition, statement, ivdep, unroll, novector);
   14634                 :             :         /* Look for the `)'.  */
   14635                 :     3169140 :         parens.require_close (parser);
   14636                 :             :         /* Parse the dependent statement.  */
   14637                 :     3169140 :         parser->in_statement = IN_ITERATION_STMT;
   14638                 :     3169140 :         bool prev = note_iteration_stmt_body_start ();
   14639                 :     3169140 :         cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
   14640                 :     3169140 :         note_iteration_stmt_body_end (prev);
   14641                 :     3169140 :         parser->in_statement = in_statement;
   14642                 :             :         /* We're done with the while-statement.  */
   14643                 :     3169140 :         finish_while_stmt (statement);
   14644                 :             :       }
   14645                 :     3169140 :       break;
   14646                 :             : 
   14647                 :     3117096 :     case RID_DO:
   14648                 :     3117096 :       {
   14649                 :     3117096 :         tree expression;
   14650                 :             : 
   14651                 :             :         /* Begin the do-statement.  */
   14652                 :     3117096 :         statement = begin_do_stmt ();
   14653                 :             :         /* Parse the body of the do-statement.  */
   14654                 :     3117096 :         parser->in_statement = IN_ITERATION_STMT;
   14655                 :     3117096 :         bool prev = note_iteration_stmt_body_start ();
   14656                 :     3117096 :         cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);
   14657                 :     3117096 :         note_iteration_stmt_body_end (prev);
   14658                 :     3117096 :         parser->in_statement = in_statement;
   14659                 :     3117096 :         finish_do_body (statement);
   14660                 :             :         /* Look for the `while' keyword.  */
   14661                 :     3117096 :         cp_parser_require_keyword (parser, RID_WHILE, RT_WHILE);
   14662                 :             :         /* Look for the `('.  */
   14663                 :     3117096 :         matching_parens parens;
   14664                 :     3117096 :         parens.require_open (parser);
   14665                 :             :         /* Parse the expression.  */
   14666                 :     3117096 :         expression = cp_parser_expression (parser);
   14667                 :             :         /* We're done with the do-statement.  */
   14668                 :     3117096 :         finish_do_stmt (expression, statement, ivdep, unroll, novector);
   14669                 :             :         /* Look for the `)'.  */
   14670                 :     3117096 :         parens.require_close (parser);
   14671                 :             :         /* Look for the `;'.  */
   14672                 :     3117096 :         cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   14673                 :             :       }
   14674                 :     3117096 :       break;
   14675                 :             : 
   14676                 :     5402446 :     case RID_FOR:
   14677                 :     5402446 :       {
   14678                 :             :         /* Look for the `('.  */
   14679                 :     5402446 :         matching_parens parens;
   14680                 :     5402446 :         parens.require_open (parser);
   14681                 :             : 
   14682                 :     5402446 :         statement = cp_parser_for (parser, ivdep, unroll, novector);
   14683                 :             : 
   14684                 :             :         /* Look for the `)'.  */
   14685                 :     5402446 :         parens.require_close (parser);
   14686                 :             : 
   14687                 :             :         /* Parse the body of the for-statement.  */
   14688                 :     5402446 :         parser->in_statement = IN_ITERATION_STMT;
   14689                 :     5402446 :         bool prev = note_iteration_stmt_body_start ();
   14690                 :     5402446 :         cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
   14691                 :     5402446 :         note_iteration_stmt_body_end (prev);
   14692                 :     5402446 :         parser->in_statement = in_statement;
   14693                 :             : 
   14694                 :             :         /* We're done with the for-statement.  */
   14695                 :     5402446 :         finish_for_stmt (statement);
   14696                 :             :       }
   14697                 :     5402446 :       break;
   14698                 :             : 
   14699                 :           0 :     default:
   14700                 :           0 :       cp_parser_error (parser, "expected iteration-statement");
   14701                 :           0 :       statement = error_mark_node;
   14702                 :           0 :       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                 :             : 
   14716                 :             : static bool
   14717                 :     5431830 : cp_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                 :     5431830 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   14726                 :             :     {
   14727                 :     3879187 :       bool is_range_for = false;
   14728                 :     3879187 :       bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   14729                 :             : 
   14730                 :             :       /* A colon is used in range-based for.  */
   14731                 :     3879187 :       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                 :     3879187 :       cp_parser_parse_tentatively (parser);
   14736                 :     3879187 :       bool expect_semicolon_p = true;
   14737                 :     3879187 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
   14738                 :             :         {
   14739                 :          17 :           cp_parser_alias_declaration (parser);
   14740                 :          17 :           expect_semicolon_p = false;
   14741                 :          17 :           if (cxx_dialect < cxx23
   14742                 :          17 :               && !cp_parser_uncommitted_to_tentative_parse_p (parser))
   14743                 :           5 :             pedwarn (cp_lexer_peek_token (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                 :     3879170 :         cp_parser_simple_declaration (parser,
   14751                 :             :                                       /*function_definition_allowed_p=*/false,
   14752                 :             :                                       decl);
   14753                 :     3879187 :       parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   14754                 :     3879187 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   14755                 :             :         {
   14756                 :             :           /* It is a range-for, consume the ':'.  */
   14757                 :      189073 :           cp_lexer_consume_token (parser->lexer);
   14758                 :      189073 :           is_range_for = true;
   14759                 :      189073 :           if (cxx_dialect < cxx11)
   14760                 :           2 :             pedwarn (cp_lexer_peek_token (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                 :     3690114 :       else if (expect_semicolon_p)
   14766                 :             :         /* The ';' is not consumed yet because we told
   14767                 :             :            cp_parser_simple_declaration not to.  */
   14768                 :     3690097 :         cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   14769                 :             : 
   14770                 :     3879187 :       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                 :     1865142 :   cp_parser_expression_statement (parser, NULL_TREE);
   14777                 :     1865142 :   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                 :             : 
   14797                 :             : static tree
   14798                 :    80670163 : cp_parser_jump_statement (cp_parser* parser)
   14799                 :             : {
   14800                 :    80670163 :   tree statement = error_mark_node;
   14801                 :    80670163 :   cp_token *token;
   14802                 :    80670163 :   enum rid keyword;
   14803                 :    80670163 :   unsigned char in_statement;
   14804                 :             : 
   14805                 :             :   /* Peek at the next token.  */
   14806                 :    80670163 :   token = cp_parser_require (parser, CPP_KEYWORD, RT_JUMP);
   14807                 :    80670163 :   if (!token)
   14808                 :           0 :     return error_mark_node;
   14809                 :             : 
   14810                 :             :   /* See what kind of keyword it is.  */
   14811                 :    80670163 :   keyword = token->keyword;
   14812                 :    80670163 :   switch (keyword)
   14813                 :             :     {
   14814                 :     2199918 :     case RID_BREAK:
   14815                 :     2199918 :       in_statement = parser->in_statement & ~IN_IF_STMT;
   14816                 :     2199918 :       switch (in_statement)
   14817                 :             :         {
   14818                 :          10 :         case 0:
   14819                 :          10 :           error_at (token->location, "break statement not within loop or switch");
   14820                 :          10 :           break;
   14821                 :     2199865 :         default:
   14822                 :     2199865 :           gcc_assert ((in_statement & IN_SWITCH_STMT)
   14823                 :             :                       || in_statement == IN_ITERATION_STMT);
   14824                 :     2199865 :           statement = finish_break_stmt ();
   14825                 :     2199865 :           if (in_statement == IN_ITERATION_STMT)
   14826                 :     1288107 :             break_maybe_infinite_loop ();
   14827                 :             :           break;
   14828                 :          23 :         case IN_OMP_BLOCK:
   14829                 :          23 :           error_at (token->location, "invalid exit from OpenMP structured block");
   14830                 :          23 :           break;
   14831                 :          20 :         case IN_OMP_FOR:
   14832                 :          20 :           error_at (token->location, "break statement used with OpenMP for loop");
   14833                 :          20 :           break;
   14834                 :             :         }
   14835                 :     2199918 :       cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   14836                 :     2199918 :       break;
   14837                 :             : 
   14838                 :      136792 :     case RID_CONTINUE:
   14839                 :      136792 :       switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
   14840                 :             :         {
   14841                 :           4 :         case 0:
   14842                 :           4 :           error_at (token->location, "continue statement not within a loop");
   14843                 :           4 :           break;
   14844                 :             :           /* Fall through.  */
   14845                 :      136757 :         case IN_ITERATION_STMT:
   14846                 :      136757 :         case IN_OMP_FOR:
   14847                 :      136757 :           statement = finish_continue_stmt ();
   14848                 :      136757 :           break;
   14849                 :          31 :         case IN_OMP_BLOCK:
   14850                 :          31 :           error_at (token->location, "invalid exit from OpenMP structured block");
   14851                 :          31 :           break;
   14852                 :           0 :         default:
   14853                 :           0 :           gcc_unreachable ();
   14854                 :             :         }
   14855                 :      136792 :       cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   14856                 :      136792 :       break;
   14857                 :             : 
   14858                 :    78331814 :     case RID_CO_RETURN:
   14859                 :    78331814 :     case RID_RETURN:
   14860                 :    78331814 :       {
   14861                 :    78331814 :         tree expr;
   14862                 :             : 
   14863                 :    78331814 :         if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   14864                 :             :           {
   14865                 :     1056330 :             cp_lexer_set_source_position (parser->lexer);
   14866                 :     1056330 :             maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   14867                 :     1056330 :             expr = cp_parser_braced_list (parser);
   14868                 :             :           }
   14869                 :    77275484 :         else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   14870                 :    76297594 :           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                 :    78331813 :         if (keyword == RID_CO_RETURN)
   14878                 :        1330 :           statement = finish_co_return_stmt (token->location, expr);
   14879                 :    78330483 :         else if (FNDECL_USED_AUTO (current_function_decl) && in_discarded_stmt)
   14880                 :             :           /* Don't deduce from a discarded return statement.  */;
   14881                 :             :         else
   14882                 :    78330478 :           statement = finish_return_stmt (expr);
   14883                 :             :         /* Look for the final `;'.  */
   14884                 :    78331813 :         cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   14885                 :             :       }
   14886                 :    78331813 :       break;
   14887                 :             : 
   14888                 :        1639 :     case RID_GOTO:
   14889                 :        1639 :       if (parser->in_function_body
   14890                 :        1639 :           && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
   14891                 :        1665 :           && cxx_dialect < cxx23)
   14892                 :             :         {
   14893                 :          24 :           error ("%<goto%> in %<constexpr%> function only available with "
   14894                 :             :                  "%<-std=c++2b%> or %<-std=gnu++2b%>");
   14895                 :          24 :           cp_function_chain->invalid_constexpr = true;
   14896                 :             :         }
   14897                 :             : 
   14898                 :             :       /* Create the goto-statement.  */
   14899                 :        1639 :       if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
   14900                 :             :         {
   14901                 :             :           /* Issue a warning about this use of a GNU extension.  */
   14902                 :         119 :           pedwarn (token->location, OPT_Wpedantic, "ISO C++ forbids computed gotos");
   14903                 :             :           /* Consume the '*' token.  */
   14904                 :         119 :           cp_lexer_consume_token (parser->lexer);
   14905                 :             :           /* Parse the dependent expression.  */
   14906                 :         119 :           finish_goto_stmt (cp_parser_expression (parser));
   14907                 :             :         }
   14908                 :             :       else
   14909                 :        1520 :         finish_goto_stmt (cp_parser_identifier (parser));
   14910                 :             :       /* Look for the final `;'.  */
   14911                 :        1639 :       cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   14912                 :        1639 :       break;
   14913                 :             : 
   14914                 :           0 :     default:
   14915                 :           0 :       cp_parser_error (parser, "expected jump-statement");
   14916                 :           0 :       break;
   14917                 :             :     }
   14918                 :             : 
   14919                 :             :   return statement;
   14920                 :             : }
   14921                 :             : 
   14922                 :             : /* Parse a declaration-statement.
   14923                 :             : 
   14924                 :             :    declaration-statement:
   14925                 :             :      block-declaration  */
   14926                 :             : 
   14927                 :             : static void
   14928                 :   138748637 : cp_parser_declaration_statement (cp_parser* parser)
   14929                 :             : {
   14930                 :   138748637 :   void *p;
   14931                 :             : 
   14932                 :             :   /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
   14933                 :   138748637 :   p = obstack_alloc (&declarator_obstack, 0);
   14934                 :             : 
   14935                 :             :  /* Parse the block-declaration.  */
   14936                 :   138748637 :   cp_parser_block_declaration (parser, /*statement_p=*/true);
   14937                 :             : 
   14938                 :             :   /* Free any declarators allocated.  */
   14939                 :   138748633 :   obstack_free (&declarator_obstack, p);
   14940                 :   138748633 : }
   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                 :             : 
   14961                 :             : static tree
   14962                 :    52626236 : cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p,
   14963                 :             :                                        const token_indent_info &guard_tinfo,
   14964                 :             :                                        vec<tree> *chain)
   14965                 :             : {
   14966                 :    52626236 :   tree statement;
   14967                 :    52626236 :   location_t body_loc = cp_lexer_peek_token (parser->lexer)->location;
   14968                 :    52626236 :   location_t body_loc_after_labels = UNKNOWN_LOCATION;
   14969                 :    52626236 :   token_indent_info body_tinfo
   14970                 :    52626236 :     = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
   14971                 :             : 
   14972                 :    52626236 :   if (if_p != NULL)
   14973                 :    37287908 :     *if_p = false;
   14974                 :             : 
   14975                 :             :   /* Mark if () ; with a special NOP_EXPR.  */
   14976                 :    52626236 :   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   14977                 :             :     {
   14978                 :       10606 :       cp_lexer_consume_token (parser->lexer);
   14979                 :       10606 :       statement = add_stmt (build_empty_stmt (body_loc));
   14980                 :             : 
   14981                 :       10606 :       if (guard_tinfo.keyword == RID_IF
   14982                 :       10606 :           && !cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
   14983                 :        1034 :         warning_at (body_loc, OPT_Wempty_body,
   14984                 :             :                     "suggest braces around empty body in an %<if%> statement");
   14985                 :        9572 :       else if (guard_tinfo.keyword == RID_ELSE)
   14986                 :          22 :         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                 :    52615630 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   14991                 :    17600532 :     statement = cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
   14992                 :             :   /* If the token is not a `{', then we must take special action.  */
   14993                 :             :   else
   14994                 :             :     {
   14995                 :             :       /* Create a compound-statement.  */
   14996                 :    35015098 :       statement = begin_compound_stmt (0);
   14997                 :             :       /* Parse the dependent-statement.  */
   14998                 :    35015098 :       cp_parser_statement (parser, NULL_TREE, false, if_p, chain,
   14999                 :             :                            &body_loc_after_labels);
   15000                 :             :       /* Finish the dummy compound-statement.  */
   15001                 :    35015098 :       finish_compound_stmt (statement);
   15002                 :             :     }
   15003                 :             : 
   15004                 :    52626236 :   token_indent_info next_tinfo
   15005                 :    52626236 :     = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
   15006                 :    52626236 :   warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);
   15007                 :             : 
   15008                 :    52626236 :   if (body_loc_after_labels != UNKNOWN_LOCATION
   15009                 :    16794046 :       && next_tinfo.type != CPP_SEMICOLON)
   15010                 :    16781007 :     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
   15011                 :    16781007 :                                     guard_tinfo.location, guard_tinfo.keyword);
   15012                 :             : 
   15013                 :             :   /* Return the statement.  */
   15014                 :    52626236 :   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                 :             : 
   15022                 :             : static void
   15023                 :     8571586 : cp_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                 :     8571586 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
   15028                 :             :     {
   15029                 :     4505112 :       token_indent_info body_tinfo
   15030                 :     4505112 :         = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
   15031                 :     4505112 :       location_t loc_after_labels = UNKNOWN_LOCATION;
   15032                 :             : 
   15033                 :     4505112 :       cp_parser_statement (parser, NULL_TREE, false, if_p, NULL,
   15034                 :             :                            &loc_after_labels);
   15035                 :     4505112 :       token_indent_info next_tinfo
   15036                 :     4505112 :         = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
   15037                 :     4505112 :       warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);
   15038                 :             : 
   15039                 :     4505112 :       if (loc_after_labels != UNKNOWN_LOCATION
   15040                 :     3456252 :           && next_tinfo.type != CPP_SEMICOLON)
   15041                 :     3446990 :         warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
   15042                 :     3446990 :                                         guard_tinfo.location,
   15043                 :     3446990 :                                         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                 :     4066474 :       matching_braces braces;
   15050                 :     4066474 :       braces.require_open (parser);
   15051                 :             :       /* If the next keyword is `__label__' we have a label declaration.  */
   15052                 :     8132956 :       while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
   15053                 :           8 :         cp_parser_label_declaration (parser);
   15054                 :             :       /* Parse an (optional) statement-seq.  */
   15055                 :     4066474 :       cp_parser_statement_seq_opt (parser, NULL_TREE);
   15056                 :     4066474 :       braces.require_close (parser);
   15057                 :             :     }
   15058                 :     8571586 : }
   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                 :             : 
   15077                 :             : static module_state *
   15078                 :        2501 : cp_parser_module_name (cp_parser *parser, bool partition_p = false,
   15079                 :             :                        module_state *parent = NULL)
   15080                 :             : {
   15081                 :        2501 :   if (partition_p
   15082                 :        2501 :       && cp_lexer_consume_token (parser->lexer)->type != CPP_COLON)
   15083                 :             :     return NULL;
   15084                 :             : 
   15085                 :        2877 :   for (;;)
   15086                 :             :     {
   15087                 :        2689 :       if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME)
   15088                 :             :         {
   15089                 :           6 :           if (partition_p)
   15090                 :           0 :             cp_parser_error (parser, "expected module-partition");
   15091                 :             :           else
   15092                 :           6 :             cp_parser_error (parser, "expected module-name");
   15093                 :           6 :           return NULL;
   15094                 :             :         }
   15095                 :             : 
   15096                 :        2683 :       tree name = cp_lexer_consume_token (parser->lexer)->u.value;
   15097                 :        2683 :       parent = get_module (name, parent, partition_p);
   15098                 :        2683 :       if (cp_lexer_peek_token (parser->lexer)->type != CPP_DOT)
   15099                 :             :         break;
   15100                 :             : 
   15101                 :         188 :       cp_lexer_consume_token (parser->lexer);
   15102                 :         188 :     }
   15103                 :             : 
   15104                 :             :   return parent;
   15105                 :             : }
   15106                 :             : 
   15107                 :             : /* Parse a module-partition.  Defers to cp_parser_module_name.  */
   15108                 :             : 
   15109                 :             : static module_state *
   15110                 :         216 : cp_parser_module_partition (cp_parser *parser, module_state *parent = NULL)
   15111                 :             : {
   15112                 :           0 :   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                 :             : 
   15122                 :             : static module_parse
   15123                 :        1633 : cp_parser_module_declaration (cp_parser *parser, module_parse mp_state,
   15124                 :             :                               bool exporting)
   15125                 :             : {
   15126                 :             :   /* We're a pseudo pragma.  */
   15127                 :        1633 :   parser->lexer->in_pragma = true;
   15128                 :        1633 :   cp_token *token = cp_lexer_consume_token (parser->lexer);
   15129                 :             : 
   15130                 :        1633 :   if (flag_header_unit)
   15131                 :             :     {
   15132                 :           3 :       error_at (token->location,
   15133                 :             :                 "module-declaration not permitted in header-unit");
   15134                 :           3 :       goto skip_eol;
   15135                 :             :     }
   15136                 :        1630 :   else if (mp_state == MP_FIRST && !exporting
   15137                 :        1630 :       && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   15138                 :             :     {
   15139                 :             :       /* Start global module fragment.  */
   15140                 :         203 :       cp_lexer_consume_token (parser->lexer);
   15141                 :         203 :       module_kind = MK_NAMED;
   15142                 :         203 :       mp_state = MP_GLOBAL;
   15143                 :         203 :       cp_parser_require_pragma_eol (parser, token);
   15144                 :             :     }
   15145                 :        1427 :   else if (!exporting
   15146                 :         240 :            && cp_lexer_next_token_is (parser->lexer, CPP_COLON)
   15147                 :          15 :            && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_PRIVATE)
   15148                 :        1439 :            && cp_lexer_nth_token_is (parser->lexer, 3, CPP_SEMICOLON))
   15149                 :             :     {
   15150                 :          12 :       cp_lexer_consume_token (parser->lexer);
   15151                 :          12 :       cp_lexer_consume_token (parser->lexer);
   15152                 :          12 :       cp_lexer_consume_token (parser->lexer);
   15153                 :          12 :       cp_parser_require_pragma_eol (parser, token);
   15154                 :             : 
   15155                 :          12 :       if ((mp_state == MP_PURVIEW || mp_state == MP_PURVIEW_IMPORTS)
   15156                 :          12 :           && module_has_cmi_p ())
   15157                 :             :         {
   15158                 :           6 :           mp_state = MP_PRIVATE_IMPORTS;
   15159                 :           6 :           sorry_at (token->location, "private module fragment");
   15160                 :             :         }
   15161                 :             :       else
   15162                 :           6 :         error_at (token->location,
   15163                 :             :                   "private module fragment only permitted in purview"
   15164                 :             :                   " of module interface or partition");
   15165                 :             :     }
   15166                 :        1415 :   else if (!(mp_state == MP_FIRST || mp_state == MP_GLOBAL))
   15167                 :             :     {
   15168                 :             :       /* Neither the first declaration, nor in a GMF.  */
   15169                 :          15 :       error_at (token->location, "module-declaration only permitted as first"
   15170                 :             :                 " declaration, or ending a global module fragment");
   15171                 :          24 :     skip_eol:
   15172                 :          24 :       cp_parser_skip_to_pragma_eol (parser, token);
   15173                 :             :     }
   15174                 :             :   else
   15175                 :             :     {
   15176                 :        1400 :       module_state *mod = cp_parser_module_name (parser);
   15177                 :        1400 :       if (mod && cp_lexer_peek_token (parser->lexer)->type == CPP_COLON)
   15178                 :          93 :         mod = cp_parser_module_partition (parser, mod);
   15179                 :        1400 :       tree attrs = cp_parser_attributes_opt (parser);
   15180                 :             : 
   15181                 :        1400 :       if (mod)
   15182                 :        1394 :         mp_state = MP_PURVIEW_IMPORTS;
   15183                 :        1394 :       if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
   15184                 :           6 :         goto skip_eol;
   15185                 :             : 
   15186                 :        1394 :       declare_module (mod, token->location, exporting, attrs, parse_in);
   15187                 :        1394 :       cp_parser_require_pragma_eol (parser, token);
   15188                 :             :     }
   15189                 :             : 
   15190                 :        1633 :   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                 :             : 
   15199                 :             : static void
   15200                 :        1706 : cp_parser_import_declaration (cp_parser *parser, module_parse mp_state,
   15201                 :             :                               bool exporting)
   15202                 :             : {
   15203                 :             :   /* We're a pseudo pragma.  */
   15204                 :        1706 :   parser->lexer->in_pragma = true;
   15205                 :        1706 :   cp_token *token = cp_lexer_consume_token (parser->lexer);
   15206                 :             : 
   15207                 :        1706 :   if (mp_state == MP_PURVIEW || mp_state == MP_PRIVATE)
   15208                 :             :     {
   15209                 :          12 :       error_at (token->location, "post-module-declaration"
   15210                 :             :                 " imports must be contiguous");
   15211                 :          12 :     note_lexer:
   15212                 :          12 :       inform (token->location, "perhaps insert a line break, or other"
   15213                 :             :               " disambiguation, to prevent this being considered a"
   15214                 :             :               " module control-line");
   15215                 :          24 :     skip_eol:
   15216                 :          24 :       cp_parser_skip_to_pragma_eol (parser, token);
   15217                 :             :     }
   15218                 :        1694 :   else if (current_scope () != global_namespace)
   15219                 :             :     {
   15220                 :           0 :       error_at (token->location, "import-declaration must be at global scope");
   15221                 :           0 :       goto note_lexer;
   15222                 :             :     }
   15223                 :             :   else
   15224                 :             :     {
   15225                 :        1694 :       module_state *mod = NULL;
   15226                 :        1694 :       cp_token *next = cp_lexer_peek_token (parser->lexer);
   15227                 :        1694 :       if (next->type == CPP_HEADER_NAME)
   15228                 :             :         {
   15229                 :         683 :           cp_lexer_consume_token (parser->lexer);
   15230                 :         683 :           mod = get_module (next->u.value);
   15231                 :             :         }
   15232                 :        1011 :       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                 :         126 :           if (named_module_p ()
   15237                 :         126 :               && (mp_state == MP_PURVIEW_IMPORTS
   15238                 :         126 :                   || mp_state == MP_PRIVATE_IMPORTS))
   15239                 :         123 :             mod = cp_parser_module_partition (parser);
   15240                 :             :           else
   15241                 :           3 :             error_at (next->location, "import specifying a module-partition"
   15242                 :             :                       " must appear after a named module-declaration");
   15243                 :             :         }
   15244                 :             :       else
   15245                 :         885 :         mod = cp_parser_module_name (parser);
   15246                 :        1694 :       tree attrs = cp_parser_attributes_opt (parser);
   15247                 :             : 
   15248                 :        1694 :       if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
   15249                 :          12 :         goto skip_eol;
   15250                 :        1682 :       cp_parser_require_pragma_eol (parser, token);
   15251                 :             : 
   15252                 :        1682 :       if (parser->in_unbraced_linkage_specification_p)
   15253                 :           3 :         error_at (token->location, "import cannot appear directly in"
   15254                 :             :                   " a linkage-specification");
   15255                 :             : 
   15256                 :        1682 :       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                 :         363 :           if (attrs
   15261                 :         363 :               && private_lookup_attribute ("__translated",
   15262                 :             :                                            strlen ("__translated"), attrs))
   15263                 :           3 :             error_at (token->location, "post-module-declaration imports"
   15264                 :             :                       " must not be include-translated");
   15265                 :         360 :           else if (!token->main_source_p)
   15266                 :           3 :             error_at (token->location, "post-module-declaration imports"
   15267                 :             :                       " must not be from header inclusion");
   15268                 :             :         }
   15269                 :             : 
   15270                 :        1682 :       import_module (mod, token->location, exporting, attrs, parse_in);
   15271                 :             :     }
   15272                 :        1678 : }
   15273                 :             : 
   15274                 :             : /*  export-declaration.
   15275                 :             : 
   15276                 :             :     export declaration
   15277                 :             :     export { declaration-seq-opt }  */
   15278                 :             : 
   15279                 :             : static void
   15280                 :        1448 : cp_parser_module_export (cp_parser *parser)
   15281                 :             : {
   15282                 :        1448 :   gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT));
   15283                 :        1448 :   cp_token *token = cp_lexer_consume_token (parser->lexer);
   15284                 :             : 
   15285                 :        1448 :   if (!module_interface_p ())
   15286                 :          15 :     error_at (token->location,
   15287                 :             :               "%qE may only occur after a module interface declaration",
   15288                 :             :               token->u.value);
   15289                 :             : 
   15290                 :        1448 :   bool braced = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE);
   15291                 :             : 
   15292                 :        1448 :   unsigned mk = module_kind;
   15293                 :        1448 :   if (module_exporting_p ())
   15294                 :           6 :     error_at (token->location,
   15295                 :             :               "%qE may only occur once in an export declaration",
   15296                 :             :               token->u.value);
   15297                 :        1448 :   module_kind |= MK_EXPORTING;
   15298                 :             : 
   15299                 :        1448 :   if (braced)
   15300                 :             :     {
   15301                 :          13 :       cp_ensure_no_omp_declare_simd (parser);
   15302                 :          13 :       cp_ensure_no_oacc_routine (parser);
   15303                 :             : 
   15304                 :          13 :       cp_lexer_consume_token (parser->lexer);
   15305                 :          13 :       cp_parser_declaration_seq_opt (parser);
   15306                 :          13 :       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                 :        1435 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID__MODULE)
   15314                 :        1435 :           || cp_lexer_next_token_is_keyword (parser->lexer, RID__IMPORT)
   15315                 :        2867 :           || cp_lexer_next_token_is_keyword (parser->lexer, RID__EXPORT))
   15316                 :           3 :         error_at (token->location, "%<export%> not part of following"
   15317                 :             :                   " module-directive");
   15318                 :        1435 :       cp_parser_declaration (parser, NULL_TREE);
   15319                 :             :     }
   15320                 :             : 
   15321                 :        1448 :   module_kind = mk;
   15322                 :        1448 : }
   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                 :             : 
   15334                 :             : static void
   15335                 :     5576372 : cp_parser_declaration_seq_opt (cp_parser* parser)
   15336                 :             : {
   15337                 :   238159679 :   while (true)
   15338                 :             :     {
   15339                 :   121868021 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   15340                 :             : 
   15341                 :   121868021 :       if (token->type == CPP_CLOSE_BRACE
   15342                 :   116291692 :           || token->type == CPP_EOF)
   15343                 :             :         break;
   15344                 :             :       else
   15345                 :   116291658 :         cp_parser_toplevel_declaration (parser);
   15346                 :   116291649 :     }
   15347                 :     5576363 : }
   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                 :             : 
   15376                 :             : static void
   15377                 :   123338430 : cp_parser_declaration (cp_parser* parser, tree prefix_attrs)
   15378                 :             : {
   15379                 :   123338430 :   int saved_pedantic;
   15380                 :             : 
   15381                 :             :   /* Check for the `__extension__' keyword.  */
   15382                 :   123338430 :   if (cp_parser_extension_opt (parser, &saved_pedantic))
   15383                 :             :     {
   15384                 :             :       /* Parse the qualified declaration.  */
   15385                 :      855343 :       cp_parser_declaration (parser, prefix_attrs);
   15386                 :             :       /* Restore the PEDANTIC flag.  */
   15387                 :      855343 :       pedantic = saved_pedantic;
   15388                 :             : 
   15389                 :      938204 :       return;
   15390                 :             :     }
   15391                 :             : 
   15392                 :             :   /* Try to figure out what kind of declaration is present.  */
   15393                 :   122483087 :   cp_token *token1 = cp_lexer_peek_token (parser->lexer);
   15394                 :   122483087 :   cp_token *token2 = (token1->type == CPP_EOF
   15395                 :   122483087 :                       ? token1 : cp_lexer_peek_nth_token (parser->lexer, 2));
   15396                 :             : 
   15397                 :   122483087 :   if (token1->type == CPP_SEMICOLON)
   15398                 :             :     {
   15399                 :       82501 :       cp_lexer_consume_token (parser->lexer);
   15400                 :             :       /* A declaration consisting of a single semicolon is invalid
   15401                 :             :        * before C++11.  Allow it unless we're being pedantic.  */
   15402                 :       82501 :       if (cxx_dialect < cxx11)
   15403                 :         607 :         pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
   15404                 :       82501 :       return;
   15405                 :             :     }
   15406                 :   122400586 :   else if (cp_lexer_nth_token_is (parser->lexer,
   15407                 :             :                                   cp_parser_skip_std_attribute_spec_seq (parser,
   15408                 :             :                                                                          1),
   15409                 :             :                                   CPP_SEMICOLON))
   15410                 :             :     {
   15411                 :         360 :       location_t attrs_loc = token1->location;
   15412                 :         360 :       tree std_attrs = cp_parser_std_attribute_spec_seq (parser);
   15413                 :             : 
   15414                 :         360 :       if (std_attrs && (flag_openmp || flag_openmp_simd))
   15415                 :             :         {
   15416                 :         261 :           gcc_assert (!parser->lexer->in_omp_attribute_pragma);
   15417                 :         261 :           std_attrs = cp_parser_handle_statement_omp_attributes (parser,
   15418                 :             :                                                                  std_attrs);
   15419                 :         261 :           if (parser->lexer->in_omp_attribute_pragma)
   15420                 :             :             {
   15421                 :             :               cp_lexer *lexer = parser->lexer;
   15422                 :         519 :               while (parser->lexer->in_omp_attribute_pragma)
   15423                 :             :                 {
   15424                 :         261 :                   gcc_assert (cp_lexer_next_token_is (parser->lexer,
   15425                 :             :                                                       CPP_PRAGMA));
   15426                 :         261 :                   cp_parser_pragma (parser, pragma_external, NULL);
   15427                 :             :                 }
   15428                 :         258 :               cp_lexer_destroy (lexer);
   15429                 :             :             }
   15430                 :             :         }
   15431                 :             : 
   15432                 :         314 :       if (std_attrs != NULL_TREE && any_nonignored_attribute_p (std_attrs))
   15433                 :          38 :         warning_at (make_location (attrs_loc, attrs_loc, parser->lexer),
   15434                 :             :                     OPT_Wattributes, "attribute ignored");
   15435                 :         360 :       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   15436                 :         360 :         cp_lexer_consume_token (parser->lexer);
   15437                 :         360 :       return;
   15438                 :             :     }
   15439                 :             : 
   15440                 :             :   /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
   15441                 :   122400226 :   void *p = obstack_alloc (&declarator_obstack, 0);
   15442                 :             : 
   15443                 :   122400226 :   tree attributes = NULL_TREE;
   15444                 :             : 
   15445                 :             :   /* Conditionally, allow attributes to precede a linkage specification.  */
   15446                 :   122400226 :   if (token1->keyword == RID_ATTRIBUTE)
   15447                 :             :     {
   15448                 :      337683 :       cp_lexer_save_tokens (parser->lexer);
   15449                 :      337683 :       attributes = cp_parser_attributes_opt (parser);
   15450                 :      337683 :       cp_token *t1 = cp_lexer_peek_token (parser->lexer);
   15451                 :      337683 :       cp_token *t2 = (t1->type == CPP_EOF
   15452                 :      337683 :                       ? t1 : cp_lexer_peek_nth_token (parser->lexer, 2));
   15453                 :      337683 :       if (t1->keyword == RID_EXTERN
   15454                 :      337683 :           && cp_parser_is_pure_string_literal (t2))
   15455                 :             :         {
   15456                 :           0 :           cp_lexer_commit_tokens (parser->lexer);
   15457                 :             :           /* We might have already been here.  */
   15458                 :           0 :           if (!c_dialect_objc ())
   15459                 :             :             {
   15460                 :           0 :               location_t where = get_finish (t2->location);
   15461                 :           0 :               warning_at (token1->location, OPT_Wattributes, "attributes are"
   15462                 :             :                           " not permitted in this position");
   15463                 :           0 :               where = linemap_position_for_loc_and_offset (line_table,
   15464                 :             :                                                            where, 1);
   15465                 :           0 :               inform (where, "attributes may be inserted here");
   15466                 :           0 :               attributes = NULL_TREE;
   15467                 :             :             }
   15468                 :             :           token1 = t1;
   15469                 :             :           token2 = t2;
   15470                 :             :         }
   15471                 :             :       else
   15472                 :             :         {
   15473                 :      337683 :           cp_lexer_rollback_tokens (parser->lexer);
   15474                 :      337683 :           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                 :   122400226 :   if (prefix_attrs)
   15480                 :             :     {
   15481                 :           0 :       if (attributes)
   15482                 :           0 :         TREE_CHAIN (prefix_attrs) = attributes;
   15483                 :           0 :       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                 :   122400226 :   if (token1->keyword == RID_EXTERN
   15489                 :   122400226 :       && cp_parser_is_pure_string_literal (token2))
   15490                 :     1035902 :     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                 :   121364324 :   else if (token1->keyword == RID_TEMPLATE)
   15495                 :             :     {
   15496                 :             :       /* `template <>' indicates a template specialization.  */
   15497                 :    57912573 :       if (token2->type == CPP_LESS
   15498                 :    57912573 :           && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER)
   15499                 :     4740145 :         cp_parser_explicit_specialization (parser);
   15500                 :             :       /* `template <' indicates a template declaration.  */
   15501                 :    53172428 :       else if (token2->type == CPP_LESS)
   15502                 :    53166567 :         cp_parser_template_declaration (parser, /*member_p=*/false);
   15503                 :             :       /* Anything else must be an explicit instantiation.  */
   15504                 :             :       else
   15505                 :        5861 :         cp_parser_explicit_instantiation (parser);
   15506                 :             :     }
   15507                 :             :   /* If the next token is `export', it's new-style modules or
   15508                 :             :      old-style template.  */
   15509                 :    63451751 :   else if (token1->keyword == RID_EXPORT)
   15510                 :             :     {
   15511                 :        1474 :       if (!modules_p ())
   15512                 :          26 :         cp_parser_template_declaration (parser, /*member_p=*/false);
   15513                 :             :       else
   15514                 :        1448 :         cp_parser_module_export (parser);
   15515                 :             :     }
   15516                 :    63450277 :   else if (cp_token_is_module_directive (token1))
   15517                 :             :     {
   15518                 :          24 :       bool exporting = token1->keyword == RID__EXPORT;
   15519                 :          24 :       cp_token *next = exporting ? token2 : token1;
   15520                 :           0 :       if (exporting)
   15521                 :           0 :         cp_lexer_consume_token (parser->lexer);
   15522                 :             :       // In module purview this will be ill-formed.
   15523                 :          24 :       auto state = (!named_module_p () ? MP_NOT_MODULE
   15524                 :           6 :                     : module_purview_p () ? MP_PURVIEW
   15525                 :          24 :                     : MP_GLOBAL);
   15526                 :          24 :       if (next->keyword == RID__MODULE)
   15527                 :           3 :         cp_parser_module_declaration (parser, state, exporting);
   15528                 :             :       else
   15529                 :          21 :         cp_parser_import_declaration (parser, 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                 :    63450253 :   else if (cp_parser_allow_gnu_extensions_p (parser)
   15535                 :    63450253 :            && token2->keyword == RID_TEMPLATE
   15536                 :    63450253 :            && (token1->keyword == RID_EXTERN
   15537                 :             :                || token1->keyword == RID_STATIC
   15538                 :             :                || token1->keyword == RID_INLINE))
   15539                 :     2678495 :     cp_parser_explicit_instantiation (parser);
   15540                 :             :   /* If the next token is `namespace', check for a named or unnamed
   15541                 :             :      namespace definition.  */
   15542                 :    60771758 :   else if (token1->keyword == RID_NAMESPACE
   15543                 :    60771758 :            && (/* A named namespace definition.  */
   15544                 :     4669687 :                (token2->type == CPP_NAME
   15545                 :     4667851 :                 && (cp_lexer_peek_nth_token (parser->lexer, 3)->type
   15546                 :             :                     != CPP_EQ))
   15547                 :        6588 :                || (token2->type == CPP_OPEN_SQUARE
   15548                 :          57 :                    && cp_lexer_peek_nth_token (parser->lexer, 3)->type
   15549                 :             :                    == CPP_OPEN_SQUARE)
   15550                 :             :                /* An unnamed namespace definition.  */
   15551                 :        6531 :                || token2->type == CPP_OPEN_BRACE
   15552                 :        4771 :                || token2->keyword == RID_ATTRIBUTE))
   15553                 :     4664926 :     cp_parser_namespace_definition (parser);
   15554                 :             :   /* An inline (associated) namespace definition.  */
   15555                 :    56106832 :   else if (token2->keyword == RID_NAMESPACE
   15556                 :      237307 :            && token1->keyword == RID_INLINE)
   15557                 :      207858 :     cp_parser_namespace_definition (parser);
   15558                 :             :   /* Objective-C++ declaration/definition.  */
   15559                 :    55898974 :   else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1->keyword))
   15560                 :           0 :     cp_parser_objc_declaration (parser, attributes);
   15561                 :    55898974 :   else if (c_dialect_objc ()
   15562                 :           0 :            && token1->keyword == RID_ATTRIBUTE
   15563                 :    55898974 :            && cp_parser_objc_valid_prefix_attributes (parser, &attributes))
   15564                 :           0 :     cp_parser_objc_declaration (parser, attributes);
   15565                 :             :   /* At this point we may have a template declared by a concept
   15566                 :             :      introduction.  */
   15567                 :    55898974 :   else if (flag_concepts
   15568                 :    55898974 :            && 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                 :    55898937 :     cp_parser_block_declaration (parser, /*statement_p=*/false);
   15574                 :             : 
   15575                 :             :   /* Free any declarators allocated.  */
   15576                 :   122400154 :   obstack_free (&declarator_obstack, p);
   15577                 :             : }
   15578                 :             : 
   15579                 :             : /* Parse a namespace-scope declaration.  */
   15580                 :             : 
   15581                 :             : static void
   15582                 :   123565093 : cp_parser_toplevel_declaration (cp_parser* parser)
   15583                 :             : {
   15584                 :   123565093 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   15585                 :             : 
   15586                 :   123565093 :   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                 :     1418386 :     cp_parser_pragma (parser, pragma_external, NULL);
   15592                 :             :   else
   15593                 :             :     /* Parse the declaration itself.  */
   15594                 :   122146707 :     cp_parser_declaration (parser, NULL_TREE);
   15595                 :   123565021 : }
   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                 :             : 
   15619                 :             : static void
   15620                 :   194647648 : cp_parser_block_declaration (cp_parser *parser,
   15621                 :             :                              bool      statement_p)
   15622                 :             : {
   15623                 :   194647648 :   int saved_pedantic;
   15624                 :             : 
   15625                 :             :   /* Check for the `__extension__' keyword.  */
   15626                 :   194647648 :   if (cp_parser_extension_opt (parser, &saved_pedantic))
   15627                 :             :     {
   15628                 :             :       /* Parse the qualified declaration.  */
   15629                 :          74 :       cp_parser_block_declaration (parser, statement_p);
   15630                 :             :       /* Restore the PEDANTIC flag.  */
   15631                 :          74 :       pedantic = saved_pedantic;
   15632                 :             : 
   15633                 :          74 :       return;
   15634                 :             :     }
   15635                 :             : 
   15636                 :             :   /* Peek at the next token to figure out which kind of declaration is
   15637                 :             :      present.  */
   15638                 :   194647574 :   cp_token *token1 = cp_lexer_peek_token (parser->lexer);
   15639                 :             : 
   15640                 :             :   /* If the next keyword is `asm', we have an asm-definition.  */
   15641                 :   194647574 :   if (token1->keyword == RID_ASM)
   15642                 :             :     {
   15643                 :       29736 :       if (statement_p)
   15644                 :       16793 :         cp_parser_commit_to_tentative_parse (parser);
   15645                 :       29736 :       cp_parser_asm_definition (parser);
   15646                 :             :     }
   15647                 :             :   /* If the next keyword is `namespace', we have a
   15648                 :             :      namespace-alias-definition.  */
   15649                 :   194617838 :   else if (token1->keyword == RID_NAMESPACE)
   15650                 :       45626 :     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                 :   194572212 :   else if (token1->keyword == RID_USING)
   15654                 :             :     {
   15655                 :     9526354 :       cp_token *token2;
   15656                 :             : 
   15657                 :     9526354 :       if (statement_p)
   15658                 :     3335285 :         cp_parser_commit_to_tentative_parse (parser);
   15659                 :             :       /* If the token after `using' is `namespace', then we have a
   15660                 :             :          using-directive.  */
   15661                 :     9526354 :       token2 = cp_lexer_peek_nth_token (parser->lexer, 2);
   15662                 :     9526354 :       if (token2->keyword == RID_NAMESPACE)
   15663                 :       94634 :         cp_parser_using_directive (parser);
   15664                 :     9431720 :       else if (token2->keyword == RID_ENUM)
   15665                 :       12441 :         cp_parser_using_enum (parser);
   15666                 :             :       /* If the second token after 'using' is '=', then we have an
   15667                 :             :          alias-declaration.  */
   15668                 :     9419279 :       else if (cxx_dialect >= cxx11
   15669                 :     9359125 :                && token2->type == CPP_NAME
   15670                 :    13635710 :                && ((cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ)
   15671                 :      868857 :                    || (cp_nth_tokens_can_be_attribute_p (parser, 3))))
   15672                 :     3347606 :         cp_parser_alias_declaration (parser);
   15673                 :             :       /* Otherwise, it's a using-declaration.  */
   15674                 :             :       else
   15675                 :     6071673 :         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                 :   185045858 :   else if (token1->keyword == RID_LABEL)
   15681                 :             :     {
   15682                 :          24 :       cp_lexer_consume_token (parser->lexer);
   15683                 :          24 :       error_at (token1->location, "%<__label__%> not at the beginning of a block");
   15684                 :          24 :       cp_parser_skip_to_end_of_statement (parser);
   15685                 :             :       /* If the next token is now a `;', consume it.  */
   15686                 :          24 :       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   15687                 :          24 :         cp_lexer_consume_token (parser->lexer);
   15688                 :             :     }
   15689                 :             :   /* If the next token is `static_assert' we have a static assertion.  */
   15690                 :   185045834 :   else if (token1->keyword == RID_STATIC_ASSERT)
   15691                 :     1575159 :     cp_parser_static_assert (parser, /*member_p=*/false);
   15692                 :             :   else
   15693                 :             :     {
   15694                 :   183470675 :       size_t attr_idx = cp_parser_skip_std_attribute_spec_seq (parser, 1);
   15695                 :   183470675 :       cp_token *after_attr = NULL;
   15696                 :   183470675 :       if (attr_idx != 1)
   15697                 :     1871450 :         after_attr = cp_lexer_peek_nth_token (parser->lexer, attr_idx);
   15698                 :             :       /* If the next tokens after attributes is `using namespace', then we have
   15699                 :             :          a using-directive.  */
   15700                 :     1871450 :       if (after_attr
   15701                 :     1871450 :           && after_attr->keyword == RID_USING
   15702                 :     1871489 :           && cp_lexer_nth_token_is_keyword (parser->lexer, attr_idx + 1,
   15703                 :             :                                             RID_NAMESPACE))
   15704                 :             :         {
   15705                 :          30 :           if (statement_p)
   15706                 :          18 :             cp_parser_commit_to_tentative_parse (parser);
   15707                 :          30 :           cp_parser_using_directive (parser);
   15708                 :             :         }
   15709                 :             :       /* If the next token after attributes is `asm', then we have
   15710                 :             :          an asm-definition.  */
   15711                 :   183470645 :       else if (after_attr && after_attr->keyword == RID_ASM)
   15712                 :             :         {
   15713                 :          45 :           if (statement_p)
   15714                 :          39 :             cp_parser_commit_to_tentative_parse (parser);
   15715                 :          45 :           cp_parser_asm_definition (parser);
   15716                 :             :         }
   15717                 :             :       /* Anything else must be a simple-declaration.  */
   15718                 :             :       else
   15719                 :   183470600 :         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                 :             : 
   15743                 :             : static void
   15744                 :   187349915 : cp_parser_simple_declaration (cp_parser* parser,
   15745                 :             :                               bool function_definition_allowed_p,
   15746                 :             :                               tree *maybe_range_for_decl)
   15747                 :             : {
   15748                 :   187349915 :   cp_decl_specifier_seq decl_specifiers;
   15749                 :   187349915 :   int declares_class_or_enum;
   15750                 :   187349915 :   bool saw_declarator;
   15751                 :   187349915 :   location_t comma_loc = UNKNOWN_LOCATION;
   15752                 :   187349915 :   location_t init_loc = UNKNOWN_LOCATION;
   15753                 :             : 
   15754                 :   187349915 :   if (maybe_range_for_decl)
   15755                 :     3879315 :     *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                 :   187349915 :   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                 :   187349915 :   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                 :   187349894 :   stop_deferring_access_checks ();
   15779                 :             : 
   15780                 :   187349894 :   cp_omp_declare_simd_data odsd;
   15781                 :   187349894 :   if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
   15782                 :       10269 :     cp_parser_handle_directive_omp_attributes (parser,
   15783                 :             :                                                &decl_specifiers.attributes,
   15784                 :             :                                                &odsd, 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                 :   187349894 :   if (!function_definition_allowed_p
   15790                 :   137686428 :       && !decl_specifiers.any_specifiers_p)
   15791                 :             :     {
   15792                 :    85311247 :       cp_parser_error (parser, "expected declaration");
   15793                 :    85311247 :       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                 :   102038647 :   if (!decl_specifiers.any_type_specifiers_p
   15803                 :   102038647 :       && 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                 :         372 :       cp_parser_commit_to_tentative_parse (parser);
   15808                 :             :       /* Give up.  */
   15809                 :         372 :       goto done;
   15810                 :             :     }
   15811                 :             : 
   15812                 :   102038275 :   cp_parser_maybe_commit_to_declaration (parser, &decl_specifiers);
   15813                 :             : 
   15814                 :             :   /* Look for C++17 decomposition declaration.  */
   15815                 :   102038275 :   for (size_t n = 1; ; n++)
   15816                 :   104646868 :     if (cp_lexer_nth_token_is (parser->lexer, n, CPP_AND)
   15817                 :   104646868 :         || cp_lexer_nth_token_is (parser->lexer, n, CPP_AND_AND))
   15818                 :     2608593 :       continue;
   15819                 :   102038275 :     else if (cp_lexer_nth_token_is (parser->lexer, n, CPP_OPEN_SQUARE)
   15820                 :       55799 :              && !cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_SQUARE)
   15821                 :   102094070 :              && decl_specifiers.any_specifiers_p)
   15822                 :             :       {
   15823                 :       55795 :         tree decl
   15824                 :       55795 :           = 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                 :       55795 :         cp_token *token = cp_lexer_peek_token (parser->lexer);
   15830                 :             :         /* If it's a `;', we are done.  */
   15831                 :       55795 :         if (token->type == CPP_SEMICOLON)
   15832                 :       55653 :           goto finish;
   15833                 :         142 :         else if (maybe_range_for_decl)
   15834                 :             :           {
   15835                 :         134 :             if (*maybe_range_for_decl == NULL_TREE)
   15836                 :           3 :               *maybe_range_for_decl = error_mark_node;
   15837                 :         134 :             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                 :           8 :             if ((decl != error_mark_node
   15845                 :           8 :                  && DECL_INITIAL (decl) != error_mark_node)
   15846                 :           8 :                 || cp_parser_uncommitted_to_tentative_parse_p (parser))
   15847                 :           8 :               cp_parser_error (parser, "expected %<;%>");
   15848                 :             :             /* Skip tokens until we reach the end of the statement.  */
   15849                 :           8 :             cp_parser_skip_to_end_of_statement (parser);
   15850                 :             :             /* If the next token is now a `;', consume it.  */
   15851                 :           8 :             if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   15852                 :           8 :               cp_lexer_consume_token (parser->lexer);
   15853                 :           8 :             goto done;
   15854                 :             :           }
   15855                 :             :       }
   15856                 :             :     else
   15857                 :     2608593 :       break;
   15858                 :             : 
   15859                 :   101982480 :   tree last_type;
   15860                 :   101982480 :   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                 :   101982480 :   tree auto_function_declaration;
   15866                 :             : 
   15867                 :   101982480 :   last_type = NULL_TREE;
   15868                 :   101982480 :   auto_specifier_p
   15869                 :   101982480 :     = decl_specifiers.type && type_uses_auto (decl_specifiers.type);
   15870                 :   101982480 :   auto_function_declaration = NULL_TREE;
   15871                 :             : 
   15872                 :             :   /* Keep going until we hit the `;' at the end of the simple
   15873                 :             :      declaration.  */
   15874                 :   101982480 :   saw_declarator = false;
   15875                 :   103170900 :   while (cp_lexer_next_token_is_not (parser->lexer,
   15876                 :             :                                      CPP_SEMICOLON))
   15877                 :             :     {
   15878                 :    98271189 :       cp_token *token;
   15879                 :    98271189 :       bool function_definition_p;
   15880                 :    98271189 :       tree decl;
   15881                 :    98271189 :       tree auto_result = NULL_TREE;
   15882                 :             : 
   15883                 :    98271189 :       if (saw_declarator)
   15884                 :             :         {
   15885                 :             :           /* If we are processing next declarator, comma is expected */
   15886                 :     1188420 :           token = cp_lexer_peek_token (parser->lexer);
   15887                 :     1188420 :           gcc_assert (token->type == CPP_COMMA);
   15888                 :     1188420 :           cp_lexer_consume_token (parser->lexer);
   15889                 :     1188420 :           if (maybe_range_for_decl)
   15890                 :             :             {
   15891                 :       48823 :               *maybe_range_for_decl = error_mark_node;
   15892                 :       48823 :               if (comma_loc == UNKNOWN_LOCATION)
   15893                 :       48800 :                 comma_loc = token->location;
   15894                 :             :             }
   15895                 :             :         }
   15896                 :             :       else
   15897                 :             :         saw_declarator = true;
   15898                 :             : 
   15899                 :             :       /* Parse the init-declarator.  */
   15900                 :    98271189 :       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                 :    98271157 :       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                 :   196542314 :       if (cp_parser_error_occurred (parser))
   15917                 :      324603 :         goto done;
   15918                 :             : 
   15919                 :    97947674 :       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                 :     5730104 :           if (auto_function_declaration == NULL_TREE)
   15925                 :     5675965 :             auto_function_declaration = fndecl_p ? decl : error_mark_node;
   15926                 :       54139 :           else if (fndecl_p || auto_function_declaration != error_mark_node)
   15927                 :             :             {
   15928                 :          12 :               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                 :          12 :               auto_function_declaration = error_mark_node;
   15933                 :             :             }
   15934                 :             :         }
   15935                 :             : 
   15936                 :    97947674 :       if (auto_result
   15937                 :    97947674 :           && (!processing_template_decl || !type_uses_auto (auto_result)))
   15938                 :             :         {
   15939                 :      849746 :           if (last_type
   15940                 :        5216 :               && last_type != error_mark_node
   15941                 :      854962 :               && !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                 :           3 :               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                 :           3 :               last_type = error_mark_node;
   15951                 :             :             }
   15952                 :             :           else
   15953                 :             :             last_type = auto_result;
   15954                 :             :         }
   15955                 :             : 
   15956                 :             :       /* Handle function definitions specially.  */
   15957                 :    97947674 :       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                 :     9477167 :           if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   15966                 :             :             {
   15967                 :           0 :               cp_token *token = cp_lexer_peek_token (parser->lexer);
   15968                 :           0 :               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                 :     9477167 :               pop_deferring_access_checks ();
   15976                 :     9477167 :               cp_finalize_omp_declare_simd (parser, &odsd);
   15977                 :     9477167 :               return;
   15978                 :             :             }
   15979                 :             :         }
   15980                 :    88470507 :       if (maybe_range_for_decl && *maybe_range_for_decl == NULL_TREE)
   15981                 :      189351 :         *maybe_range_for_decl = decl;
   15982                 :             :       /* The next token should be either a `,' or a `;'.  */
   15983                 :    88470507 :       token = cp_lexer_peek_token (parser->lexer);
   15984                 :             :       /* If it's a `,', there are more declarators to come.  */
   15985                 :    88470507 :       if (token->type == CPP_COMMA)
   15986                 :             :         /* will be consumed next time around */;
   15987                 :             :       /* If it's a `;', we are done.  */
   15988                 :    87282087 :       else if (token->type == CPP_SEMICOLON)
   15989                 :             :         break;
   15990                 :      190207 :       else if (maybe_range_for_decl)
   15991                 :             :         {
   15992                 :      189087 :           if ((declares_class_or_enum & 2) && token->type == CPP_COLON)
   15993                 :           9 :             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                 :        1120 :           if ((decl != error_mark_node
   16003                 :             :                /* grokfndecl sets DECL_INITIAL to error_mark_node for
   16004                 :             :                   functions.  */
   16005                 :         116 :                && (fndecl_p || DECL_INITIAL (decl) != error_mark_node))
   16006                 :        1120 :               || cp_parser_uncommitted_to_tentative_parse_p (parser))
   16007                 :         104 :             cp_parser_error (parser, "expected %<,%> or %<;%>");
   16008                 :             :           /* Skip tokens until we reach the end of the statement.  */
   16009                 :        1120 :           cp_parser_skip_to_end_of_statement (parser);
   16010                 :             :           /* If the next token is now a `;', consume it.  */
   16011                 :        1120 :           if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   16012                 :         772 :             cp_lexer_consume_token (parser->lexer);
   16013                 :        1120 :           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                 :     1188420 :       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                 :    92180678 :   if (!saw_declarator)
   16028                 :             :     {
   16029                 :    14699133 :       if (cp_parser_declares_only_class_p (parser))
   16030                 :             :         {
   16031                 :     4899711 :           if (!declares_class_or_enum
   16032                 :         138 :               && decl_specifiers.type
   16033                 :     4899842 :               && 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                 :           6 :             decl_specifiers.type = NULL_TREE;
   16038                 :     4899711 :           shadow_tag (&decl_specifiers);
   16039                 :             :         }
   16040                 :             :       /* Perform any deferred access checks.  */
   16041                 :     4899711 :       perform_deferred_access_checks (tf_warning_or_error);
   16042                 :             :     }
   16043                 :             : 
   16044                 :             :   /* Consume the `;'.  */
   16045                 :    92236465 :  finish:
   16046                 :    92236465 :   if (!maybe_range_for_decl)
   16047                 :    88669641 :     cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   16048                 :     3566824 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   16049                 :             :     {
   16050                 :      189218 :       if (init_loc != UNKNOWN_LOCATION)
   16051                 :           8 :         error_at (init_loc, "initializer in range-based %<for%> loop");
   16052                 :      189218 :       if (comma_loc != UNKNOWN_LOCATION)
   16053                 :           6 :         error_at (comma_loc,
   16054                 :             :                   "multiple declarations in range-based %<for%> loop");
   16055                 :             :     }
   16056                 :             : 
   16057                 :     3377606 :  done:
   16058                 :   177872695 :   pop_deferring_access_checks ();
   16059                 :   177872695 :   cp_finalize_omp_declare_simd (parser, &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                 :             : 
   16066                 :             : static tree
   16067                 :       55795 : cp_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                 :       55795 :   cp_ref_qualifier ref_qual = cp_parser_ref_qualifier_opt (parser);
   16073                 :       55795 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   16074                 :       55795 :   cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
   16075                 :             : 
   16076                 :             :   /* Parse the identifier-list.  */
   16077                 :       55795 :   auto_vec<cp_expr, 10> v;
   16078                 :       55795 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
   16079                 :      168028 :     while (true)
   16080                 :             :       {
   16081                 :      111911 :         cp_expr e = cp_parser_identifier (parser);
   16082                 :      111911 :         if (e.get_value () == error_mark_node)
   16083                 :             :           break;
   16084                 :      111905 :         v.safe_push (e);
   16085                 :      111905 :         if (!cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   16086                 :             :           break;
   16087                 :       56117 :         cp_lexer_consume_token (parser->lexer);
   16088                 :       56117 :       }
   16089                 :             : 
   16090                 :       55795 :   location_t end_loc = cp_lexer_peek_token (parser->lexer)->location;
   16091                 :       55795 :   if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
   16092                 :             :     {
   16093                 :           9 :       end_loc = UNKNOWN_LOCATION;
   16094                 :           9 :       cp_parser_skip_to_closing_parenthesis_1 (parser, true, CPP_CLOSE_SQUARE,
   16095                 :             :                                                false);
   16096                 :           9 :       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
   16097                 :           0 :         cp_lexer_consume_token (parser->lexer);
   16098                 :             :       else
   16099                 :             :         {
   16100                 :           9 :           cp_parser_skip_to_end_of_statement (parser);
   16101                 :           9 :           return error_mark_node;
   16102                 :             :         }
   16103                 :             :     }
   16104                 :             : 
   16105                 :       55786 :   if (cxx_dialect < cxx17)
   16106                 :         158 :     pedwarn (loc, OPT_Wc__17_extensions,
   16107                 :             :              "structured bindings only available with "
   16108                 :             :              "%<-std=c++17%> or %<-std=gnu++17%>");
   16109                 :             : 
   16110                 :       55786 :   tree pushed_scope;
   16111                 :       55786 :   cp_declarator *declarator = make_declarator (cdk_decomp);
   16112                 :       55786 :   loc = end_loc == UNKNOWN_LOCATION ? loc : make_location (loc, loc, end_loc);
   16113                 :       55786 :   declarator->id_loc = loc;
   16114                 :       55786 :   if (ref_qual != REF_QUAL_NONE)
   16115                 :        9374 :     declarator = make_reference_declarator (TYPE_UNQUALIFIED, declarator,
   16116                 :             :                                             ref_qual == REF_QUAL_RVALUE,
   16117                 :             :                                             NULL_TREE);
   16118                 :       55786 :   tree decl = start_decl (declarator, decl_specifiers, SD_INITIALIZED,
   16119                 :             :                           NULL_TREE, decl_specifiers->attributes,
   16120                 :             :                           &pushed_scope);
   16121                 :       55786 :   tree orig_decl = decl;
   16122                 :             : 
   16123                 :       55786 :   unsigned int i;
   16124                 :       55786 :   cp_expr e;
   16125                 :       55786 :   cp_decl_specifier_seq decl_specs;
   16126                 :       55786 :   clear_decl_specs (&decl_specs);
   16127                 :       55786 :   decl_specs.type = make_auto ();
   16128                 :       55786 :   if (decl_specifiers->storage_class == sc_static)
   16129                 :          86 :     decl_specs.storage_class = sc_static;
   16130                 :             :   tree prev = decl;
   16131                 :      167688 :   FOR_EACH_VEC_ELT (v, i, e)
   16132                 :             :     {
   16133                 :      111902 :       if (i == 0)
   16134                 :       55785 :         declarator = make_id_declarator (NULL_TREE, e.get_value (),
   16135                 :             :                                          sfk_none, e.get_location ());
   16136                 :             :       else
   16137                 :             :         {
   16138                 :       56117 :           declarator->u.id.unqualified_name = e.get_value ();
   16139                 :       56117 :           declarator->id_loc = e.get_location ();
   16140                 :             :         }
   16141                 :      111902 :       tree elt_pushed_scope;
   16142                 :      111902 :       tree decl2 = start_decl (declarator, &decl_specs, SD_DECOMPOSITION,
   16143                 :             :                                NULL_TREE, NULL_TREE, &elt_pushed_scope);
   16144                 :      111902 :       if (decl2 == error_mark_node)
   16145                 :             :         decl = error_mark_node;
   16146                 :      111891 :       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                 :           0 :           gcc_assert (errorcount);
   16151                 :             :           decl = error_mark_node;
   16152                 :             :         }
   16153                 :             :       else
   16154                 :             :         prev = decl2;
   16155                 :      111902 :       if (elt_pushed_scope)
   16156                 :         112 :         pop_scope (elt_pushed_scope);
   16157                 :             :     }
   16158                 :             : 
   16159                 :       55786 :   if (v.is_empty ())
   16160                 :             :     {
   16161                 :           1 :       error_at (loc, "empty structured binding declaration");
   16162                 :           1 :       decl = error_mark_node;
   16163                 :             :     }
   16164                 :             : 
   16165                 :       55786 :   if (maybe_range_for_decl == NULL
   16166                 :       55786 :       || cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
   16167                 :             :     {
   16168                 :       55655 :       bool non_constant_p = false, is_direct_init = false;
   16169                 :       55655 :       *init_loc = cp_lexer_peek_token (parser->lexer)->location;
   16170                 :       55655 :       tree initializer = cp_parser_initializer (parser, &is_direct_init,
   16171                 :             :                                                 &non_constant_p);
   16172                 :       55655 :       if (initializer == NULL_TREE
   16173                 :       55653 :           || (TREE_CODE (initializer) == TREE_LIST
   16174                 :          19 :               && TREE_CHAIN (initializer))
   16175                 :      111304 :           || (is_direct_init
   16176                 :          53 :               && BRACE_ENCLOSED_INITIALIZER_P (initializer)
   16177                 :          38 :               && CONSTRUCTOR_NELTS (initializer) != 1))
   16178                 :             :         {
   16179                 :          10 :           error_at (loc, "invalid initializer for structured binding "
   16180                 :             :                     "declaration");
   16181                 :          10 :           initializer = error_mark_node;
   16182                 :             :         }
   16183                 :             : 
   16184                 :       55655 :       if (decl != error_mark_node)
   16185                 :             :         {
   16186                 :       55646 :           cp_decomp decomp = { prev, v.length () };
   16187                 :      111234 :           cp_finish_decl (decl, initializer, non_constant_p, NULL_TREE,
   16188                 :             :                           (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT),
   16189                 :             :                           &decomp);
   16190                 :       55646 :           cp_finish_decomp (decl, &decomp);
   16191                 :             :         }
   16192                 :             :     }
   16193                 :         131 :   else if (decl != error_mark_node)
   16194                 :             :     {
   16195                 :         131 :       *maybe_range_for_decl = prev;
   16196                 :         131 :       cp_decomp decomp = { prev, v.length () };
   16197                 :             :       /* Ensure DECL_VALUE_EXPR is created for all the decls but
   16198                 :             :          the underlying DECL.  */
   16199                 :         131 :       cp_finish_decomp (decl, &decomp);
   16200                 :             :     }
   16201                 :             : 
   16202                 :       55786 :   if (pushed_scope)
   16203                 :          37 :     pop_scope (pushed_scope);
   16204                 :             : 
   16205                 :       55786 :   if (decl == error_mark_node && DECL_P (orig_decl))
   16206                 :             :     {
   16207                 :           9 :       if (DECL_NAMESPACE_SCOPE_P (orig_decl))
   16208                 :           3 :         SET_DECL_ASSEMBLER_NAME (orig_decl, get_identifier ("<decomp>"));
   16209                 :             :     }
   16210                 :             : 
   16211                 :             :   return decl;
   16212                 :       55795 : }
   16213                 :             : 
   16214                 :             : /* Names of storage classes.  */
   16215                 :             : 
   16216                 :             : static const char *const
   16217                 :             : cp_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                 :             : 
   16258                 :             : static void
   16259                 :   681843804 : cp_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                 :   681843804 :   bool constructor_possible_p = !parser->in_declarator_p;
   16265                 :   681843804 :   bool found_decl_spec = false;
   16266                 :   681843804 :   cp_token *start_token = NULL;
   16267                 :   681843804 :   cp_decl_spec ds;
   16268                 :             : 
   16269                 :             :   /* Clear DECL_SPECS.  */
   16270                 :   681843804 :   clear_decl_specs (decl_specs);
   16271                 :             : 
   16272                 :             :   /* Assume no class or enumeration type is declared.  */
   16273                 :   681843804 :   *declares_class_or_enum = 0;
   16274                 :             : 
   16275                 :             :   /* Keep a token that additionally will be used for diagnostics.  */
   16276                 :   681843804 :   cp_token *first_specifier = NULL;
   16277                 :             :   /* Keep reading specifiers until there are no more to read.  */
   16278                 :  1525551573 :   while (true)
   16279                 :             :     {
   16280                 :  1525551573 :       bool constructor_p;
   16281                 :  1525551573 :       cp_token *token;
   16282                 :  1525551573 :       ds = ds_last;
   16283                 :             : 
   16284                 :             :       /* Peek at the next token.  */
   16285                 :  1525551573 :       token = cp_lexer_peek_token (parser->lexer);
   16286                 :             : 
   16287                 :             :       /* Save the first token of the decl spec list for error
   16288                 :             :          reporting.  */
   16289                 :  1525551573 :       if (!start_token)
   16290                 :             :         start_token = token;
   16291                 :             :       /* Handle attributes.  */
   16292                 :  1525551573 :       if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) == 0
   16293                 :  1525551573 :           && cp_next_tokens_can_be_attribute_p (parser))
   16294                 :             :         {
   16295                 :             :           /* Parse the attributes.  */
   16296                 :    14170393 :           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                 :    14170393 :           if (cxx11_attribute_p (attrs))
   16311                 :             :             {
   16312                 :    10299531 :               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                 :          48 :                   if (find_contract (attrs))
   16319                 :             :                     {
   16320                 :           3 :                       diagnose_misapplied_contracts (attrs);
   16321                 :           3 :                       attrs = NULL_TREE;
   16322                 :             :                     }
   16323                 :          45 :                   else if (decl_specs->type && CLASS_TYPE_P (decl_specs->type))
   16324                 :             :                     {
   16325                 :             :                       /*  This is an attribute following a
   16326                 :             :                           class-specifier.  */
   16327                 :           6 :                       if (decl_specs->type_definition_p)
   16328                 :           6 :                         warn_misplaced_attr_for_class_type (token->location,
   16329                 :             :                                                             decl_specs->type);
   16330                 :          48 :                       attrs = NULL_TREE;
   16331                 :             :                     }
   16332                 :             :                   else
   16333                 :             :                     {
   16334                 :          39 :                       decl_specs->std_attributes
   16335                 :          39 :                         = attr_chainon (decl_specs->std_attributes, attrs);
   16336                 :          39 :                       if (decl_specs->locations[ds_std_attribute] == 0)
   16337                 :          39 :                         decl_specs->locations[ds_std_attribute] = token->location;
   16338                 :             :                     }
   16339                 :          48 :                   continue;
   16340                 :             :                 }
   16341                 :             :             }
   16342                 :             : 
   16343                 :    14170345 :           decl_specs->attributes
   16344                 :    14170345 :             = attr_chainon (decl_specs->attributes, attrs);
   16345                 :    14170345 :           if (decl_specs->locations[ds_attribute] == 0)
   16346                 :    14057383 :             decl_specs->locations[ds_attribute] = token->location;
   16347                 :    14170345 :           continue;
   16348                 :    14170345 :         }
   16349                 :             :       /* We know by this point that the token is not part of an attribute.  */
   16350                 :  1511381180 :       if (!first_specifier)
   16351                 :   681843804 :         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                 :  1511381180 :       if (token->keyword == RID_THIS && (flags & CP_PARSER_FLAGS_PARAMETER))
   16356                 :             :         {
   16357                 :      175519 :           cp_lexer_consume_token (parser->lexer);
   16358                 :      175519 :           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                 :           0 :               if (decl_specs->locations[ds_this] == 0)
   16363                 :             :                 {
   16364                 :           0 :                   auto_diagnostic_group d;
   16365                 :           0 :                   gcc_rich_location richloc (token->location);
   16366                 :             :                   /* Works, need to add tests for it though.  */
   16367                 :           0 :                   richloc.add_fixit_remove ();
   16368                 :           0 :                   richloc.add_fixit_insert_before (first_specifier->location,
   16369                 :             :                                                    "this ");
   16370                 :           0 :                   error_at (&richloc,
   16371                 :             :                             "%<this%> must be the first specifier "
   16372                 :             :                             "in a parameter declaration");
   16373                 :           0 :                 }
   16374                 :             :             }
   16375                 :      175519 :           set_and_check_decl_spec_loc (decl_specs, ds_this, token);
   16376                 :      175519 :           continue;
   16377                 :      175519 :         }
   16378                 :             : 
   16379                 :             :       /* Assume we will find a decl-specifier keyword.  */
   16380                 :  1511205661 :       found_decl_spec = true;
   16381                 :             :       /* If the next token is an appropriate keyword, we can simply
   16382                 :             :          add it to the list.  */
   16383                 :  1511205661 :       switch (token->keyword)
   16384                 :             :         {
   16385                 :             :           /* decl-specifier:
   16386                 :             :                friend
   16387                 :             :                constexpr
   16388                 :             :                constinit */
   16389                 :     4764289 :         case RID_FRIEND:
   16390                 :     4764289 :           if (!at_class_scope_p ())
   16391                 :             :             {
   16392                 :          20 :               gcc_rich_location richloc (token->location);
   16393                 :          20 :               richloc.add_fixit_remove ();
   16394                 :          20 :               error_at (&richloc, "%<friend%> used outside of class");
   16395                 :          20 :               cp_lexer_purge_token (parser->lexer);
   16396                 :          20 :             }
   16397                 :             :           else
   16398                 :             :             {
   16399                 :     4764269 :               ds = ds_friend;
   16400                 :             :               /* Consume the token.  */
   16401                 :     4764269 :               cp_lexer_consume_token (parser->lexer);
   16402                 :             :             }
   16403                 :             :           break;
   16404                 :             : 
   16405                 :    37667373 :         case RID_CONSTEXPR:
   16406                 :    37667373 :           ds = ds_constexpr;
   16407                 :    37667373 :           cp_lexer_consume_token (parser->lexer);
   16408                 :    37667373 :           break;
   16409                 :             : 
   16410                 :         173 :         case RID_CONSTINIT:
   16411                 :         173 :           ds = ds_constinit;
   16412                 :         173 :           cp_lexer_consume_token (parser->lexer);
   16413                 :         173 :           break;
   16414                 :             : 
   16415                 :       62183 :         case RID_CONSTEVAL:
   16416                 :       62183 :           ds = ds_consteval;
   16417                 :       62183 :           cp_lexer_consume_token (parser->lexer);
   16418                 :       62183 :           break;
   16419                 :             : 
   16420                 :         285 :         case RID_CONCEPT:
   16421                 :         285 :           ds = ds_concept;
   16422                 :         285 :           cp_lexer_consume_token (parser->lexer);
   16423                 :             : 
   16424                 :         285 :           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                 :         284 :           if (!flag_concepts_ts)
   16430                 :             :             {
   16431                 :          14 :               cp_token *next = cp_lexer_peek_token (parser->lexer);
   16432                 :          14 :               if (next->keyword == RID_BOOL)
   16433                 :           1 :                 permerror (next->location, "the %<bool%> keyword is not "
   16434                 :             :                            "allowed in a C++20 concept definition");
   16435                 :             :               else
   16436                 :          13 :                 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                 :         284 :           if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   16444                 :          11 :               && cp_lexer_nth_token_is (parser->lexer, 2, CPP_EQ)
   16445                 :         292 :               && !decl_specs->any_type_specifiers_p)
   16446                 :             :             {
   16447                 :           7 :               cp_parser_set_decl_spec_type (decl_specs, boolean_type_node,
   16448                 :             :                                             token, /*type_definition*/false);
   16449                 :           7 :               decl_specs->any_type_specifiers_p = true;
   16450                 :             :             }
   16451                 :             :           break;
   16452                 :             : 
   16453                 :             :           /* function-specifier:
   16454                 :             :                inline
   16455                 :             :                virtual
   16456                 :             :                explicit  */
   16457                 :    34947359 :         case RID_INLINE:
   16458                 :    34947359 :         case RID_VIRTUAL:
   16459                 :    34947359 :         case RID_EXPLICIT:
   16460                 :    34947359 :           cp_parser_function_specifier_opt (parser, decl_specs);
   16461                 :    34947359 :           break;
   16462                 :             : 
   16463                 :             :           /* decl-specifier:
   16464                 :             :                typedef  */
   16465                 :    25522322 :         case RID_TYPEDEF:
   16466                 :    25522322 :           ds = ds_typedef;
   16467                 :             :           /* Consume the token.  */
   16468                 :    25522322 :           cp_lexer_consume_token (parser->lexer);
   16469                 :             : 
   16470                 :    25522322 :           if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
   16471                 :             :             break;
   16472                 :             : 
   16473                 :             :           /* A constructor declarator cannot appear in a typedef.  */
   16474                 :    25522319 :           constructor_possible_p = false;
   16475                 :             :           /* The "typedef" keyword can only occur in a declaration; we
   16476                 :             :              may as well commit at this point.  */
   16477                 :    25522319 :           cp_parser_commit_to_tentative_parse (parser);
   16478                 :             : 
   16479                 :    25522319 :           if (decl_specs->storage_class != sc_none)
   16480                 :             :             {
   16481                 :          12 :               if (decl_specs->conflicting_specifiers_p)
   16482                 :             :                 break;
   16483                 :          12 :               gcc_rich_location richloc (token->location);
   16484                 :          12 :               location_t oloc = decl_specs->locations[ds_storage_class];
   16485                 :          12 :               richloc.add_location_if_nearby (oloc);
   16486                 :          12 :               error_at (&richloc,
   16487                 :             :                         "%<typedef%> specifier conflicts with %qs",
   16488                 :          12 :                         cp_storage_class_name[decl_specs->storage_class]);
   16489                 :          12 :               decl_specs->conflicting_specifiers_p = true;
   16490                 :          12 :             }
   16491                 :             :           break;
   16492                 :             : 
   16493                 :             :           /* storage-class-specifier:
   16494                 :             :                auto
   16495                 :             :                register
   16496                 :             :                static
   16497                 :             :                extern
   16498                 :             :                mutable
   16499                 :             : 
   16500                 :             :              GNU Extension:
   16501                 :             :                thread  */
   16502                 :     8843235 :         case RID_AUTO:
   16503                 :     8843235 :           if (cxx_dialect == cxx98)
   16504                 :             :             {
   16505                 :             :               /* Consume the token.  */
   16506                 :          31 :               cp_lexer_consume_token (parser->lexer);
   16507                 :             : 
   16508                 :             :               /* Complain about `auto' as a storage specifier, if
   16509                 :             :                  we're complaining about C++0x compatibility.  */
   16510                 :          31 :               gcc_rich_location richloc (token->location);
   16511                 :          31 :               richloc.add_fixit_remove ();
   16512                 :          31 :               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                 :          31 :               cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
   16518                 :             :                                            token);
   16519                 :          31 :             }
   16520                 :             :           else
   16521                 :             :             /* C++0x auto type-specifier.  */
   16522                 :             :             found_decl_spec = false;
   16523                 :             :           break;
   16524                 :             : 
   16525                 :    46353702 :         case RID_REGISTER:
   16526                 :    46353702 :         case RID_STATIC:
   16527                 :    46353702 :         case RID_EXTERN:
   16528                 :    46353702 :         case RID_MUTABLE:
   16529                 :             :           /* Consume the token.  */
   16530                 :    46353702 :           cp_lexer_consume_token (parser->lexer);
   16531                 :    46353702 :           cp_parser_set_storage_class (parser, decl_specs, token->keyword,
   16532                 :             :                                        token);
   16533                 :    46353702 :           break;
   16534                 :       19136 :         case RID_THREAD:
   16535                 :             :           /* Consume the token.  */
   16536                 :       19136 :           ds = ds_thread;
   16537                 :       19136 :           cp_lexer_consume_token (parser->lexer);
   16538                 :       19136 :           break;
   16539                 :             : 
   16540                 :             :         default:
   16541                 :             :           /* We did not yet find a decl-specifier yet.  */
   16542                 :             :           found_decl_spec = false;
   16543                 :             :           break;
   16544                 :             :         }
   16545                 :             : 
   16546                 :  1511205661 :       if (found_decl_spec
   16547                 :   149336853 :           && (flags & CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR)
   16548                 :           8 :           && token->keyword != RID_CONSTEXPR)
   16549                 :           3 :         error ("%qD invalid in condition", ridpointers[token->keyword]);
   16550                 :             : 
   16551                 :   149336853 :       if (found_decl_spec
   16552                 :   149336853 :           && (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
   16553                 :      132562 :           && token->keyword != RID_MUTABLE
   16554                 :        1164 :           && token->keyword != RID_CONSTEXPR
   16555                 :          68 :           && token->keyword != RID_CONSTEVAL)
   16556                 :             :         {
   16557                 :          62 :           if (token->keyword != RID_STATIC)
   16558                 :           7 :             error_at (token->location, "%qD invalid in lambda",
   16559                 :           7 :                       ridpointers[token->keyword]);
   16560                 :          55 :           else if (cxx_dialect < cxx23)
   16561                 :          35 :             pedwarn (token->location, OPT_Wc__23_extensions,
   16562                 :             :                      "%qD only valid in lambda with %<-std=c++23%> or "
   16563                 :          35 :                      "%<-std=gnu++23%>", ridpointers[token->keyword]);
   16564                 :             :         }
   16565                 :             : 
   16566                 :  1511205661 :       if (ds != ds_last)
   16567                 :    68035741 :         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                 :  1511205661 :       constructor_p
   16572                 :  3022411320 :         = (!found_decl_spec
   16573                 :  1511205661 :            && constructor_possible_p
   16574                 :  1917256350 :            && (cp_parser_constructor_declarator_p
   16575                 :   406050691 :                (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                 :  1511205659 :       if (!found_decl_spec && !constructor_p)
   16581                 :             :         {
   16582                 :  1340989248 :           int decl_spec_declares_class_or_enum;
   16583                 :  1340989248 :           bool is_cv_qualifier;
   16584                 :  1340989248 :           tree type_spec;
   16585                 :             : 
   16586                 :  1340989248 :           if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
   16587                 :      132557 :             flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
   16588                 :             : 
   16589                 :  1340989248 :           type_spec
   16590                 :  1340989248 :             = 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                 :  1340989220 :           *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                 :  1340989220 :           if (type_spec && !is_cv_qualifier)
   16634                 :   594147942 :             flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
   16635                 :             :           /* A constructor declarator cannot follow a type-specifier.  */
   16636                 :   680025004 :           if (type_spec)
   16637                 :             :             {
   16638                 :   680025004 :               constructor_possible_p = false;
   16639                 :   680025004 :               found_decl_spec = true;
   16640                 :   680025004 :               if (!is_cv_qualifier)
   16641                 :   594147942 :                 decl_specs->any_type_specifiers_p = true;
   16642                 :             : 
   16643                 :   680025004 :               if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) != 0)
   16644                 :          21 :                 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                 :  1511205631 :       if (!found_decl_spec)
   16651                 :             :         break;
   16652                 :             : 
   16653                 :   829361857 :       if (decl_specs->std_attributes)
   16654                 :             :         {
   16655                 :          12 :           error_at (decl_specs->locations[ds_std_attribute],
   16656                 :             :                     "standard attributes in middle of decl-specifiers");
   16657                 :          12 :           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                 :   829361857 :       decl_specs->any_specifiers_p = true;
   16664                 :             :       /* After we see one decl-specifier, further decl-specifiers are
   16665                 :             :          always optional.  */
   16666                 :   829361857 :       flags |= CP_PARSER_FLAGS_OPTIONAL;
   16667                 :             :     }
   16668                 :             : 
   16669                 :             :   /* Don't allow a friend specifier with a class definition.  */
   16670                 :   681843774 :   if (decl_spec_seq_has_spec_p (decl_specs, ds_friend)
   16671                 :   681843774 :       && (*declares_class_or_enum & 2))
   16672                 :           8 :     error_at (decl_specs->locations[ds_friend],
   16673                 :             :               "class definition may not be declared a friend");
   16674                 :   681843774 : }
   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                 :             : 
   16692                 :             : static tree
   16693                 :     2684356 : cp_parser_storage_class_specifier_opt (cp_parser* parser)
   16694                 :             : {
   16695                 :     2684356 :   switch (cp_lexer_peek_token (parser->lexer)->keyword)
   16696                 :             :     {
   16697                 :           0 :     case RID_AUTO:
   16698                 :           0 :       if (cxx_dialect != cxx98)
   16699                 :             :         return NULL_TREE;
   16700                 :             :       /* Fall through for C++98.  */
   16701                 :     2678463 :       gcc_fallthrough ();
   16702                 :             : 
   16703                 :     2678463 :     case RID_REGISTER:
   16704                 :     2678463 :     case RID_STATIC:
   16705                 :     2678463 :     case RID_EXTERN:
   16706                 :     2678463 :     case RID_MUTABLE:
   16707                 :     2678463 :     case RID_THREAD:
   16708                 :             :       /* Consume the token.  */
   16709                 :     2678463 :       return cp_lexer_consume_token (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                 :             : 
   16729                 :             : static tree
   16730                 :    34953252 : cp_parser_function_specifier_opt (cp_parser* parser,
   16731                 :             :                                   cp_decl_specifier_seq *decl_specs)
   16732                 :             : {
   16733                 :    34953252 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   16734                 :    34953252 :   switch (token->keyword)
   16735                 :             :     {
   16736                 :    26119788 :     case RID_INLINE:
   16737                 :    26119788 :       set_and_check_decl_spec_loc (decl_specs, ds_inline, token);
   16738                 :    26119788 :       break;
   16739                 :             : 
   16740                 :     3811199 :     case RID_VIRTUAL:
   16741                 :             :       /* 14.5.2.3 [temp.mem]
   16742                 :             : 
   16743                 :             :          A member function template shall not be virtual.  */
   16744                 :     3811199 :       if (PROCESSING_REAL_TEMPLATE_DECL_P ()
   16745                 :     3811223 :           && current_class_type)
   16746                 :          12 :         error_at (token->location, "templates may not be %<virtual%>");
   16747                 :             :       else
   16748                 :     3811187 :         set_and_check_decl_spec_loc (decl_specs, ds_virtual, token);
   16749                 :             :       break;
   16750                 :             : 
   16751                 :     5016404 :     case RID_EXPLICIT:
   16752                 :     5016404 :       {
   16753                 :     5016404 :         tree id = cp_lexer_consume_token (parser->lexer)->u.value;
   16754                 :             :         /* If we see '(', it's C++20 explicit(bool).  */
   16755                 :     5016404 :         tree expr;
   16756                 :     5016404 :         if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   16757                 :             :           {
   16758                 :       97828 :             matching_parens parens;
   16759                 :       97828 :             parens.consume_open (parser);
   16760                 :             : 
   16761                 :             :             /* New types are not allowed in an explicit-specifier.  */
   16762                 :       97828 :             const char *saved_message
   16763                 :             :               = parser->type_definition_forbidden_message;
   16764                 :       97828 :             parser->type_definition_forbidden_message
   16765                 :       97828 :               = G_("types may not be defined in explicit-specifier");
   16766                 :             : 
   16767                 :       97828 :             if (cxx_dialect < cxx20)
   16768                 :           8 :               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                 :       97828 :             expr = cp_parser_constant_expression (parser);
   16774                 :             : 
   16775                 :             :             /* Restore the saved message.  */
   16776                 :       97828 :             parser->type_definition_forbidden_message = saved_message;
   16777                 :       97828 :             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                 :     4918576 :           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                 :     5016404 :         expr = build_explicit_specifier (expr, tf_warning_or_error);
   16788                 :             :         /* We could evaluate it -- mark the decl as appropriate.  */
   16789                 :     5016404 :         if (expr == boolean_true_node)
   16790                 :     4918602 :           set_and_check_decl_spec_loc (decl_specs, ds_explicit, token);
   16791                 :       97802 :         else if (expr == boolean_false_node)
   16792                 :             :           /* Don't mark the decl as explicit.  */;
   16793                 :       97788 :         else if (decl_specs)
   16794                 :             :           /* The expression was value-dependent.  Remember it so that we can
   16795                 :             :              substitute it later.  */
   16796                 :       97788 :           decl_specs->explicit_specifier = expr;
   16797                 :             :         return id;
   16798                 :             :       }
   16799                 :             : 
   16800                 :             :     default:
   16801                 :             :       return NULL_TREE;
   16802                 :             :     }
   16803                 :             : 
   16804                 :             :   /* Consume the token.  */
   16805                 :    29930987 :   return cp_lexer_consume_token (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                 :             : 
   16814                 :             : static void
   16815                 :     1035902 : cp_parser_linkage_specification (cp_parser* parser, tree prefix_attr)
   16816                 :             : {
   16817                 :             :   /* Look for the `extern' keyword.  */
   16818                 :     1035902 :   cp_token *extern_token
   16819                 :     1035902 :     = cp_parser_require_keyword (parser, RID_EXTERN, RT_EXTERN);
   16820                 :             : 
   16821                 :             :   /* Look for the string-literal.  */
   16822                 :     1035902 :   cp_token *string_token = cp_lexer_peek_token (parser->lexer);
   16823                 :     1035902 :   tree linkage;
   16824                 :     1035902 :   if (cxx_dialect >= cxx26)
   16825                 :       92450 :     linkage = cp_parser_unevaluated_string_literal (parser);
   16826                 :             :   else
   16827                 :      943452 :     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                 :     1035902 :   if (linkage == error_mark_node
   16834                 :     1035902 :       || strlen (TREE_STRING_POINTER (linkage))
   16835                 :     1035899 :          != (size_t) (TREE_STRING_LENGTH (linkage) - 1))
   16836                 :             :     {
   16837                 :           3 :       cp_parser_error (parser, "invalid linkage-specification");
   16838                 :             :       /* Assume C++ linkage.  */
   16839                 :           3 :       linkage = lang_name_cplusplus;
   16840                 :             :     }
   16841                 :             :   else
   16842                 :     1035899 :     linkage = get_identifier (TREE_STRING_POINTER (linkage));
   16843                 :             : 
   16844                 :             :   /* We're now using the new linkage.  */
   16845                 :     1035902 :   unsigned saved_module = module_kind;
   16846                 :     1035902 :   module_kind &= ~MK_ATTACH;
   16847                 :     1035902 :   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                 :     1035902 :   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                 :     1035902 :   parser->innermost_linkage_specification_location
   16859                 :     1035902 :     = make_location (extern_token->location,
   16860                 :             :                      extern_token->location,
   16861                 :             :                      get_finish (string_token->location));
   16862                 :             : 
   16863                 :             :   /* If the next token is a `{', then we're using the first
   16864                 :             :      production.  */
   16865                 :     1035902 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   16866                 :             :     {
   16867                 :      703616 :       cp_ensure_no_omp_declare_simd (parser);
   16868                 :      703616 :       cp_ensure_no_oacc_routine (parser);
   16869                 :             : 
   16870                 :             :       /* Consume the `{' token.  */
   16871                 :      703616 :       matching_braces braces;
   16872                 :      703616 :       braces.consume_open (parser);
   16873                 :             :       /* Parse the declarations.  */
   16874                 :      703616 :       cp_parser_declaration_seq_opt (parser);
   16875                 :             :       /* Look for the closing `}'.  */
   16876                 :      703616 :       braces.require_close (parser);
   16877                 :             :     }
   16878                 :             :   /* Otherwise, there's just one declaration.  */
   16879                 :             :   else
   16880                 :             :     {
   16881                 :      332286 :       bool saved_in_unbraced_linkage_specification_p;
   16882                 :             : 
   16883                 :      332286 :       saved_in_unbraced_linkage_specification_p
   16884                 :      332286 :         = parser->in_unbraced_linkage_specification_p;
   16885                 :      332286 :       parser->in_unbraced_linkage_specification_p = true;
   16886                 :      332286 :       cp_parser_declaration (parser, prefix_attr);
   16887                 :      332286 :       parser->in_unbraced_linkage_specification_p
   16888                 :      332286 :         = saved_in_unbraced_linkage_specification_p;
   16889                 :             :     }
   16890                 :             : 
   16891                 :             :   /* We're done with the linkage-specification.  */
   16892                 :     1035902 :   pop_lang_context ();
   16893                 :     1035902 :   module_kind = saved_module;
   16894                 :             : 
   16895                 :             :   /* Restore location of parent linkage specification, if any.  */
   16896                 :     1035902 :   parser->innermost_linkage_specification_location = saved_location;
   16897                 :     1035902 : }
   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                 :             : 
   16908                 :             : static void
   16909                 :     3599010 : cp_parser_static_assert (cp_parser *parser, bool member_p)
   16910                 :             : {
   16911                 :     3599010 :   cp_expr condition;
   16912                 :     3599010 :   location_t token_loc;
   16913                 :     3599010 :   tree message;
   16914                 :             : 
   16915                 :             :   /* Peek at the `static_assert' token so we can keep track of exactly
   16916                 :             :      where the static assertion started.  */
   16917                 :     3599010 :   token_loc = cp_lexer_peek_token (parser->lexer)->location;
   16918                 :             : 
   16919                 :             :   /* Look for the `static_assert' keyword.  */
   16920                 :     3599010 :   if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT,
   16921                 :             :                                   RT_STATIC_ASSERT))
   16922                 :           0 :     return;
   16923                 :             : 
   16924                 :             :   /*  We know we are in a static assertion; commit to any tentative
   16925                 :             :       parse.  */
   16926                 :     3599010 :   if (cp_parser_parsing_tentatively (parser))
   16927                 :     3572355 :     cp_parser_commit_to_tentative_parse (parser);
   16928                 :             : 
   16929                 :             :   /* Parse the `(' starting the static assertion condition.  */
   16930                 :     3599010 :   matching_parens parens;
   16931                 :     3599010 :   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                 :     3599010 :   condition
   16936                 :     3599010 :     = cp_parser_constant_expression (parser,
   16937                 :             :                                      /*allow_non_constant_p=*/true,
   16938                 :             :                                      /*non_constant_p=*/nullptr);
   16939                 :             : 
   16940                 :     3599010 :   if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
   16941                 :             :     {
   16942                 :      442282 :       if (pedantic && cxx_dialect < cxx17)
   16943                 :          21 :         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                 :      442282 :       cp_lexer_consume_token (parser->lexer);
   16948                 :      442282 :       message = build_string (1, "");
   16949                 :      442282 :       TREE_TYPE (message) = char_array_type_node;
   16950                 :      442282 :       fix_string_type (message);
   16951                 :             :     }
   16952                 :             :   else
   16953                 :             :     {
   16954                 :             :       /* Parse the separating `,'.  */
   16955                 :     3156728 :       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   16956                 :             : 
   16957                 :             :       /* Parse the message expression.  */
   16958                 :     3156728 :       bool string_lit = true;
   16959                 :     3156728 :       for (unsigned int i = 1; ; ++i)
   16960                 :             :         {
   16961                 :     6580512 :           cp_token *tok = cp_lexer_peek_nth_token (parser->lexer, i);
   16962                 :     6580512 :           if (cp_parser_is_pure_string_literal (tok))
   16963                 :     3423784 :             continue;
   16964                 :     3156728 :           else if (tok->type == CPP_CLOSE_PAREN)
   16965                 :             :             break;
   16966                 :         177 :           string_lit = false;
   16967                 :         177 :           break;
   16968                 :     3423784 :         }
   16969                 :     3156728 :       if (!string_lit)
   16970                 :             :         {
   16971                 :         177 :           location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   16972                 :         177 :           if (cxx_dialect < cxx26)
   16973                 :         177 :             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                 :         177 :           message = cp_parser_conditional_expression (parser);
   16978                 :         177 :           if (TREE_CODE (message) == STRING_CST)
   16979                 :           0 :             message = build1_loc (loc, PAREN_EXPR, TREE_TYPE (message),
   16980                 :             :                                   message);
   16981                 :             :         }
   16982                 :     3156551 :       else if (cxx_dialect >= cxx26)
   16983                 :      349155 :         message = cp_parser_unevaluated_string_literal (parser);
   16984                 :             :       else
   16985                 :     2807396 :         message = cp_parser_string_literal (parser, /*translate=*/false,
   16986                 :             :                                             /*wide_ok=*/true);
   16987                 :             : 
   16988                 :             :       /* A `)' completes the static assertion.  */
   16989                 :     3156728 :       if (!parens.require_close (parser))
   16990                 :           0 :         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                 :     3599010 :   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                 :     3599010 :   location_t assert_loc = condition.get_location ();
   17003                 :     3599010 :   if (assert_loc == UNKNOWN_LOCATION)
   17004                 :           2 :     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                 :     3599010 :   finish_static_assert (condition, message, assert_loc, member_p,
   17009                 :             :                         /*show_expr_p=*/false);
   17010                 :             : }
   17011                 :             : 
   17012                 :             : /* Parse the expression in decltype ( expression ).  */
   17013                 :             : 
   17014                 :             : static tree
   17015                 :     2493152 : cp_parser_decltype_expr (cp_parser *parser,
   17016                 :             :                          bool &id_expression_or_member_access_p)
   17017                 :             : {
   17018                 :     2493152 :   cp_token *id_expr_start_token;
   17019                 :     2493152 :   tree expr;
   17020                 :             : 
   17021                 :             :   /* First, try parsing an id-expression.  */
   17022                 :     2493152 :   id_expr_start_token = cp_lexer_peek_token (parser->lexer);
   17023                 :     2493152 :   cp_parser_parse_tentatively (parser);
   17024                 :     2493152 :   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                 :     2208218 :   if (!cp_parser_error_occurred (parser) && expr != error_mark_node)
   17032                 :             :     {
   17033                 :     2208215 :       bool non_integral_constant_expression_p = false;
   17034                 :     2208215 :       tree id_expression = expr;
   17035                 :     2208215 :       cp_id_kind idk;
   17036                 :     2208215 :       const char *error_msg;
   17037                 :             : 
   17038                 :     2208215 :       if (identifier_p (expr))
   17039                 :             :         /* Lookup the name we got back from the id-expression.  */
   17040                 :     1269827 :         expr = cp_parser_lookup_name_simple (parser, expr,
   17041                 :             :                                              id_expr_start_token->location);
   17042                 :             : 
   17043                 :     2208215 :       if (expr
   17044                 :     2208215 :           && expr != error_mark_node
   17045                 :     2194977 :           && TREE_CODE (expr) != TYPE_DECL
   17046                 :     1893518 :           && (TREE_CODE (expr) != BIT_NOT_EXPR
   17047                 :          18 :               || !TYPE_P (TREE_OPERAND (expr, 0)))
   17048                 :     4101715 :           && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
   17049                 :             :         {
   17050                 :             :           /* Complete lookup of the id-expression.  */
   17051                 :      209755 :           expr = (finish_id_expression
   17052                 :      209755 :                   (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                 :      209755 :           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                 :           9 :               cp_parser_parse_definitely (parser);
   17070                 :           9 :               cp_parser_error (parser, error_msg);
   17071                 :           9 :               id_expression_or_member_access_p = true;
   17072                 :           9 :               return error_mark_node;
   17073                 :             :             }
   17074                 :             :         }
   17075                 :             : 
   17076                 :     2208206 :       if (expr
   17077                 :     2208206 :           && expr != error_mark_node
   17078                 :     4403174 :           && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
   17079                 :             :         /* We have an id-expression.  */
   17080                 :      209780 :         id_expression_or_member_access_p = true;
   17081                 :             :     }
   17082                 :             : 
   17083                 :     2493143 :   if (!id_expression_or_member_access_p)
   17084                 :             :     {
   17085                 :             :       /* Abort the id-expression parse.  */
   17086                 :     2283363 :       cp_parser_abort_tentative_parse (parser);
   17087                 :             : 
   17088                 :             :       /* Parsing tentatively, again.  */
   17089                 :     2283363 :       cp_parser_parse_tentatively (parser);
   17090                 :             : 
   17091                 :             :       /* Parse a class member access.  */
   17092                 :     2283363 :       expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
   17093                 :             :                                            /*cast_p=*/false, /*decltype*/true,
   17094                 :             :                                            /*member_access_only_p=*/true, NULL);
   17095                 :             : 
   17096                 :     2283363 :       if (expr
   17097                 :     2283363 :           && expr != error_mark_node
   17098                 :     2283484 :           && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
   17099                 :             :         /* We have an id-expression.  */
   17100                 :         100 :         id_expression_or_member_access_p = true;
   17101                 :             :     }
   17102                 :             : 
   17103                 :     2493143 :   if (id_expression_or_member_access_p)
   17104                 :             :     /* We have parsed the complete id-expression or member access.  */
   17105                 :      209880 :     cp_parser_parse_definitely (parser);
   17106                 :             :   else
   17107                 :             :     {
   17108                 :             :       /* Abort our attempt to parse an id-expression or member access
   17109                 :             :          expression.  */
   17110                 :     2283263 :       cp_parser_abort_tentative_parse (parser);
   17111                 :             : 
   17112                 :             :       /* Parse a full expression.  */
   17113                 :     2283263 :       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                 :             : 
   17127                 :             : static tree
   17128                 :     2798741 : cp_parser_decltype (cp_parser *parser)
   17129                 :             : {
   17130                 :     2798741 :   bool id_expression_or_member_access_p = false;
   17131                 :     2798741 :   cp_token *start_token = cp_lexer_peek_token (parser->lexer);
   17132                 :             : 
   17133                 :     2798741 :   if (start_token->type == CPP_DECLTYPE)
   17134                 :             :     {
   17135                 :             :       /* Already parsed.  */
   17136                 :       29817 :       cp_lexer_consume_token (parser->lexer);
   17137                 :       29817 :       return saved_checks_value (start_token->u.tree_check_value);
   17138                 :             :     }
   17139                 :             : 
   17140                 :             :   /* Look for the `decltype' token.  */
   17141                 :     2768924 :   if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE))
   17142                 :           0 :     return error_mark_node;
   17143                 :             : 
   17144                 :             :   /* Parse the opening `('.  */
   17145                 :     2768924 :   matching_parens parens;
   17146                 :     2768924 :   if (!parens.require_open (parser))
   17147                 :          49 :     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                 :     2768875 :   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                 :     6106369 :   if (cp_parser_uncommitted_to_tentative_parse_p (parser)
   17157                 :      568619 :       && !parser->in_declarator_p)
   17158                 :      543231 :     cp_parser_commit_to_topmost_tentative_parse (parser);
   17159                 :             : 
   17160                 :     2768875 :   push_deferring_access_checks (dk_deferred);
   17161                 :             : 
   17162                 :     2768875 :   tree expr = NULL_TREE;
   17163                 :             : 
   17164                 :     2768875 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO)
   17165                 :     2768875 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
   17166                 :             :     {
   17167                 :             :       /* decltype (auto) */
   17168                 :      275723 :       cp_lexer_consume_token (parser->lexer);
   17169                 :      275723 :       if (cxx_dialect < cxx14)
   17170                 :             :         {
   17171                 :           2 :           error_at (start_token->location,
   17172                 :             :                     "%<decltype(auto)%> type specifier only available with "
   17173                 :             :                     "%<-std=c++14%> or %<-std=gnu++14%>");
   17174                 :           2 :           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                 :     2493152 :       const char *saved_message = parser->type_definition_forbidden_message;
   17184                 :     2493152 :       parser->type_definition_forbidden_message
   17185                 :     2493152 :         = G_("types may not be defined in %<decltype%> expressions");
   17186                 :             : 
   17187                 :             :       /* The restrictions on constant-expressions do not apply inside
   17188                 :             :          decltype expressions.  */
   17189                 :     2493152 :       bool saved_integral_constant_expression_p
   17190                 :             :         = parser->integral_constant_expression_p;
   17191                 :     2493152 :       bool saved_non_integral_constant_expression_p
   17192                 :             :         = parser->non_integral_constant_expression_p;
   17193                 :     2493152 :       parser->integral_constant_expression_p = false;
   17194                 :             : 
   17195                 :             :       /* Within a parenthesized expression, a `>' token is always
   17196                 :             :          the greater-than operator.  */
   17197                 :     2493152 :       bool saved_greater_than_is_operator_p
   17198                 :             :         = parser->greater_than_is_operator_p;
   17199                 :     2493152 :       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                 :     2493152 :       auto cleanup = make_temp_override
   17209                 :     2493152 :         (parser->auto_is_implicit_function_template_parm_p, false);
   17210                 :             : 
   17211                 :             :       /* Do not actually evaluate the expression.  */
   17212                 :     2493152 :       ++cp_unevaluated_operand;
   17213                 :             : 
   17214                 :             :       /* Do not warn about problems with the expression.  */
   17215                 :     2493152 :       ++c_inhibit_evaluation_warnings;
   17216                 :             : 
   17217                 :     2493152 :       expr = cp_parser_decltype_expr (parser, id_expression_or_member_access_p);
   17218                 :     2493152 :       STRIP_ANY_LOCATION_WRAPPER (expr);
   17219                 :             : 
   17220                 :             :       /* Go back to evaluating expressions.  */
   17221                 :     2493152 :       --cp_unevaluated_operand;
   17222                 :     2493152 :       --c_inhibit_evaluation_warnings;
   17223                 :             : 
   17224                 :             :       /* The `>' token might be the end of a template-id or
   17225                 :             :          template-parameter-list now.  */
   17226                 :     2493152 :       parser->greater_than_is_operator_p
   17227                 :     2493152 :         = saved_greater_than_is_operator_p;
   17228                 :             : 
   17229                 :             :       /* Restore the old message and the integral constant expression
   17230                 :             :          flags.  */
   17231                 :     2493152 :       parser->type_definition_forbidden_message = saved_message;
   17232                 :     2493152 :       parser->integral_constant_expression_p
   17233                 :     2493152 :         = saved_integral_constant_expression_p;
   17234                 :     2493152 :       parser->non_integral_constant_expression_p
   17235                 :     2493152 :         = saved_non_integral_constant_expression_p;
   17236                 :     2493152 :     }
   17237                 :             : 
   17238                 :             :   /* Parse to the closing `)'.  */
   17239                 :     5537588 :   if (expr == error_mark_node || !parens.require_close (parser))
   17240                 :             :     {
   17241                 :         174 :       cp_parser_skip_to_closing_parenthesis (parser, true, false,
   17242                 :             :                                              /*consume_paren=*/true);
   17243                 :         174 :       expr = error_mark_node;
   17244                 :             :     }
   17245                 :             : 
   17246                 :             :   /* If we got a parse error while tentative, bail out now.  */
   17247                 :     5537750 :   if (cp_parser_error_occurred (parser))
   17248                 :             :     {
   17249                 :          30 :       pop_deferring_access_checks ();
   17250                 :          30 :       return error_mark_node;
   17251                 :             :     }
   17252                 :             : 
   17253                 :     2768845 :   if (!expr)
   17254                 :             :     /* Build auto.  */
   17255                 :      275721 :     expr = make_decltype_auto ();
   17256                 :             :   else
   17257                 :     2493124 :     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                 :     2768845 :   start_token->type = CPP_DECLTYPE;
   17263                 :     2768845 :   start_token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
   17264                 :     2768845 :   start_token->tree_check_p = true;
   17265                 :     2768845 :   start_token->u.tree_check_value->value = expr;
   17266                 :     2768845 :   start_token->u.tree_check_value->checks = get_deferred_access_checks ();
   17267                 :     2768845 :   start_token->keyword = RID_MAX;
   17268                 :             : 
   17269                 :     2768845 :   location_t loc = start_token->location;
   17270                 :     2768845 :   loc = make_location (loc, loc, parser->lexer);
   17271                 :     2768845 :   start_token->location = loc;
   17272                 :             : 
   17273                 :     2768845 :   cp_lexer_purge_tokens_after (parser->lexer, start_token);
   17274                 :             : 
   17275                 :     2768845 :   pop_to_parent_deferring_access_checks ();
   17276                 :             : 
   17277                 :     2768845 :   return expr;
   17278                 :     2768875 : }
   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                 :             : 
   17289                 :             : static tree
   17290                 :     1172620 : cp_parser_conversion_function_id (cp_parser* parser)
   17291                 :             : {
   17292                 :     1172620 :   tree type;
   17293                 :     1172620 :   tree saved_scope;
   17294                 :     1172620 :   tree saved_qualifying_scope;
   17295                 :     1172620 :   tree saved_object_scope;
   17296                 :     1172620 :   tree pushed_scope = NULL_TREE;
   17297                 :             : 
   17298                 :             :   /* Look for the `operator' token.  */
   17299                 :     1172620 :   if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
   17300                 :           0 :     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                 :     1172620 :   saved_scope = parser->scope;
   17305                 :     1172620 :   saved_qualifying_scope = parser->qualifying_scope;
   17306                 :     1172620 :   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                 :     1172620 :   if (saved_scope)
   17321                 :      133804 :     pushed_scope = push_scope (saved_scope);
   17322                 :             :   /* Parse the conversion-type-id.  */
   17323                 :     1172620 :   type = cp_parser_conversion_type_id (parser);
   17324                 :             :   /* Leave the scope of the class, if any.  */
   17325                 :     1172620 :   if (pushed_scope)
   17326                 :      133804 :     pop_scope (pushed_scope);
   17327                 :             :   /* Restore the saved scope.  */
   17328                 :     1172620 :   parser->scope = saved_scope;
   17329                 :     1172620 :   parser->qualifying_scope = saved_qualifying_scope;
   17330                 :     1172620 :   parser->object_scope = saved_object_scope;
   17331                 :             :   /* If the TYPE is invalid, indicate failure.  */
   17332                 :     1172620 :   if (type == error_mark_node)
   17333                 :             :     return error_mark_node;
   17334                 :     1172583 :   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                 :             : 
   17344                 :             : static tree
   17345                 :     1172620 : cp_parser_conversion_type_id (cp_parser* parser)
   17346                 :             : {
   17347                 :     1172620 :   tree attributes;
   17348                 :     1172620 :   cp_decl_specifier_seq type_specifiers;
   17349                 :     1172620 :   cp_declarator *declarator;
   17350                 :     1172620 :   tree type_specified;
   17351                 :     1172620 :   const char *saved_message;
   17352                 :             : 
   17353                 :             :   /* Parse the attributes.  */
   17354                 :     1172620 :   attributes = cp_parser_attributes_opt (parser);
   17355                 :             : 
   17356                 :     1172620 :   saved_message = parser->type_definition_forbidden_message;
   17357                 :     1172620 :   parser->type_definition_forbidden_message
   17358                 :     1172620 :     = 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                 :     1172620 :   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                 :     1172620 :   parser->type_definition_forbidden_message = saved_message;
   17368                 :             : 
   17369                 :             :   /* If that didn't work, stop.  */
   17370                 :     1172620 :   if (type_specifiers.type == error_mark_node)
   17371                 :             :     return error_mark_node;
   17372                 :             :   /* Parse the conversion-declarator.  */
   17373                 :     1172583 :   declarator = cp_parser_conversion_declarator_opt (parser);
   17374                 :             : 
   17375                 :     1172583 :   type_specified =  grokdeclarator (declarator, &type_specifiers, TYPENAME,
   17376                 :             :                                     /*initialized=*/0, &attributes);
   17377                 :     1172583 :   if (attributes)
   17378                 :          16 :     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                 :     2998140 :   if (! cp_parser_uncommitted_to_tentative_parse_p (parser)
   17383                 :      652974 :       && type_uses_auto (type_specified))
   17384                 :             :     {
   17385                 :          51 :       if (cxx_dialect < cxx14)
   17386                 :             :         {
   17387                 :           0 :           error ("invalid use of %<auto%> in conversion operator");
   17388                 :           0 :           return error_mark_node;
   17389                 :             :         }
   17390                 :          51 :       else if (template_parm_scope_p ())
   17391                 :           3 :         warning (0, "use of %<auto%> in member template "
   17392                 :             :                  "conversion operator can never be deduced");
   17393                 :             :     }
   17394                 :             : 
   17395                 :     1172583 :   return type_specified;
   17396                 :             : }
   17397                 :             : 
   17398                 :             : /* Parse an (optional) conversion-declarator.
   17399                 :             : 
   17400                 :             :    conversion-declarator:
   17401                 :             :      ptr-operator conversion-declarator [opt]
   17402                 :             : 
   17403                 :             :    */
   17404                 :             : 
   17405                 :             : static cp_declarator *
   17406                 :     1254778 : cp_parser_conversion_declarator_opt (cp_parser* parser)
   17407                 :             : {
   17408                 :     1254778 :   enum tree_code code;
   17409                 :     1254778 :   tree class_type, std_attributes = NULL_TREE;
   17410                 :     1254778 :   cp_cv_quals cv_quals;
   17411                 :             : 
   17412                 :             :   /* We don't know if there's a ptr-operator next, or not.  */
   17413                 :     1254778 :   cp_parser_parse_tentatively (parser);
   17414                 :             :   /* Try the ptr-operator.  */
   17415                 :     1254778 :   code = cp_parser_ptr_operator (parser, &class_type, &cv_quals,
   17416                 :             :                                  &std_attributes);
   17417                 :             :   /* If it worked, look for more conversion-declarators.  */
   17418                 :     1254778 :   if (cp_parser_parse_definitely (parser))
   17419                 :             :     {
   17420                 :       82195 :       cp_declarator *declarator;
   17421                 :             : 
   17422                 :             :       /* Parse another optional declarator.  */
   17423                 :       82195 :       declarator = cp_parser_conversion_declarator_opt (parser);
   17424                 :             : 
   17425                 :       82195 :       declarator = cp_parser_make_indirect_declarator
   17426                 :       82195 :         (code, class_type, cv_quals, declarator, std_attributes);
   17427                 :             : 
   17428                 :       82195 :       return declarator;
   17429                 :             :    }
   17430                 :             : 
   17431                 :             :   return NULL;
   17432                 :             : }
   17433                 :             : 
   17434                 :             : /* Parse an (optional) ctor-initializer.
   17435                 :             : 
   17436                 :             :    ctor-initializer:
   17437                 :             :      : mem-initializer-list  */
   17438                 :             : 
   17439                 :             : static void
   17440                 :    98020965 : cp_parser_ctor_initializer_opt (cp_parser* parser)
   17441                 :             : {
   17442                 :             :   /* If the next token is not a `:', then there is no
   17443                 :             :      ctor-initializer.  */
   17444                 :    98020965 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
   17445                 :             :     {
   17446                 :             :       /* Do default initialization of any bases and members.  */
   17447                 :   170619220 :       if (DECL_CONSTRUCTOR_P (current_function_decl))
   17448                 :     1102701 :         finish_mem_initializers (NULL_TREE);
   17449                 :    85309610 :       return;
   17450                 :             :     }
   17451                 :             : 
   17452                 :             :   /* Consume the `:' token.  */
   17453                 :    12711355 :   cp_lexer_consume_token (parser->lexer);
   17454                 :             :   /* And the mem-initializer-list.  */
   17455                 :    12711355 :   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                 :             : 
   17464                 :             : static void
   17465                 :    12711355 : cp_parser_mem_initializer_list (cp_parser* parser)
   17466                 :             : {
   17467                 :    12711355 :   tree mem_initializer_list = NULL_TREE;
   17468                 :    12711355 :   tree target_ctor = error_mark_node;
   17469                 :    12711355 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   17470                 :             : 
   17471                 :             :   /* Let the semantic analysis code know that we are starting the
   17472                 :             :      mem-initializer-list.  */
   17473                 :    25422710 :   if (!DECL_CONSTRUCTOR_P (current_function_decl))
   17474                 :          12 :     error_at (token->location,
   17475                 :             :               "only constructors take member initializers");
   17476                 :             : 
   17477                 :             :   /* Loop through the list.  */
   17478                 :    26728027 :   while (true)
   17479                 :             :     {
   17480                 :    19719691 :       tree mem_initializer;
   17481                 :             : 
   17482                 :    19719691 :       token = cp_lexer_peek_token (parser->lexer);
   17483                 :             :       /* Parse the mem-initializer.  */
   17484                 :    19719691 :       mem_initializer = cp_parser_mem_initializer (parser);
   17485                 :             :       /* If the next token is a `...', we're expanding member initializers. */
   17486                 :    19719691 :       bool ellipsis = cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS);
   17487                 :    19719691 :       if (ellipsis
   17488                 :    19719691 :           || (mem_initializer != error_mark_node
   17489                 :    19719598 :               && check_for_bare_parameter_packs (TREE_PURPOSE
   17490                 :             :                                                  (mem_initializer))))
   17491                 :             :         {
   17492                 :             :           /* Consume the `...'. */
   17493                 :          34 :           if (ellipsis)
   17494                 :          31 :             cp_lexer_consume_token (parser->lexer);
   17495                 :             : 
   17496                 :             :           /* The TREE_PURPOSE must be a _TYPE, because base-specifiers
   17497                 :             :              can be expanded but members cannot. */
   17498                 :          34 :           if (mem_initializer != error_mark_node
   17499                 :          68 :               && !TYPE_P (TREE_PURPOSE (mem_initializer)))
   17500                 :             :             {
   17501                 :           4 :               error_at (token->location,
   17502                 :             :                         "cannot expand initializer for member %qD",
   17503                 :           4 :                         TREE_PURPOSE (mem_initializer));
   17504                 :           4 :               mem_initializer = error_mark_node;
   17505                 :             :             }
   17506                 :             : 
   17507                 :             :           /* Construct the pack expansion type. */
   17508                 :          34 :           if (mem_initializer != error_mark_node)
   17509                 :          30 :             mem_initializer = make_pack_expansion (mem_initializer);
   17510                 :             :         }
   17511                 :    19719691 :       if (target_ctor != error_mark_node
   17512                 :           6 :           && mem_initializer != error_mark_node)
   17513                 :             :         {
   17514                 :           6 :           error ("mem-initializer for %qD follows constructor delegation",
   17515                 :           6 :                  TREE_PURPOSE (mem_initializer));
   17516                 :           6 :           mem_initializer = error_mark_node;
   17517                 :             :         }
   17518                 :             :       /* Look for a target constructor. */
   17519                 :    19719691 :       if (mem_initializer != error_mark_node
   17520                 :    19719619 :           && CLASS_TYPE_P (TREE_PURPOSE (mem_initializer))
   17521                 :    24546715 :           && same_type_p (TREE_PURPOSE (mem_initializer), current_class_type))
   17522                 :             :         {
   17523                 :     1318250 :           maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
   17524                 :     1318250 :           if (mem_initializer_list)
   17525                 :             :             {
   17526                 :           6 :               error ("constructor delegation follows mem-initializer for %qD",
   17527                 :           6 :                      TREE_PURPOSE (mem_initializer_list));
   17528                 :           6 :               mem_initializer = error_mark_node;
   17529                 :             :             }
   17530                 :             :           target_ctor = mem_initializer;
   17531                 :             :         }
   17532                 :             :       /* Add it to the list, unless it was erroneous.  */
   17533                 :    19719691 :       if (mem_initializer != error_mark_node)
   17534                 :             :         {
   17535                 :    19719613 :           TREE_CHAIN (mem_initializer) = mem_initializer_list;
   17536                 :    19719613 :           mem_initializer_list = mem_initializer;
   17537                 :             :         }
   17538                 :             :       /* If the next token is not a `,', we're done.  */
   17539                 :    19719691 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   17540                 :             :         break;
   17541                 :             :       /* Consume the `,' token.  */
   17542                 :     7008336 :       cp_lexer_consume_token (parser->lexer);
   17543                 :     7008336 :     }
   17544                 :             : 
   17545                 :             :   /* Perform semantic analysis.  */
   17546                 :    25422710 :   if (DECL_CONSTRUCTOR_P (current_function_decl))
   17547                 :    12711343 :     finish_mem_initializers (mem_initializer_list);
   17548                 :    12711355 : }
   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                 :             : 
   17566                 :             : static tree
   17567                 :    19719691 : cp_parser_mem_initializer (cp_parser* parser)
   17568                 :             : {
   17569                 :    19719691 :   tree mem_initializer_id;
   17570                 :    19719691 :   tree expression_list;
   17571                 :    19719691 :   tree member;
   17572                 :    19719691 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   17573                 :             : 
   17574                 :             :   /* Find out what is being initialized.  */
   17575                 :    19719691 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   17576                 :             :     {
   17577                 :           8 :       permerror (token->location,
   17578                 :             :                  "anachronistic old-style base class initializer");
   17579                 :           8 :       mem_initializer_id = NULL_TREE;
   17580                 :             :     }
   17581                 :             :   else
   17582                 :             :     {
   17583                 :    19719683 :       mem_initializer_id = cp_parser_mem_initializer_id (parser);
   17584                 :    19719683 :       if (mem_initializer_id == error_mark_node)
   17585                 :             :         return mem_initializer_id;
   17586                 :             :     }
   17587                 :    19719676 :   member = expand_member_init (mem_initializer_id);
   17588                 :    19719676 :   if (member && !DECL_P (member))
   17589                 :     5746551 :     in_base_initializer = 1;
   17590                 :             : 
   17591                 :    19719676 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   17592                 :             :     {
   17593                 :      317454 :       cp_lexer_set_source_position (parser->lexer);
   17594                 :      317454 :       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   17595                 :      317454 :       expression_list = cp_parser_braced_list (parser);
   17596                 :      317454 :       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
   17597                 :      317454 :       expression_list = build_tree_list (NULL_TREE, expression_list);
   17598                 :             :     }
   17599                 :             :   else
   17600                 :             :     {
   17601                 :    19402222 :       vec<tree, va_gc> *vec;
   17602                 :    19402222 :       vec = cp_parser_parenthesized_expression_list (parser, 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                 :    19402222 :       if (vec == NULL)
   17609                 :           4 :         return error_mark_node;
   17610                 :    19402218 :       expression_list = build_tree_list_vec (vec);
   17611                 :    19402218 :       release_tree_vector (vec);
   17612                 :             :     }
   17613                 :             : 
   17614                 :    19719672 :   if (expression_list == error_mark_node)
   17615                 :             :     return error_mark_node;
   17616                 :    19719672 :   if (!expression_list)
   17617                 :     2169467 :     expression_list = void_type_node;
   17618                 :             : 
   17619                 :    19719672 :   in_base_initializer = 0;
   17620                 :             : 
   17621                 :    19719672 :   if (!member)
   17622                 :             :     return error_mark_node;
   17623                 :    19719629 :   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                 :    19719629 :   location_t loc
   17629                 :    19719629 :     = make_location (token->location, token->location, parser->lexer);
   17630                 :    19719629 :   tree dummy = build0 (EMPTY_CLASS_EXPR, NULL_TREE);
   17631                 :    19719629 :   SET_EXPR_LOCATION (dummy, loc);
   17632                 :    19719629 :   TREE_TYPE (node) = dummy;
   17633                 :             : 
   17634                 :    19719629 :   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                 :             : 
   17648                 :             : static tree
   17649                 :    19719683 : cp_parser_mem_initializer_id (cp_parser* parser)
   17650                 :             : {
   17651                 :    19719683 :   bool global_scope_p;
   17652                 :    19719683 :   bool nested_name_specifier_p;
   17653                 :    19719683 :   bool template_p = false;
   17654                 :    19719683 :   tree id;
   17655                 :             : 
   17656                 :    19719683 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   17657                 :             : 
   17658                 :             :   /* `typename' is not allowed in this context ([temp.res]).  */
   17659                 :    19719683 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
   17660                 :             :     {
   17661                 :           4 :       error_at (token->location,
   17662                 :             :                 "keyword %<typename%> not allowed in this context (a qualified "
   17663                 :             :                 "member initializer is implicitly a type)");
   17664                 :           4 :       cp_lexer_consume_token (parser->lexer);
   17665                 :             :     }
   17666                 :             :   /* Look for the optional `::' operator.  */
   17667                 :    19719683 :   global_scope_p
   17668                 :    19719683 :     = (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                 :    19719683 :   nested_name_specifier_p
   17684                 :    19719683 :     = (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                 :    19719683 :   if (nested_name_specifier_p)
   17691                 :       23689 :     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                 :    19719683 :   if (global_scope_p || nested_name_specifier_p)
   17695                 :       23689 :     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                 :       23689 :                                  /*is_declaration=*/true);
   17702                 :             :   /* Otherwise, we could also be looking for an ordinary identifier.  */
   17703                 :    19695994 :   cp_parser_parse_tentatively (parser);
   17704                 :    19695994 :   if (cp_lexer_next_token_is_decltype (parser->lexer))
   17705                 :             :     /* Try a decltype-specifier.  */
   17706                 :           6 :     id = cp_parser_decltype (parser);
   17707                 :             :   else
   17708                 :             :     /* Otherwise, try a class-name.  */
   17709                 :    19695988 :     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                 :    19695994 :   if (cp_parser_parse_definitely (parser))
   17718                 :             :     return id;
   17719                 :             :   /* Otherwise, look for an ordinary identifier.  */
   17720                 :    13973128 :   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                 :             : 
   17733                 :             : static cp_expr
   17734                 :    61779763 : cp_parser_operator_function_id (cp_parser* parser)
   17735                 :             : {
   17736                 :    61779763 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   17737                 :             :   /* Look for the `operator' keyword.  */
   17738                 :    61779763 :   if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
   17739                 :           0 :     return error_mark_node;
   17740                 :             :   /* And then the name of the operator itself.  */
   17741                 :    61779763 :   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                 :             : 
   17747                 :             : tree
   17748                 :      614637 : cp_literal_operator_id (const char* name)
   17749                 :             : {
   17750                 :      614637 :   tree identifier;
   17751                 :      614637 :   char *buffer = XNEWVEC (char, strlen (UDLIT_OP_ANSI_PREFIX)
   17752                 :             :                               + strlen (name) + 10);
   17753                 :      614637 :   sprintf (buffer, UDLIT_OP_ANSI_FORMAT, name);
   17754                 :      614637 :   identifier = get_identifier (buffer);
   17755                 :      614637 :   XDELETEVEC (buffer);
   17756                 :             : 
   17757                 :      614637 :   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                 :             : 
   17775                 :             : static cp_expr
   17776                 :    61779763 : cp_parser_operator (cp_parser* parser, location_t start_loc)
   17777                 :             : {
   17778                 :    61779763 :   tree id = NULL_TREE;
   17779                 :    61779763 :   cp_token *token;
   17780                 :    61779763 :   bool utf8 = false;
   17781                 :             : 
   17782                 :             :   /* Peek at the next token.  */
   17783                 :    61779763 :   token = cp_lexer_peek_token (parser->lexer);
   17784                 :             : 
   17785                 :    61779763 :   location_t end_loc = token->location;
   17786                 :             : 
   17787                 :             :   /* Figure out which operator we have.  */
   17788                 :    61779763 :   enum tree_code op = ERROR_MARK;
   17789                 :    61779763 :   bool assop = false;
   17790                 :    61779763 :   bool consumed = false;
   17791                 :    61779763 :   switch (token->type)
   17792                 :             :     {
   17793                 :     2337328 :     case CPP_KEYWORD:
   17794                 :     2337328 :       {
   17795                 :             :         /* The keyword should be either `new', `delete' or `co_await'.  */
   17796                 :     2337328 :         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                 :     1041991 :         end_loc = cp_lexer_consume_token (parser->lexer)->location;
   17807                 :             : 
   17808                 :             :         /* Peek at the next token.  */
   17809                 :     1041991 :         token = cp_lexer_peek_token (parser->lexer);
   17810                 :             :         /* If it's a `[' token then this is the array variant of the
   17811                 :             :            operator.  */
   17812                 :     1041991 :         if (token->type == CPP_OPEN_SQUARE
   17813                 :      295459 :             && op != CO_AWAIT_EXPR)
   17814                 :             :           {
   17815                 :             :             /* Consume the `[' token.  */
   17816                 :      295459 :             cp_lexer_consume_token (parser->lexer);
   17817                 :             :             /* Look for the `]' token.  */
   17818                 :      590918 :             if (cp_token *close_token
   17819                 :      295459 :                 = cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
   17820                 :      295439 :               end_loc = close_token->location;
   17821                 :      295459 :             op = op == NEW_EXPR ? VEC_NEW_EXPR : VEC_DELETE_EXPR;
   17822                 :             :           }
   17823                 :             :         consumed = true;
   17824                 :             :         break;
   17825                 :             :       }
   17826                 :             : 
   17827                 :     1173818 :     case CPP_PLUS:
   17828                 :     1173818 :       op = PLUS_EXPR;
   17829                 :     1173818 :       break;
   17830                 :             : 
   17831                 :     1010032 :     case CPP_MINUS:
   17832                 :     1010032 :       op = MINUS_EXPR;
   17833                 :     1010032 :       break;
   17834                 :             : 
   17835                 :     1266079 :     case CPP_MULT:
   17836                 :     1266079 :       op = MULT_EXPR;
   17837                 :     1266079 :       break;
   17838                 :             : 
   17839                 :      586587 :     case CPP_DIV:
   17840                 :      586587 :       op = TRUNC_DIV_EXPR;
   17841                 :      586587 :       break;
   17842                 :             : 
   17843                 :      193952 :     case CPP_MOD:
   17844                 :      193952 :       op = TRUNC_MOD_EXPR;
   17845                 :      193952 :       break;
   17846                 :             : 
   17847                 :      426656 :     case CPP_XOR:
   17848                 :      426656 :       op = BIT_XOR_EXPR;
   17849                 :      426656 :       break;
   17850                 :             : 
   17851                 :      468344 :     case CPP_AND:
   17852                 :      468344 :       op = BIT_AND_EXPR;
   17853                 :      468344 :       break;
   17854                 :             : 
   17855                 :      457024 :     case CPP_OR:
   17856                 :      457024 :       op = BIT_IOR_EXPR;
   17857                 :      457024 :       break;
   17858                 :             : 
   17859                 :      379329 :     case CPP_COMPL:
   17860                 :      379329 :       op = BIT_NOT_EXPR;
   17861                 :      379329 :       break;
   17862                 :             : 
   17863                 :       93990 :     case CPP_NOT:
   17864                 :       93990 :       op = TRUTH_NOT_EXPR;
   17865                 :       93990 :       break;
   17866                 :             : 
   17867                 :    11902528 :     case CPP_EQ:
   17868                 :    11902528 :       assop = true;
   17869                 :    11902528 :       op = NOP_EXPR;
   17870                 :    11902528 :       break;
   17871                 :             : 
   17872                 :     1577525 :     case CPP_LESS:
   17873                 :     1577525 :       op = LT_EXPR;
   17874                 :     1577525 :       break;
   17875                 :             : 
   17876                 :     1367353 :     case CPP_GREATER:
   17877                 :     1367353 :       op = GT_EXPR;
   17878                 :     1367353 :       break;
   17879                 :             : 
   17880                 :     1409020 :     case CPP_PLUS_EQ:
   17881                 :     1409020 :       assop = true;
   17882                 :     1409020 :       op = PLUS_EXPR;
   17883                 :     1409020 :       break;
   17884                 :             : 
   17885                 :     1063998 :     case CPP_MINUS_EQ:
   17886                 :     1063998 :       assop = true;
   17887                 :     1063998 :       op = MINUS_EXPR;
   17888                 :     1063998 :       break;
   17889                 :             : 
   17890                 :      631746 :     case CPP_MULT_EQ:
   17891                 :      631746 :       assop = true;
   17892                 :      631746 :       op = MULT_EXPR;
   17893                 :      631746 :       break;
   17894                 :             : 
   17895                 :      668618 :     case CPP_DIV_EQ:
   17896                 :      668618 :       assop = true;
   17897                 :      668618 :       op = TRUNC_DIV_EXPR;
   17898                 :      668618 :       break;
   17899                 :             : 
   17900                 :      459382 :     case CPP_MOD_EQ:
   17901                 :      459382 :       assop = true;
   17902                 :      459382 :       op = TRUNC_MOD_EXPR;
   17903                 :      459382 :       break;
   17904                 :             : 
   17905                 :      739586 :     case CPP_XOR_EQ:
   17906                 :      739586 :       assop = true;
   17907                 :      739586 :       op = BIT_XOR_EXPR;
   17908                 :      739586 :       break;
   17909                 :             : 
   17910                 :      733902 :     case CPP_AND_EQ:
   17911                 :      733902 :       assop = true;
   17912                 :      733902 :       op = BIT_AND_EXPR;
   17913                 :      733902 :       break;
   17914                 :             : 
   17915                 :      737746 :     case CPP_OR_EQ:
   17916                 :      737746 :       assop = true;
   17917                 :      737746 :       op = BIT_IOR_EXPR;
   17918                 :      737746 :       break;
   17919                 :             : 
   17920                 :     3008366 :     case CPP_LSHIFT:
   17921                 :     3008366 :       op = LSHIFT_EXPR;
   17922                 :     3008366 :       break;
   17923                 :             : 
   17924                 :     2505758 :     case CPP_RSHIFT:
   17925                 :     2505758 :       op = RSHIFT_EXPR;
   17926                 :     2505758 :       break;
   17927                 :             : 
   17928                 :      467490 :     case CPP_LSHIFT_EQ:
   17929                 :      467490 :       assop = true;
   17930                 :      467490 :       op = LSHIFT_EXPR;
   17931                 :      467490 :       break;
   17932                 :             : 
   17933                 :      462518 :     case CPP_RSHIFT_EQ:
   17934                 :      462518 :       assop = true;
   17935                 :      462518 :       op = RSHIFT_EXPR;
   17936                 :      462518 :       break;
   17937                 :             : 
   17938                 :     3895889 :     case CPP_EQ_EQ:
   17939                 :     3895889 :       op = EQ_EXPR;
   17940                 :     3895889 :       break;
   17941                 :             : 
   17942                 :     2493665 :     case CPP_NOT_EQ:
   17943                 :     2493665 :       op = NE_EXPR;
   17944                 :     2493665 :       break;
   17945                 :             : 
   17946                 :     1365000 :     case CPP_LESS_EQ:
   17947                 :     1365000 :       op = LE_EXPR;
   17948                 :     1365000 :       break;
   17949                 :             : 
   17950                 :     1369637 :     case CPP_GREATER_EQ:
   17951                 :     1369637 :       op = GE_EXPR;
   17952                 :     1369637 :       break;
   17953                 :             : 
   17954                 :      395786 :     case CPP_SPACESHIP:
   17955                 :      395786 :       op = SPACESHIP_EXPR;
   17956                 :      395786 :       break;
   17957                 :             : 
   17958                 :      146300 :     case CPP_AND_AND:
   17959                 :      146300 :       op = TRUTH_ANDIF_EXPR;
   17960                 :      146300 :       break;
   17961                 :             : 
   17962                 :      146288 :     case CPP_OR_OR:
   17963                 :      146288 :       op = TRUTH_ORIF_EXPR;
   17964                 :      146288 :       break;
   17965                 :             : 
   17966                 :     1854167 :     case CPP_PLUS_PLUS:
   17967                 :     1854167 :       op = POSTINCREMENT_EXPR;
   17968                 :     1854167 :       break;
   17969                 :             : 
   17970                 :      939262 :     case CPP_MINUS_MINUS:
   17971                 :      939262 :       op = PREDECREMENT_EXPR;
   17972                 :      939262 :       break;
   17973                 :             : 
   17974                 :        4690 :     case CPP_COMMA:
   17975                 :        4690 :       op = COMPOUND_EXPR;
   17976                 :        4690 :       break;
   17977                 :             : 
   17978                 :         138 :     case CPP_DEREF_STAR:
   17979                 :         138 :       op = MEMBER_REF;
   17980                 :         138 :       break;
   17981                 :             : 
   17982                 :      698323 :     case CPP_DEREF:
   17983                 :      698323 :       op = COMPONENT_REF;
   17984                 :      698323 :       break;
   17985                 :             : 
   17986                 :          16 :     case CPP_QUERY:
   17987                 :          16 :       op = COND_EXPR;
   17988                 :             :       /* Consume the `?'.  */
   17989                 :          16 :       cp_lexer_consume_token (parser->lexer);
   17990                 :             :       /* Look for the matching `:'.  */
   17991                 :          16 :       cp_parser_require (parser, CPP_COLON, RT_COLON);
   17992                 :          16 :       consumed = true;
   17993                 :          16 :       break;
   17994                 :             : 
   17995                 :     8264895 :     case CPP_OPEN_PAREN:
   17996                 :     8264895 :       {
   17997                 :             :         /* Consume the `('.  */
   17998                 :     8264895 :         matching_parens parens;
   17999                 :     8264895 :         parens.consume_open (parser);
   18000                 :             :         /* Look for the matching `)'.  */
   18001                 :     8264895 :         token = parens.require_close (parser);
   18002                 :     8264895 :         if (token)
   18003                 :     8264887 :           end_loc = token->location;
   18004                 :     8264895 :         op = CALL_EXPR;
   18005                 :     8264895 :         consumed = true;
   18006                 :     8264895 :         break;
   18007                 :             :       }
   18008                 :             : 
   18009                 :     1761708 :     case CPP_OPEN_SQUARE:
   18010                 :             :       /* Consume the `['.  */
   18011                 :     1761708 :       cp_lexer_consume_token (parser->lexer);
   18012                 :             :       /* Look for the matching `]'.  */
   18013                 :     1761708 :       token = cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
   18014                 :     1761708 :       if (token)
   18015                 :     1761708 :         end_loc = token->location;
   18016                 :             :       op = ARRAY_REF;
   18017                 :             :       consumed = true;
   18018                 :             :       break;
   18019                 :             : 
   18020                 :          17 :     case CPP_UTF8STRING:
   18021                 :          17 :     case CPP_UTF8STRING_USERDEF:
   18022                 :          17 :       utf8 = true;
   18023                 :             :       /* FALLTHRU */
   18024                 :      527997 :     case CPP_STRING:
   18025                 :      527997 :     case CPP_WSTRING:
   18026                 :      527997 :     case CPP_STRING16:
   18027                 :      527997 :     case CPP_STRING32:
   18028                 :      527997 :     case CPP_STRING_USERDEF:
   18029                 :      527997 :     case CPP_WSTRING_USERDEF:
   18030                 :      527997 :     case CPP_STRING16_USERDEF:
   18031                 :      527997 :     case CPP_STRING32_USERDEF:
   18032                 :      527997 :       {
   18033                 :      527997 :         tree string_tree;
   18034                 :      527997 :         int sz, len;
   18035                 :             : 
   18036                 :      527997 :         if (cxx_dialect == cxx98)
   18037                 :           4 :           maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);
   18038                 :             : 
   18039                 :             :         /* Consume the string.  */
   18040                 :      527997 :         cp_expr str = cp_parser_userdef_string_literal (parser,
   18041                 :             :                                                         /*lookup_udlit=*/false);
   18042                 :      527997 :         if (str == error_mark_node)
   18043                 :           0 :           return error_mark_node;
   18044                 :      527997 :         else if (TREE_CODE (str) == USERDEF_LITERAL)
   18045                 :             :           {
   18046                 :      526246 :             string_tree = USERDEF_LITERAL_VALUE (str.get_value ());
   18047                 :      526246 :             id = USERDEF_LITERAL_SUFFIX_ID (str.get_value ());
   18048                 :      526246 :             end_loc = str.get_location ();
   18049                 :             :           }
   18050                 :             :         else
   18051                 :             :           {
   18052                 :        1751 :             string_tree = str;
   18053                 :             :             /* Look for the suffix identifier.  */
   18054                 :        1751 :             token = cp_lexer_peek_token (parser->lexer);
   18055                 :        1751 :             if (token->type == CPP_NAME)
   18056                 :             :               {
   18057                 :        1739 :                 id = cp_parser_identifier (parser);
   18058                 :        1739 :                 end_loc = token->location;
   18059                 :             :               }
   18060                 :          12 :             else if (token->type == CPP_KEYWORD)
   18061                 :             :               {
   18062                 :           3 :                 error ("unexpected keyword;"
   18063                 :             :                        " remove space between quotes and suffix identifier");
   18064                 :           3 :                 return error_mark_node;
   18065                 :             :               }
   18066                 :             :             else
   18067                 :             :               {
   18068                 :           9 :                 error ("expected suffix identifier");
   18069                 :           9 :                 return error_mark_node;
   18070                 :             :               }
   18071                 :             :           }
   18072                 :      527985 :         sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
   18073                 :             :                                (TREE_TYPE (TREE_TYPE (string_tree))));
   18074                 :      527985 :         len = TREE_STRING_LENGTH (string_tree) / sz - 1;
   18075                 :      527985 :         if (len != 0)
   18076                 :             :           {
   18077                 :          36 :             error ("expected empty string after %<operator%> keyword");
   18078                 :          36 :             return error_mark_node;
   18079                 :             :           }
   18080                 :      527949 :         if (utf8 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string_tree)))
   18081                 :      527935 :             != char_type_node)
   18082                 :             :           {
   18083                 :          76 :             error ("invalid encoding prefix in literal operator");
   18084                 :          76 :             return error_mark_node;
   18085                 :             :           }
   18086                 :      527873 :         if (id != error_mark_node)
   18087                 :             :           {
   18088                 :      527873 :             const char *name = IDENTIFIER_POINTER (id);
   18089                 :      527873 :             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                 :      527873 :         location_t combined_loc
   18097                 :      527873 :           = make_location (start_loc, start_loc, parser->lexer);
   18098                 :      527873 :         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                 :    61251766 :   if (op != ERROR_MARK)
   18109                 :             :     {
   18110                 :    58169102 :       id = ovl_op_identifier (assop, op);
   18111                 :    58169102 :       if (!consumed)
   18112                 :    47100492 :         cp_lexer_consume_token (parser->lexer);
   18113                 :             :     }
   18114                 :             :   /* Otherwise, no valid operator name was present.  */
   18115                 :             :   else
   18116                 :             :     {
   18117                 :     3082664 :       cp_parser_error (parser, "expected operator");
   18118                 :     3082664 :       id = error_mark_node;
   18119                 :             :     }
   18120                 :             : 
   18121                 :    61251766 :   start_loc = make_location (start_loc, start_loc, get_finish (end_loc));
   18122                 :    61251766 :   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                 :             : 
   18154                 :             : static void
   18155                 :    72766826 : cp_parser_template_declaration (cp_parser* parser, bool member_p)
   18156                 :             : {
   18157                 :             :   /* Check for `export'.  */
   18158                 :    72766826 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT))
   18159                 :             :     {
   18160                 :             :       /* Consume the `export' token.  */
   18161                 :          26 :       cp_lexer_consume_token (parser->lexer);
   18162                 :             :       /* Warn that this use of export is deprecated.  */
   18163                 :          26 :       if (cxx_dialect < cxx11)
   18164                 :           6 :         warning (0, "keyword %<export%> not implemented, and will be ignored");
   18165                 :          20 :       else if (cxx_dialect < cxx20)
   18166                 :          13 :         warning (0, "keyword %<export%> is deprecated, and is ignored");
   18167                 :             :       else
   18168                 :           7 :         warning (0, "keyword %<export%> is enabled with %<-fmodules-ts%>");
   18169                 :             :     }
   18170                 :             : 
   18171                 :    72766826 :   cp_parser_template_declaration_after_export (parser, member_p);
   18172                 :    72766817 : }
   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                 :             : 
   18183                 :             : static tree
   18184                 :    75019297 : cp_parser_template_parameter_list (cp_parser* parser)
   18185                 :             : {
   18186                 :    75019297 :   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                 :    75019297 :   auto_suppress_location_wrappers sentinel;
   18192                 :             : 
   18193                 :    75019297 :   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                 :   211030733 :   while (true)
   18202                 :             :     {
   18203                 :   143025015 :       tree parameter;
   18204                 :   143025015 :       bool is_non_type;
   18205                 :   143025015 :       bool is_parameter_pack;
   18206                 :   143025015 :       location_t parm_loc;
   18207                 :             : 
   18208                 :             :       /* Parse the template-parameter.  */
   18209                 :   143025015 :       parm_loc = cp_lexer_peek_token (parser->lexer)->location;
   18210                 :   143025015 :       parameter = cp_parser_template_parameter (parser,
   18211                 :             :                                                 &is_non_type,
   18212                 :             :                                                 &is_parameter_pack);
   18213                 :             :       /* Add it to the list.  */
   18214                 :   143025015 :       if (parameter != error_mark_node)
   18215                 :   143024868 :         parameter_list = process_template_parm (parameter_list,
   18216                 :             :                                                 parm_loc,
   18217                 :             :                                                 parameter,
   18218                 :             :                                                 is_non_type,
   18219                 :             :                                                 is_parameter_pack);
   18220                 :             :       else
   18221                 :             :        {
   18222                 :         147 :          tree err_parm = build_tree_list (parameter, parameter);
   18223                 :         147 :          parameter_list = chainon (parameter_list, err_parm);
   18224                 :             :        }
   18225                 :             : 
   18226                 :             :       /* If the next token is not a `,', we're done.  */
   18227                 :   143025015 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   18228                 :             :         break;
   18229                 :             :       /* Otherwise, consume the `,' token.  */
   18230                 :    68005718 :       cp_lexer_consume_token (parser->lexer);
   18231                 :    68005718 :     }
   18232                 :             : 
   18233                 :    75019297 :   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                 :             : 
   18250                 :             : static tree
   18251                 :          40 : cp_parser_introduction_list (cp_parser *parser)
   18252                 :             : {
   18253                 :          40 :   vec<tree, va_gc> *introduction_vec = make_tree_vector ();
   18254                 :             : 
   18255                 :          74 :   while (true)
   18256                 :             :     {
   18257                 :          57 :       bool is_pack = cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS);
   18258                 :          57 :       if (is_pack)
   18259                 :          11 :         cp_lexer_consume_token (parser->lexer);
   18260                 :             : 
   18261                 :          57 :       tree identifier = cp_parser_identifier (parser);
   18262                 :          57 :       if (identifier == error_mark_node)
   18263                 :             :         break;
   18264                 :             : 
   18265                 :             :       /* Build placeholder. */
   18266                 :          56 :       tree parm = build_nt (WILDCARD_DECL);
   18267                 :          56 :       DECL_SOURCE_LOCATION (parm)
   18268                 :          56 :         = cp_lexer_peek_token (parser->lexer)->location;
   18269                 :          56 :       DECL_NAME (parm) = identifier;
   18270                 :          56 :       WILDCARD_PACK_P (parm) = is_pack;
   18271                 :          56 :       vec_safe_push (introduction_vec, parm);
   18272                 :             : 
   18273                 :             :       /* If the next token is not a `,', we're done.  */
   18274                 :          56 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   18275                 :             :         break;
   18276                 :             :       /* Otherwise, consume the `,' token.  */
   18277                 :          17 :       cp_lexer_consume_token (parser->lexer);
   18278                 :          17 :     }
   18279                 :             : 
   18280                 :             :   /* Convert the vec into a TREE_VEC.  */
   18281                 :          40 :   tree introduction_list = make_tree_vec (introduction_vec->length ());
   18282                 :          40 :   unsigned int n;
   18283                 :          40 :   tree parm;
   18284                 :         136 :   FOR_EACH_VEC_ELT (*introduction_vec, n, parm)
   18285                 :          56 :     TREE_VEC_ELT (introduction_list, n) = parm;
   18286                 :             : 
   18287                 :          40 :   release_tree_vector (introduction_vec);
   18288                 :          40 :   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                 :             : 
   18294                 :             : static inline cp_declarator*
   18295                 :     1705701 : get_id_declarator (cp_declarator *declarator)
   18296                 :             : {
   18297                 :     1705701 :   cp_declarator *d = declarator;
   18298                 :     3347140 :   while (d && d->kind != cdk_id)
   18299                 :      829843 :     d = d->declarator;
   18300                 :     2517297 :   return d;
   18301                 :             : }
   18302                 :             : 
   18303                 :             : /* Get the unqualified-id from the DECLARATOR or NULL_TREE if this
   18304                 :             :    is an abstract declarator. */
   18305                 :             : 
   18306                 :             : static inline tree
   18307                 :     1705701 : get_unqualified_id (cp_declarator *declarator)
   18308                 :             : {
   18309                 :     1705701 :   declarator = get_id_declarator (declarator);
   18310                 :     1705701 :   if (declarator)
   18311                 :     1705677 :     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                 :             : 
   18318                 :             : static inline bool
   18319                 :    20209270 : is_constrained_parameter (tree type)
   18320                 :             : {
   18321                 :    20209270 :   return (type
   18322                 :    19485015 :           && TREE_CODE (type) == TYPE_DECL
   18323                 :    12440666 :           && CONSTRAINED_PARM_CONCEPT (type)
   18324                 :    22108773 :           && DECL_P (CONSTRAINED_PARM_CONCEPT (type)));
   18325                 :             : }
   18326                 :             : 
   18327                 :             : /* Returns true if PARM declares a constrained-parameter. */
   18328                 :             : 
   18329                 :             : static inline bool
   18330                 :    13096462 : is_constrained_parameter (cp_parameter_declarator *parm)
   18331                 :             : {
   18332                 :    13096462 :   return is_constrained_parameter (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                 :             : 
   18338                 :             : bool
   18339                 :     1687469 : cp_parser_check_constrained_type_parm (cp_parser *parser,
   18340                 :             :                                        cp_parameter_declarator *parm)
   18341                 :             : {
   18342                 :     1687469 :   if (!parm->declarator)
   18343                 :             :     return true;
   18344                 :             : 
   18345                 :     1687447 :   if (parm->declarator->kind != cdk_id)
   18346                 :             :     {
   18347                 :           6 :       cp_parser_error (parser, "invalid constrained type parameter");
   18348                 :           6 :       return false;
   18349                 :             :     }
   18350                 :             : 
   18351                 :             :   /* Don't allow cv-qualified type parameters.  */
   18352                 :     1687441 :   if (decl_spec_seq_has_spec_p (&parm->decl_specifiers, ds_const)
   18353                 :     1687441 :       || decl_spec_seq_has_spec_p (&parm->decl_specifiers, ds_volatile))
   18354                 :             :     {
   18355                 :           2 :       cp_parser_error (parser, "cv-qualified type parameter");
   18356                 :           2 :       return false;
   18357                 :             :     }
   18358                 :             : 
   18359                 :             :   return true;
   18360                 :             : }
   18361                 :             : 
   18362                 :             : /* Finish parsing/processing a template type parameter and checking
   18363                 :             :    various restrictions. */
   18364                 :             : 
   18365                 :             : static inline tree
   18366                 :     1687465 : cp_parser_constrained_type_template_parm (cp_parser *parser,
   18367                 :             :                                           tree id,
   18368                 :             :                                           cp_parameter_declarator* parmdecl)
   18369                 :             : {
   18370                 :     1687465 :   if (cp_parser_check_constrained_type_parm (parser, parmdecl))
   18371                 :     1687457 :     return finish_template_type_parm (class_type_node, id);
   18372                 :             :   else
   18373                 :           8 :     return error_mark_node;
   18374                 :             : }
   18375                 :             : 
   18376                 :             : static tree
   18377                 :           4 : finish_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                 :           4 :   tree saved_parms = current_template_parms;
   18382                 :           4 :   begin_template_parm_list ();
   18383                 :           4 :   current_template_parms = DECL_TEMPLATE_PARMS (proto);
   18384                 :           4 :   end_template_parm_list ();
   18385                 :             : 
   18386                 :           4 :   tree parm = finish_template_template_parm (class_type_node, id);
   18387                 :           4 :   current_template_parms = saved_parms;
   18388                 :             : 
   18389                 :           4 :   return parm;
   18390                 :             : }
   18391                 :             : 
   18392                 :             : /* Finish parsing/processing a template template parameter by borrowing
   18393                 :             :    the template parameter list from the prototype parameter.  */
   18394                 :             : 
   18395                 :             : static tree
   18396                 :           4 : cp_parser_constrained_template_template_parm (cp_parser *parser,
   18397                 :             :                                               tree proto,
   18398                 :             :                                               tree id,
   18399                 :             :                                               cp_parameter_declarator *parmdecl)
   18400                 :             : {
   18401                 :           4 :   if (!cp_parser_check_constrained_type_parm (parser, parmdecl))
   18402                 :           0 :     return error_mark_node;
   18403                 :           4 :   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                 :             : 
   18409                 :             : static tree
   18410                 :           4 : cp_parser_constrained_non_type_template_parm (bool *is_non_type,
   18411                 :             :                                               cp_parameter_declarator *parm)
   18412                 :             : {
   18413                 :           4 :   *is_non_type = true;
   18414                 :           4 :   cp_declarator *decl = parm->declarator;
   18415                 :           4 :   cp_decl_specifier_seq *specs = &parm->decl_specifiers;
   18416                 :           4 :   specs->type = TREE_TYPE (DECL_INITIAL (specs->type));
   18417                 :           4 :   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                 :             : 
   18425                 :             : static tree
   18426                 :     1687473 : finish_constrained_parameter (cp_parser *parser,
   18427                 :             :                               cp_parameter_declarator *parmdecl,
   18428                 :             :                               bool *is_non_type)
   18429                 :             : {
   18430                 :     1687473 :   tree decl = parmdecl->decl_specifiers.type;
   18431                 :     1687473 :   tree id = get_unqualified_id (parmdecl->declarator);
   18432                 :     1687473 :   tree def = parmdecl->default_argument;
   18433                 :     1687473 :   tree proto = DECL_INITIAL (decl);
   18434                 :             : 
   18435                 :             :   /* Build the parameter. Return an error if the declarator was invalid. */
   18436                 :     1687473 :   tree parm;
   18437                 :     1687473 :   if (TREE_CODE (proto) == TYPE_DECL)
   18438                 :     1687465 :     parm = cp_parser_constrained_type_template_parm (parser, id, parmdecl);
   18439                 :           8 :   else if (TREE_CODE (proto) == TEMPLATE_DECL)
   18440                 :           4 :     parm = cp_parser_constrained_template_template_parm (parser, proto, id,
   18441                 :             :                                                          parmdecl);
   18442                 :             :   else
   18443                 :           4 :     parm = cp_parser_constrained_non_type_template_parm (is_non_type, parmdecl);
   18444                 :     1687473 :   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                 :     1687465 :   parm = build_tree_list (def, parm);
   18450                 :     1687465 :   TEMPLATE_PARM_CONSTRAINTS (parm) = decl;
   18451                 :             : 
   18452                 :     1687465 :   return parm;
   18453                 :             : }
   18454                 :             : 
   18455                 :             : /* Returns true if the parsed type actually represents the declaration
   18456                 :             :    of a type template-parameter.  */
   18457                 :             : 
   18458                 :             : static bool
   18459                 :     3607010 : declares_constrained_type_template_parameter (tree type)
   18460                 :             : {
   18461                 :     3607010 :   return (is_constrained_parameter (type)
   18462                 :     3607010 :           && 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                 :             : 
   18468                 :             : static bool
   18469                 :     3505798 : declares_constrained_template_template_parameter (tree type)
   18470                 :             : {
   18471                 :     3505798 :   return (is_constrained_parameter (type)
   18472                 :     3505798 :           && 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                 :             : 
   18478                 :             : static tree
   18479                 :     7387458 : cp_parser_default_type_template_argument (cp_parser *parser)
   18480                 :             : {
   18481                 :     7387458 :   gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_EQ));
   18482                 :             : 
   18483                 :             :   /* Consume the `=' token.  */
   18484                 :     7387458 :   cp_lexer_consume_token (parser->lexer);
   18485                 :             : 
   18486                 :     7387458 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   18487                 :             : 
   18488                 :             :   /* Tell cp_parser_lambda_expression this is a default argument.  */
   18489                 :     7387458 :   auto lvf = make_temp_override (parser->local_variables_forbidden_p);
   18490                 :     7387458 :   parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
   18491                 :             : 
   18492                 :             :   /* Parse the default-argument.  */
   18493                 :     7387458 :   push_deferring_access_checks (dk_no_deferred);
   18494                 :    14774916 :   tree default_argument = cp_parser_type_id (parser,
   18495                 :             :                                              CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
   18496                 :             :                                              NULL);
   18497                 :     7387458 :   pop_deferring_access_checks ();
   18498                 :             : 
   18499                 :     7387458 :   if (flag_concepts && type_uses_auto (default_argument))
   18500                 :             :     {
   18501                 :           2 :       error_at (token->location,
   18502                 :             :                 "invalid use of %<auto%> in default template argument");
   18503                 :           2 :       return error_mark_node;
   18504                 :             :     }
   18505                 :             : 
   18506                 :             :   return default_argument;
   18507                 :     7387458 : }
   18508                 :             : 
   18509                 :             : /* Parse a default argument for a template template-parameter.  */
   18510                 :             : 
   18511                 :             : static tree
   18512                 :         952 : cp_parser_default_template_template_argument (cp_parser *parser)
   18513                 :             : {
   18514                 :         952 :   gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_EQ));
   18515                 :             : 
   18516                 :         952 :   bool is_template;
   18517                 :             : 
   18518                 :             :   /* Consume the `='.  */
   18519                 :         952 :   cp_lexer_consume_token (parser->lexer);
   18520                 :             :   /* Parse the id-expression.  */
   18521                 :         952 :   push_deferring_access_checks (dk_no_deferred);
   18522                 :             :   /* save token before parsing the id-expression, for error
   18523                 :             :      reporting */
   18524                 :         952 :   const cp_token* token = cp_lexer_peek_token (parser->lexer);
   18525                 :         952 :   tree default_argument
   18526                 :         952 :     = 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                 :         952 :   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                 :         948 :     default_argument
   18540                 :         948 :       = 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                 :         948 :                                token->location);
   18547                 :             :   /* See if the default argument is valid.  */
   18548                 :         952 :   default_argument = check_template_template_default_arg (default_argument);
   18549                 :         952 :   pop_deferring_access_checks ();
   18550                 :         952 :   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                 :             : 
   18565                 :             : static tree
   18566                 :   143025015 : cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
   18567                 :             :                               bool *is_parameter_pack)
   18568                 :             : {
   18569                 :   143025015 :   cp_token *token;
   18570                 :   143025015 :   cp_parameter_declarator *parameter_declarator;
   18571                 :   143025015 :   tree parm;
   18572                 :             : 
   18573                 :             :   /* Assume it is a type parameter or a template parameter.  */
   18574                 :   143025015 :   *is_non_type = false;
   18575                 :             :   /* Assume it not a parameter pack. */
   18576                 :   143025015 :   *is_parameter_pack = false;
   18577                 :             :   /* Peek at the next token.  */
   18578                 :   143025015 :   token = cp_lexer_peek_token (parser->lexer);
   18579                 :             :   /* If it is `template', we have a type-parameter.  */
   18580                 :   143025015 :   if (token->keyword == RID_TEMPLATE)
   18581                 :      296580 :     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                 :   142728435 :   if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
   18596                 :             :     {
   18597                 :             :       /* Peek at the token after `class' or `typename'.  */
   18598                 :   129735661 :       token = cp_lexer_peek_nth_token (parser->lexer, 2);
   18599                 :             :       /* If it's an ellipsis, we have a template type parameter
   18600                 :             :          pack. */
   18601                 :   129735661 :       if (token->type == CPP_ELLIPSIS)
   18602                 :     7433219 :         return cp_parser_type_parameter (parser, is_parameter_pack);
   18603                 :             :       /* If it's an identifier, skip it.  */
   18604                 :   122302442 :       if (token->type == CPP_NAME)
   18605                 :   117515673 :         token = cp_lexer_peek_nth_token (parser->lexer, 3);
   18606                 :             :       /* Now, see if the token looks like the end of a template
   18607                 :             :          parameter.  */
   18608                 :   122302442 :       if (token->type == CPP_COMMA
   18609                 :             :           || token->type == CPP_EQ
   18610                 :             :           || token->type == CPP_GREATER)
   18611                 :   122198754 :         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                 :    13096462 :   parameter_declarator
   18623                 :    13096462 :      = cp_parser_parameter_declaration (parser,
   18624                 :             :                                         CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
   18625                 :             :                                         /*template_parm_p=*/true,
   18626                 :             :                                         /*parenthesized_p=*/NULL);
   18627                 :             : 
   18628                 :    13096462 :   if (!parameter_declarator)
   18629                 :           0 :     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                 :    13096462 :   if (parameter_declarator->template_parameter_pack_p)
   18634                 :      582304 :     *is_parameter_pack = true;
   18635                 :             : 
   18636                 :    13096462 :   if (parameter_declarator->default_argument)
   18637                 :             :     {
   18638                 :             :       /* Can happen in some cases of erroneous input (c++/34892).  */
   18639                 :     2111640 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   18640                 :             :         /* Consume the `...' for better error recovery.  */
   18641                 :           4 :         cp_lexer_consume_token (parser->lexer);
   18642                 :             :     }
   18643                 :             : 
   18644                 :             :   /* The parameter may have been constrained type parameter.  */
   18645                 :    13096462 :   if (is_constrained_parameter (parameter_declarator))
   18646                 :     1687473 :     return finish_constrained_parameter (parser,
   18647                 :             :                                          parameter_declarator,
   18648                 :     1687473 :                                          is_non_type);
   18649                 :             : 
   18650                 :             :   // Now we're sure that the parameter is a non-type parameter.
   18651                 :    11408989 :   *is_non_type = true;
   18652                 :             : 
   18653                 :    11408989 :   parm = grokdeclarator (parameter_declarator->declarator,
   18654                 :             :                          &parameter_declarator->decl_specifiers,
   18655                 :             :                          TPARM, /*initialized=*/0,
   18656                 :             :                          /*attrlist=*/NULL);
   18657                 :    11408989 :   if (parm == error_mark_node)
   18658                 :             :     return error_mark_node;
   18659                 :             : 
   18660                 :    11408850 :   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                 :             : 
   18686                 :             : static tree
   18687                 :   129928553 : cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
   18688                 :             : {
   18689                 :   129928553 :   cp_token *token;
   18690                 :   129928553 :   tree parameter;
   18691                 :             : 
   18692                 :             :   /* Look for a keyword to tell us what kind of parameter this is.  */
   18693                 :   129928553 :   token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_TYPENAME_TEMPLATE);
   18694                 :   129928553 :   if (!token)
   18695                 :           0 :     return error_mark_node;
   18696                 :             : 
   18697                 :   129928553 :   switch (token->keyword)
   18698                 :             :     {
   18699                 :   129631973 :     case RID_CLASS:
   18700                 :   129631973 :     case RID_TYPENAME:
   18701                 :   129631973 :       {
   18702                 :   129631973 :         tree identifier;
   18703                 :   129631973 :         tree default_argument;
   18704                 :             : 
   18705                 :             :         /* If the next token is an ellipsis, we have a template
   18706                 :             :            argument pack. */
   18707                 :   129631973 :         if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   18708                 :             :           {
   18709                 :             :             /* Consume the `...' token. */
   18710                 :     7433219 :             cp_lexer_consume_token (parser->lexer);
   18711                 :     7433219 :             maybe_warn_variadic_templates ();
   18712                 :             : 
   18713                 :     7433219 :             *is_parameter_pack = true;
   18714                 :             :           }
   18715                 :             : 
   18716                 :             :         /* If the next token is an identifier, then it names the
   18717                 :             :            parameter.  */
   18718                 :   129631973 :         if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   18719                 :   124478391 :           identifier = cp_parser_identifier (parser);
   18720                 :             :         else
   18721                 :             :           identifier = NULL_TREE;
   18722                 :             : 
   18723                 :             :         /* Create the parameter.  */
   18724                 :   129631973 :         parameter = finish_template_type_parm (class_type_node, identifier);
   18725                 :             : 
   18726                 :             :         /* If the next token is an `=', we have a default argument.  */
   18727                 :   129631973 :         if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   18728                 :             :           {
   18729                 :     7286246 :             default_argument
   18730                 :     7286246 :               = cp_parser_default_type_template_argument (parser);
   18731                 :             : 
   18732                 :             :             /* Template parameter packs cannot have default
   18733                 :             :                arguments. */
   18734                 :     7286246 :             if (*is_parameter_pack)
   18735                 :             :               {
   18736                 :           9 :                 if (identifier)
   18737                 :           6 :                   error_at (token->location,
   18738                 :             :                             "template parameter pack %qD cannot have a "
   18739                 :             :                             "default argument", identifier);
   18740                 :             :                 else
   18741                 :           3 :                   error_at (token->location,
   18742                 :             :                             "template parameter packs cannot have "
   18743                 :             :                             "default arguments");
   18744                 :             :                 default_argument = NULL_TREE;
   18745                 :             :               }
   18746                 :     7286237 :             else if (check_for_bare_parameter_packs (default_argument))
   18747                 :           9 :               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                 :   129631973 :         parameter = build_tree_list (default_argument, parameter);
   18755                 :             :       }
   18756                 :   129631973 :       break;
   18757                 :             : 
   18758                 :      296580 :     case RID_TEMPLATE:
   18759                 :      296580 :       {
   18760                 :      296580 :         tree identifier;
   18761                 :      296580 :         tree default_argument;
   18762                 :             : 
   18763                 :             :         /* Look for the `<'.  */
   18764                 :      296580 :         cp_parser_require (parser, CPP_LESS, RT_LESS);
   18765                 :             :         /* Parse the template-parameter-list.  */
   18766                 :      296580 :         cp_parser_template_parameter_list (parser);
   18767                 :             :         /* Look for the `>'.  */
   18768                 :      296580 :         cp_parser_require (parser, CPP_GREATER, RT_GREATER);
   18769                 :             : 
   18770                 :             :         /* If template requirements are present, parse them.  */
   18771                 :      296580 :         if (flag_concepts)
   18772                 :             :           {
   18773                 :       80467 :             tree reqs = get_shorthand_constraints (current_template_parms);
   18774                 :       80467 :             if (tree dreqs = cp_parser_requires_clause_opt (parser, false))
   18775                 :           9 :               reqs = combine_constraint_expressions (reqs, dreqs);
   18776                 :       80467 :             TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
   18777                 :             :           }
   18778                 :             : 
   18779                 :             :         /* Look for the `class' or 'typename' keywords.  */
   18780                 :      296580 :         cp_parser_type_parameter_key (parser);
   18781                 :             :         /* If the next token is an ellipsis, we have a template
   18782                 :             :            argument pack. */
   18783                 :      296580 :         if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   18784                 :             :           {
   18785                 :             :             /* Consume the `...' token. */
   18786                 :         117 :             cp_lexer_consume_token (parser->lexer);
   18787                 :         117 :             maybe_warn_variadic_templates ();
   18788                 :             : 
   18789                 :         117 :             *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                 :      296580 :         if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
   18796                 :      296535 :             && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
   18797                 :      592886 :             && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   18798                 :             :           {
   18799                 :      296254 :             identifier = cp_parser_identifier (parser);
   18800                 :             :             /* Treat invalid names as if the parameter were nameless.  */
   18801                 :      296254 :             if (identifier == error_mark_node)
   18802                 :         334 :               identifier = NULL_TREE;
   18803                 :             :           }
   18804                 :             :         else
   18805                 :             :           identifier = NULL_TREE;
   18806                 :             : 
   18807                 :             :         /* Create the template parameter.  */
   18808                 :      296580 :         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                 :      296580 :         if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   18814                 :             :           {
   18815                 :         951 :             default_argument
   18816                 :         951 :               = cp_parser_default_template_template_argument (parser);
   18817                 :             : 
   18818                 :             :             /* Template parameter packs cannot have default
   18819                 :             :                arguments. */
   18820                 :         951 :             if (*is_parameter_pack)
   18821                 :             :               {
   18822                 :           0 :                 if (identifier)
   18823                 :           0 :                   error_at (token->location,
   18824                 :             :                             "template parameter pack %qD cannot "
   18825                 :             :                             "have a default argument",
   18826                 :             :                             identifier);
   18827                 :             :                 else
   18828                 :           0 :                   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                 :      296580 :         parameter = build_tree_list (default_argument, parameter);
   18839                 :             :       }
   18840                 :      296580 :       break;
   18841                 :             : 
   18842                 :           0 :     default:
   18843                 :           0 :       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                 :             : 
   18864                 :             : static tree
   18865                 :  3203388580 : cp_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                 :  3203388580 :   tree templ;
   18872                 :  3203388580 :   tree arguments;
   18873                 :  3203388580 :   tree template_id;
   18874                 :  3203388580 :   cp_token_position start_of_id = 0;
   18875                 :  3203388580 :   cp_token *next_token = NULL, *next_token_2 = NULL;
   18876                 :  3203388580 :   bool is_identifier;
   18877                 :             : 
   18878                 :             :   /* If the next token corresponds to a template-id, there is no need
   18879                 :             :      to reparse it.  */
   18880                 :  3203388580 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   18881                 :             : 
   18882                 :  3203388580 :   if (token->type == CPP_TEMPLATE_ID)
   18883                 :             :     {
   18884                 :   281004692 :       cp_lexer_consume_token (parser->lexer);
   18885                 :   281004692 :       return saved_checks_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                 :   688296206 :   if ((token->type != CPP_NAME && token->keyword != RID_OPERATOR)
   18891                 :  2954021740 :       || (token->type == CPP_NAME
   18892                 :  2234087682 :           && !cp_parser_nth_token_starts_template_argument_list_p
   18893                 :  2234087682 :                (parser, 2)))
   18894                 :             :     {
   18895                 :  2663403848 :       cp_parser_error (parser, "expected template-id");
   18896                 :  2663403848 :       return error_mark_node;
   18897                 :             :     }
   18898                 :             : 
   18899                 :             :   /* Remember where the template-id starts.  */
   18900                 :   517960080 :   if (cp_parser_uncommitted_to_tentative_parse_p (parser))
   18901                 :   258980040 :     start_of_id = cp_lexer_token_position (parser->lexer, false);
   18902                 :             : 
   18903                 :   258980040 :   push_deferring_access_checks (dk_deferred);
   18904                 :             : 
   18905                 :             :   /* Parse the template-name.  */
   18906                 :   258980040 :   is_identifier = false;
   18907                 :   258980040 :   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                 :   258980040 :   vec<deferred_access_check, va_gc> *checks = get_deferred_access_checks ();
   18915                 :   258980040 :   pop_deferring_access_checks ();
   18916                 :   258980040 :   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                 :   191384152 :   tentative_firewall firewall (parser);
   18923                 :   191384152 :   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                 :   191384152 :   if (((next_token = cp_lexer_peek_token (parser->lexer))->type
   18929                 :             :        == CPP_OPEN_SQUARE)
   18930                 :       31426 :       && next_token->flags & DIGRAPH
   18931                 :           1 :       && ((next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2))->type
   18932                 :             :           == CPP_COLON)
   18933                 :   191384153 :       && !(next_token_2->flags & PREV_WHITE))
   18934                 :             :     {
   18935                 :           1 :       cp_parser_parse_tentatively (parser);
   18936                 :             :       /* Change `:' into `::'.  */
   18937                 :           1 :       next_token_2->type = CPP_SCOPE;
   18938                 :             :       /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is
   18939                 :             :          CPP_LESS.  */
   18940                 :           1 :       cp_lexer_consume_token (parser->lexer);
   18941                 :             : 
   18942                 :             :       /* Parse the arguments.  */
   18943                 :           1 :       arguments = cp_parser_enclosed_template_argument_list (parser);
   18944                 :           1 :       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                 :           0 :           next_token_2->type = CPP_COLON;
   18950                 :           0 :           cp_parser_error (parser, "expected %<<%>");
   18951                 :           0 :           pop_deferring_access_checks ();
   18952                 :           0 :           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                 :           1 :       if (permerror (next_token->location,
   18957                 :             :                      "%<<::%> cannot begin a template-argument list"))
   18958                 :             :         {
   18959                 :           1 :           static bool hint = false;
   18960                 :           1 :           inform (next_token->location,
   18961                 :             :                   "%<<:%> is an alternate spelling for %<[%>."
   18962                 :             :                   " Insert whitespace between %<<%> and %<::%>");
   18963                 :           1 :           if (!hint && !flag_permissive)
   18964                 :             :             {
   18965                 :           0 :               inform (next_token->location, "(if you use %<-fpermissive%> "
   18966                 :             :                       "or %<-std=c++11%>, or %<-std=gnu++11%> G++ will "
   18967                 :             :                       "accept your code)");
   18968                 :           0 :               hint = true;
   18969                 :             :             }
   18970                 :             :         }
   18971                 :             :     }
   18972                 :             :   else
   18973                 :             :     {
   18974                 :             :       /* Look for the `<' that starts the template-argument-list.  */
   18975                 :   191384151 :       if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
   18976                 :             :         {
   18977                 :    11520773 :           pop_deferring_access_checks ();
   18978                 :    11520773 :           return error_mark_node;
   18979                 :             :         }
   18980                 :             :       /* Parse the arguments.  */
   18981                 :   179863378 :       arguments = cp_parser_enclosed_template_argument_list (parser);
   18982                 :             : 
   18983                 :   179863378 :       if ((cxx_dialect > cxx17)
   18984                 :    51040546 :           && (TREE_CODE (templ) == FUNCTION_DECL || identifier_p (templ))
   18985                 :       98733 :           && !template_keyword_p
   18986                 :   179863378 :           && (cp_parser_error_occurred (parser)
   18987                 :         214 :               || cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)))
   18988                 :             :         {
   18989                 :             :           /* This didn't go well.  */
   18990                 :         204 :           if (TREE_CODE (templ) == FUNCTION_DECL)
   18991                 :             :             {
   18992                 :             :               /* C++20 says that "function-name < a;" is now ill-formed.  */
   18993                 :          18 :               if (cp_parser_error_occurred (parser))
   18994                 :             :                 {
   18995                 :           8 :                   error_at (token->location, "invalid template-argument-list");
   18996                 :           8 :                   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                 :           1 :                 error_at (cp_lexer_peek_token (parser->lexer)->location,
   19003                 :             :                           "expected %<(%> after template-argument-list");
   19004                 :           9 :               if (start_of_id)
   19005                 :             :                 /* Purge all subsequent tokens.  */
   19006                 :           9 :                 cp_lexer_purge_tokens_after (parser->lexer, start_of_id);
   19007                 :             :             }
   19008                 :             :           else
   19009                 :         399 :             cp_parser_simulate_error (parser);
   19010                 :         204 :           pop_deferring_access_checks ();
   19011                 :         204 :           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                 :   179863175 :   location_t combined_loc
   19021                 :   179863175 :     = make_location (token->location, token->location, 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                 :   179863175 :   if (flag_concepts && check_auto_in_tmpl_args (templ, arguments))
   19030                 :           4 :     template_id = error_mark_node;
   19031                 :             :   /* Build a representation of the specialization.  */
   19032                 :   179863171 :   else if (identifier_p (templ))
   19033                 :      559473 :     template_id = build_min_nt_loc (combined_loc,
   19034                 :             :                                     TEMPLATE_ID_EXPR,
   19035                 :             :                                     templ, arguments);
   19036                 :   162091610 :   else if (DECL_TYPE_TEMPLATE_P (templ)
   19037                 :   189212106 :            || 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                 :   152183202 :       bool entering_scope
   19045                 :   152183202 :         = (template_parm_scope_p ()
   19046                 :   152183202 :            && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE));
   19047                 :   152183202 :       template_id
   19048                 :   152183202 :         = finish_template_type (templ, arguments, entering_scope);
   19049                 :             :     }
   19050                 :    27120496 :   else if (concept_definition_p (templ))
   19051                 :             :     {
   19052                 :             :       /* The caller will decide whether this is a concept check or type
   19053                 :             :          constraint.  */
   19054                 :     4508649 :       template_id = build2_loc (combined_loc, TEMPLATE_ID_EXPR,
   19055                 :             :                                 boolean_type_node, templ, arguments);
   19056                 :             :     }
   19057                 :    22611847 :   else if (variable_template_p (templ))
   19058                 :             :     {
   19059                 :     5399883 :       template_id = lookup_template_variable (templ, arguments, tf_warning_or_error);
   19060                 :     5399883 :       if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
   19061                 :     5399853 :         SET_EXPR_LOCATION (template_id, combined_loc);
   19062                 :             :     }
   19063                 :    17211964 :   else if (TREE_CODE (templ) == TYPE_DECL
   19064                 :    17211964 :            && TREE_CODE (TREE_TYPE (templ)) == TYPENAME_TYPE)
   19065                 :             :     {
   19066                 :             :       /* Some type template in dependent scope.  */
   19067                 :          28 :       tree &name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (templ));
   19068                 :          28 :       name = build_min_nt_loc (combined_loc,
   19069                 :             :                                TEMPLATE_ID_EXPR,
   19070                 :             :                                name, arguments);
   19071                 :          28 :       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                 :    17211936 :       gcc_assert (OVL_P (templ) || BASELINK_P (templ));
   19078                 :             : 
   19079                 :    17211936 :       template_id = lookup_template_function (templ, arguments);
   19080                 :    17211936 :       if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
   19081                 :    16912038 :         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                 :   179863172 :   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                 :   179863172 :       && !(cp_parser_error_occurred (parser)
   19094                 :         187 :            && cp_parser_parsing_tentatively (parser)
   19095                 :         187 :            && parser->in_declarator_p))
   19096                 :             :     {
   19097                 :             :       /* Reset the contents of the START_OF_ID token.  */
   19098                 :   179863137 :       token->type = CPP_TEMPLATE_ID;
   19099                 :   179863137 :       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                 :   179863137 :       token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
   19104                 :   179863137 :       token->tree_check_p = true;
   19105                 :   179863137 :       token->u.tree_check_value->value = template_id;
   19106                 :   179863137 :       token->u.tree_check_value->checks = get_deferred_access_checks ();
   19107                 :   179863137 :       token->keyword = RID_MAX;
   19108                 :             : 
   19109                 :             :       /* Purge all subsequent tokens.  */
   19110                 :   179863137 :       cp_lexer_purge_tokens_after (parser->lexer, 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                 :         164 :       if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
   19117                 :          67 :         error_at (token->location, "parse error in template argument list");
   19118                 :             :     }
   19119                 :             : 
   19120                 :   179863172 :   pop_to_parent_deferring_access_checks ();
   19121                 :   179863172 :   return template_id;
   19122                 :   191384149 : }
   19123                 :             : 
   19124                 :             : /* Like cp_parser_template_id, called in non-type context.  */
   19125                 :             : 
   19126                 :             : static tree
   19127                 :  1225921906 : cp_parser_template_id_expr (cp_parser *parser,
   19128                 :             :                             bool template_keyword_p,
   19129                 :             :                             bool check_dependency_p,
   19130                 :             :                             bool is_declaration)
   19131                 :             : {
   19132                 :  1225921906 :   tree x = cp_parser_template_id (parser, template_keyword_p, check_dependency_p,
   19133                 :             :                                   none_type, is_declaration);
   19134                 :  1225921906 :   if (TREE_CODE (x) == TEMPLATE_ID_EXPR
   19135                 :  1225921906 :       && concept_check_p (x))
   19136                 :             :     /* We didn't check the arguments in cp_parser_template_id; do that now.  */
   19137                 :     3762579 :     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                 :             : 
   19178                 :             : static tree
   19179                 :   281072892 : cp_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                 :   281072892 :   tree identifier;
   19187                 :   281072892 :   tree decl;
   19188                 :   281072892 :   cp_token *token = cp_lexer_peek_token (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                 :   281072892 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_OPERATOR))
   19193                 :             :     {
   19194                 :             :       /* We don't know whether we're looking at an
   19195                 :             :          operator-function-id or a conversion-function-id.  */
   19196                 :    31637852 :       cp_parser_parse_tentatively (parser);
   19197                 :             :       /* Try an operator-function-id.  */
   19198                 :    31637852 :       identifier = cp_parser_operator_function_id (parser);
   19199                 :             :       /* If that didn't work, try a conversion-function-id.  */
   19200                 :    31637852 :       if (!cp_parser_parse_definitely (parser))
   19201                 :             :         {
   19202                 :     1910072 :           cp_parser_error (parser, "expected template-name");
   19203                 :     1910072 :           return error_mark_node;
   19204                 :             :         }
   19205                 :             :     }
   19206                 :             :   /* Look for the identifier.  */
   19207                 :             :   else
   19208                 :   249435040 :     identifier = cp_parser_identifier (parser);
   19209                 :             : 
   19210                 :             :   /* If we didn't find an identifier, we don't have a template-id.  */
   19211                 :   279162820 :   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                 :   278550598 :   if (processing_template_decl
   19227                 :   278550598 :       && 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                 :   209523644 :       if (is_declaration
   19237                 :   209523644 :           && !template_keyword_p
   19238                 :    13708802 :           && parser->scope && TYPE_P (parser->scope)
   19239                 :         169 :           && check_dependency_p
   19240                 :          39 :           && 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                 :   209523679 :           && !constructor_name_p (identifier, parser->scope))
   19244                 :             :         {
   19245                 :          11 :           cp_token_position start = 0;
   19246                 :             : 
   19247                 :             :           /* Explain what went wrong.  */
   19248                 :          11 :           error_at (token->location, "non-template %qD used as template",
   19249                 :             :                     identifier);
   19250                 :          11 :           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                 :          33 :           if (cp_parser_simulate_error (parser))
   19254                 :          11 :             start = cp_lexer_token_position (parser->lexer, true);
   19255                 :             :           /* Parse the template arguments so that we can issue error
   19256                 :             :              messages about them.  */
   19257                 :          11 :           cp_lexer_consume_token (parser->lexer);
   19258                 :          11 :           cp_parser_enclosed_template_argument_list (parser);
   19259                 :             :           /* Skip tokens until we find a good place from which to
   19260                 :             :              continue parsing.  */
   19261                 :          11 :           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                 :          11 :           if (start)
   19270                 :          11 :             cp_lexer_purge_tokens_after (parser->lexer, start);
   19271                 :          11 :           if (is_identifier)
   19272                 :          11 :             *is_identifier = true;
   19273                 :          11 :           parser->context->object_type = NULL_TREE;
   19274                 :          11 :           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                 :   209523633 :       if (template_keyword_p)
   19282                 :             :         {
   19283                 :     3319318 :           tree scope = (parser->scope ? parser->scope
   19284                 :       52677 :                         : parser->context->object_type);
   19285                 :     3319318 :           if (scope && TYPE_P (scope)
   19286                 :     3920327 :               && (!CLASS_TYPE_P (scope)
   19287                 :      542987 :                   || (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                 :      550259 :               parser->object_scope = parser->context->object_type;
   19292                 :      550259 :               parser->context->object_type = NULL_TREE;
   19293                 :      550259 :               return identifier;
   19294                 :             :             }
   19295                 :             :         }
   19296                 :             :     }
   19297                 :             : 
   19298                 :             :   /* cp_parser_lookup_name clears OBJECT_TYPE.  */
   19299                 :   278000328 :   tree scope = (parser->scope ? parser->scope
   19300                 :   239851743 :                 : parser->context->object_type);
   19301                 :             : 
   19302                 :             :   /* Look up the name.  */
   19303                 :   278000328 :   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                 :   278000328 :   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                 :   278000328 :   decl = maybe_get_template_decl_from_type_decl (decl);
   19328                 :             : 
   19329                 :             :   /* If DECL is a template, then the name was a template-name.  */
   19330                 :   278000328 :   if (TREE_CODE (decl) == TEMPLATE_DECL)
   19331                 :             :     {
   19332                 :   164004456 :       if ((TREE_DEPRECATED (decl) || TREE_UNAVAILABLE (decl))
   19333                 :     1179444 :           && deprecated_state != UNAVAILABLE_DEPRECATED_SUPPRESS)
   19334                 :             :         {
   19335                 :     1179444 :           tree d = DECL_TEMPLATE_RESULT (decl);
   19336                 :     1179444 :           tree attr;
   19337                 :     1179444 :           if (TREE_CODE (d) == TYPE_DECL)
   19338                 :     1179444 :             attr = TYPE_ATTRIBUTES (TREE_TYPE (d));
   19339                 :             :           else
   19340                 :           0 :             attr = DECL_ATTRIBUTES (d);
   19341                 :     1179444 :           if (TREE_UNAVAILABLE (decl))
   19342                 :             :             {
   19343                 :           4 :               attr = lookup_attribute ("unavailable", attr);
   19344                 :           4 :               error_unavailable_use (decl, attr);
   19345                 :             :             }
   19346                 :     1179440 :           else if (TREE_DEPRECATED (decl)
   19347                 :     1179440 :                    && deprecated_state != DEPRECATED_SUPPRESS)
   19348                 :             :             {
   19349                 :     1179440 :               attr = lookup_attribute ("deprecated", attr);
   19350                 :     1179440 :               warn_deprecated_use (decl, attr);
   19351                 :             :             }
   19352                 :             :         }
   19353                 :             :     }
   19354                 :             :   else
   19355                 :             :     {
   19356                 :             :       /* Look through an overload set for any templates.  */
   19357                 :   113995872 :       bool found = false;
   19358                 :             : 
   19359                 :   227991744 :       for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
   19360                 :   240716065 :            !found && iter; ++iter)
   19361                 :   126720193 :         if (TREE_CODE (*iter) == TEMPLATE_DECL)
   19362                 :    28732868 :           found = true;
   19363                 :             : 
   19364                 :             :       /* "an unqualified name for which name lookup either finds one or more
   19365                 :             :          functions or finds nothing".  */
   19366                 :   113995872 :       if (!found
   19367                 :    85263004 :           && (cxx_dialect > cxx17)
   19368                 :    21006503 :           && !scope
   19369                 :    19810389 :           && cp_lexer_next_token_is (parser->lexer, CPP_LESS)
   19370                 :   125194270 :           && 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                 :    11198364 :           if (TREE_CODE (decl) == OVERLOAD
   19376                 :             :               /* Name lookup found one function.  */
   19377                 :    11198353 :               || TREE_CODE (decl) == FUNCTION_DECL
   19378                 :             :               /* Name lookup found nothing.  */
   19379                 :    11198332 :               || decl == error_mark_node)
   19380                 :         270 :             found = true;
   19381                 :             :         }
   19382                 :             : 
   19383                 :             :       /* "that follows the keyword template"..."in a type-only context" */
   19384                 :   113995872 :       if (!found && scope
   19385                 :     4757373 :           && (template_keyword_p || tag_type != none_type)
   19386                 :        9317 :           && dependentish_scope_p (scope)
   19387                 :   114005084 :           && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
   19388                 :             :         found = true;
   19389                 :             : 
   19390                 :   113986660 :       if (!found)
   19391                 :             :         {
   19392                 :             :           /* The name does not name a template.  */
   19393                 :    85253522 :           cp_parser_error (parser, "expected template-name");
   19394                 :    85253522 :           return error_mark_node;
   19395                 :             :         }
   19396                 :    28742301 :       else if ((!DECL_P (decl) && !is_overloaded_fn (decl))
   19397                 :    28732932 :                || TREE_CODE (decl) == USING_DECL
   19398                 :             :                /* cp_parser_template_id can only handle some TYPE_DECLs.  */
   19399                 :    57475282 :                || (TREE_CODE (decl) == TYPE_DECL
   19400                 :          28 :                    && 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                 :             : 
   19416                 :             : static tree
   19417                 :   179404304 : cp_parser_template_argument_list (cp_parser* parser)
   19418                 :             : {
   19419                 :   179404304 :   bool saved_in_template_argument_list_p;
   19420                 :   179404304 :   bool saved_ice_p;
   19421                 :   179404304 :   bool saved_non_ice_p;
   19422                 :             : 
   19423                 :             :   /* Don't create location wrapper nodes within a template-argument-list.  */
   19424                 :   179404304 :   auto_suppress_location_wrappers sentinel;
   19425                 :             : 
   19426                 :   179404304 :   saved_in_template_argument_list_p = parser->in_template_argument_list_p;
   19427                 :   179404304 :   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                 :   179404304 :   saved_ice_p = parser->integral_constant_expression_p;
   19432                 :   179404304 :   parser->integral_constant_expression_p = false;
   19433                 :   179404304 :   saved_non_ice_p = parser->non_integral_constant_expression_p;
   19434                 :   179404304 :   parser->non_integral_constant_expression_p = false;
   19435                 :             : 
   19436                 :             :   /* Parse the arguments.  */
   19437                 :   179404304 :   auto_vec<tree, 10> args;
   19438                 :   294951429 :   do
   19439                 :             :     {
   19440                 :   294951429 :       if (!args.is_empty ())
   19441                 :             :         /* Consume the comma.  */
   19442                 :   115547125 :         cp_lexer_consume_token (parser->lexer);
   19443                 :             : 
   19444                 :             :       /* Parse the template-argument.  */
   19445                 :   294951429 :       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                 :   294951429 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   19450                 :             :         {
   19451                 :     8840048 :           if (argument == error_mark_node)
   19452                 :             :             {
   19453                 :           9 :               cp_token *token = cp_lexer_peek_token (parser->lexer);
   19454                 :           9 :               error_at (token->location,
   19455                 :             :                         "expected parameter pack before %<...%>");
   19456                 :             :             }
   19457                 :             :           /* Consume the `...' token. */
   19458                 :     8840048 :           cp_lexer_consume_token (parser->lexer);
   19459                 :             : 
   19460                 :             :           /* Make the argument into a TYPE_PACK_EXPANSION or
   19461                 :             :              EXPR_PACK_EXPANSION. */
   19462                 :     8840048 :           argument = make_pack_expansion (argument);
   19463                 :             :         }
   19464                 :             : 
   19465                 :   294951429 :       args.safe_push (argument);
   19466                 :             :     }
   19467                 :   294951429 :   while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
   19468                 :             : 
   19469                 :   179404304 :   int n_args = args.length ();
   19470                 :   179404304 :   tree vec = make_tree_vec (n_args);
   19471                 :             : 
   19472                 :   474355733 :   for (int i = 0; i < n_args; i++)
   19473                 :   294951429 :     TREE_VEC_ELT (vec, i) = args[i];
   19474                 :             : 
   19475                 :   179404304 :   parser->non_integral_constant_expression_p = saved_non_ice_p;
   19476                 :   179404304 :   parser->integral_constant_expression_p = saved_ice_p;
   19477                 :   179404304 :   parser->in_template_argument_list_p = saved_in_template_argument_list_p;
   19478                 :   179404304 :   if (CHECKING_P)
   19479                 :   179404304 :     SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
   19480                 :   179404304 :   return vec;
   19481                 :   179404304 : }
   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                 :             : 
   19499                 :             : static tree
   19500                 :   294951429 : cp_parser_template_argument (cp_parser* parser)
   19501                 :             : {
   19502                 :   294951429 :   tree argument;
   19503                 :   294951429 :   bool template_p;
   19504                 :   294951429 :   bool address_p;
   19505                 :   294951429 :   bool maybe_type_id = false;
   19506                 :   294951429 :   cp_token *token = NULL, *argument_start_token = NULL;
   19507                 :   294951429 :   location_t loc = 0;
   19508                 :   294951429 :   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                 :   294951429 :   cp_parser_parse_tentatively (parser);
   19521                 :   294951429 :   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                 :   850438268 :   if (!cp_parser_error_occurred (parser)
   19539                 :   260535431 :       && ((cxx_dialect == cxx98
   19540                 :      767428 :            && cp_lexer_next_token_is (parser->lexer, 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                 :   260535421 :           || cp_lexer_next_token_is (parser->lexer, CPP_GREATER_EQ)))
   19546                 :             :     {
   19547                 :          21 :       maybe_type_id = true;
   19548                 :          21 :       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                 :   294951408 :       if (!cp_parser_next_token_ends_template_argument_p (parser))
   19556                 :    27303425 :         cp_parser_error (parser, "expected template-argument");
   19557                 :             :       /* If that worked, we're done.  */
   19558                 :   294951408 :       if (cp_parser_parse_definitely (parser))
   19559                 :             :         return argument;
   19560                 :             :     }
   19561                 :             :   /* We're still not sure what the argument will be.  */
   19562                 :    34475376 :   cp_parser_parse_tentatively (parser);
   19563                 :             :   /* Try a template.  */
   19564                 :    34475376 :   argument_start_token = cp_lexer_peek_token (parser->lexer);
   19565                 :    34475376 :   argument = cp_parser_id_expression (parser,
   19566                 :             :                                       /*template_keyword_p=*/false,
   19567                 :             :                                       /*check_dependency_p=*/true,
   19568                 :             :                                       &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                 :    34475376 :   if (!cp_parser_next_token_ends_template_argument_p (parser))
   19574                 :    10514470 :     cp_parser_error (parser, "expected template-argument");
   19575                 :    92911646 :   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                 :    23960894 :       if (TREE_CODE (argument) != TYPE_DECL)
   19582                 :    23960894 :         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                 :    23960894 :       if (TREE_CODE (argument) != TEMPLATE_DECL
   19590                 :    16657158 :                && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
   19591                 :    16651167 :         cp_parser_error (parser, "expected template-name");
   19592                 :             :     }
   19593                 :    34475376 :   if (cp_parser_parse_definitely (parser))
   19594                 :             :     {
   19595                 :     7309727 :       if (TREE_UNAVAILABLE (argument))
   19596                 :           4 :         error_unavailable_use (argument, NULL_TREE);
   19597                 :     7309723 :       else if (TREE_DEPRECATED (argument))
   19598                 :           4 :         warn_deprecated_use (argument, NULL_TREE);
   19599                 :     7309727 :       return argument;
   19600                 :             :     }
   19601                 :             :   /* It must be a non-type argument.  In C++17 any constant-expression is
   19602                 :             :      allowed.  */
   19603                 :    27165649 :   if (cxx_dialect > cxx14)
   19604                 :    26870152 :     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                 :      295497 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   19620                 :             :     {
   19621                 :      119008 :       cp_parser_parse_tentatively (parser);
   19622                 :      119008 :       argument = cp_parser_primary_expression (parser,
   19623                 :             :                                                /*address_p=*/false,
   19624                 :             :                                                /*cast_p=*/false,
   19625                 :             :                                                /*template_arg_p=*/true,
   19626                 :             :                                                &idk);
   19627                 :      119008 :       if (TREE_CODE (argument) != TEMPLATE_PARM_INDEX
   19628                 :      119008 :           || !cp_parser_next_token_ends_template_argument_p (parser))
   19629                 :      148675 :         cp_parser_simulate_error (parser);
   19630                 :      119008 :       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                 :      206156 :   address_p = cp_lexer_next_token_is (parser->lexer, CPP_AND);
   19637                 :      206156 :   if (address_p)
   19638                 :             :     {
   19639                 :         609 :       loc = cp_lexer_peek_token (parser->lexer)->location;
   19640                 :         609 :       cp_lexer_consume_token (parser->lexer);
   19641                 :             :     }
   19642                 :             :   /* See if we might have an id-expression.  */
   19643                 :      206156 :   token = cp_lexer_peek_token (parser->lexer);
   19644                 :      206156 :   if (token->type == CPP_NAME
   19645                 :      175884 :       || token->keyword == RID_OPERATOR
   19646                 :      175882 :       || token->type == CPP_SCOPE
   19647                 :      175866 :       || token->type == CPP_TEMPLATE_ID
   19648                 :      174835 :       || token->type == CPP_NESTED_NAME_SPECIFIER)
   19649                 :             :     {
   19650                 :       86095 :       cp_parser_parse_tentatively (parser);
   19651                 :       86095 :       argument = cp_parser_primary_expression (parser,
   19652                 :             :                                                address_p,
   19653                 :             :                                                /*cast_p=*/false,
   19654                 :             :                                                /*template_arg_p=*/true,
   19655                 :             :                                                &idk);
   19656                 :      182963 :       if (cp_parser_error_occurred (parser)
   19657                 :       85512 :           || !cp_parser_next_token_ends_template_argument_p (parser))
   19658                 :       11356 :         cp_parser_abort_tentative_parse (parser);
   19659                 :             :       else
   19660                 :             :         {
   19661                 :       74739 :           tree probe;
   19662                 :             : 
   19663                 :       74739 :           if (INDIRECT_REF_P (argument))
   19664                 :             :             {
   19665                 :             :               /* Strip the dereference temporarily.  */
   19666                 :          25 :               gcc_assert (REFERENCE_REF_P (argument));
   19667                 :          25 :               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                 :       74739 :           probe = argument;
   19674                 :       74739 :           if (TREE_CODE (probe) == SCOPE_REF)
   19675                 :       47914 :             probe = TREE_OPERAND (probe, 1);
   19676                 :       74739 :           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                 :        5527 :               if (!address_p && !DECL_EXTERNAL_LINKAGE_P (probe))
   19682                 :       77151 :                 cp_parser_simulate_error (parser);
   19683                 :             :             }
   19684                 :       69212 :           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                 :       68838 :           else if (address_p
   19690                 :         311 :                    && (TREE_CODE (argument) == OFFSET_REF
   19691                 :          57 :                        || TREE_CODE (argument) == SCOPE_REF))
   19692                 :             :             /* A pointer-to-member.  */
   19693                 :             :             ;
   19694                 :       68529 :           else if (TREE_CODE (argument) == TEMPLATE_PARM_INDEX)
   19695                 :             :             ;
   19696                 :             :           else
   19697                 :      143244 :             cp_parser_simulate_error (parser);
   19698                 :             : 
   19699                 :       74739 :           if (cp_parser_parse_definitely (parser))
   19700                 :             :             {
   19701                 :        3822 :               if (address_p)
   19702                 :         597 :                 argument = build_x_unary_op (loc, ADDR_EXPR, argument,
   19703                 :             :                                              NULL_TREE, tf_warning_or_error);
   19704                 :             :               else
   19705                 :        3225 :                 argument = convert_from_reference (argument);
   19706                 :        3822 :               return argument;
   19707                 :             :             }
   19708                 :             :         }
   19709                 :             :     }
   19710                 :             :   /* If the argument started with "&", there are no other valid
   19711                 :             :      alternatives at this point.  */
   19712                 :      202334 :   if (address_p)
   19713                 :             :     {
   19714                 :          12 :       cp_parser_error (parser, "invalid non-type template argument");
   19715                 :          12 :       return error_mark_node;
   19716                 :             :     }
   19717                 :             : 
   19718                 :      202322 :  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                 :    27072474 :   if (maybe_type_id)
   19724                 :          21 :     cp_parser_parse_tentatively (parser);
   19725                 :             : 
   19726                 :    27072474 :   if (cxx_dialect <= cxx14)
   19727                 :      202322 :     argument = cp_parser_constant_expression (parser);
   19728                 :             :   else
   19729                 :             :     {
   19730                 :             :       /* In C++20, we can encounter a braced-init-list.  */
   19731                 :    26870152 :       if (cxx_dialect >= cxx20
   19732                 :    26870152 :           && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   19733                 :          25 :         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                 :    26870127 :       argument = cp_parser_assignment_expression (parser);
   19738                 :    26870127 :       require_potential_constant_expression (argument);
   19739                 :             :     }
   19740                 :             : 
   19741                 :    27072449 :   if (!maybe_type_id)
   19742                 :             :     return argument;
   19743                 :          21 :   if (!cp_parser_next_token_ends_template_argument_p (parser))
   19744                 :          16 :     cp_parser_error (parser, "expected template-argument");
   19745                 :          21 :   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                 :          16 :   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                 :             : 
   19776                 :             : static void
   19777                 :     2684356 : cp_parser_explicit_instantiation (cp_parser* parser)
   19778                 :             : {
   19779                 :     2684356 :   int declares_class_or_enum;
   19780                 :     2684356 :   cp_decl_specifier_seq decl_specifiers;
   19781                 :     2684356 :   tree extension_specifier = NULL_TREE;
   19782                 :             : 
   19783                 :     2684356 :   auto_timevar tv (TV_TEMPLATE_INST);
   19784                 :             : 
   19785                 :             :   /* Look for an (optional) storage-class-specifier or
   19786                 :             :      function-specifier.  */
   19787                 :     2684356 :   if (cp_parser_allow_gnu_extensions_p (parser))
   19788                 :             :     {
   19789                 :     2684356 :       extension_specifier
   19790                 :     2684356 :         = cp_parser_storage_class_specifier_opt (parser);
   19791                 :     2684356 :       if (!extension_specifier)
   19792                 :        5893 :         extension_specifier
   19793                 :        5893 :           = cp_parser_function_specifier_opt (parser,
   19794                 :             :                                               /*decl_specs=*/NULL);
   19795                 :             :     }
   19796                 :             : 
   19797                 :             :   /* Look for the `template' keyword.  */
   19798                 :     2684356 :   cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
   19799                 :             :   /* Let the front end know that we are processing an explicit
   19800                 :             :      instantiation.  */
   19801                 :     2684356 :   begin_explicit_instantiation ();
   19802                 :             :   /* [temp.explicit] says that we are supposed to ignore access
   19803                 :             :      control while processing explicit instantiation directives.  */
   19804                 :     2684356 :   push_deferring_access_checks (dk_no_check);
   19805                 :             :   /* Parse a decl-specifier-seq.  */
   19806                 :     2684356 :   cp_parser_decl_specifier_seq (parser,
   19807                 :             :                                 CP_PARSER_FLAGS_OPTIONAL,
   19808                 :             :                                 &decl_specifiers,
   19809                 :             :                                 &declares_class_or_enum);
   19810                 :             : 
   19811                 :     2684356 :   cp_omp_declare_simd_data odsd;
   19812                 :     2684356 :   if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
   19813                 :           6 :     cp_parser_handle_directive_omp_attributes (parser,
   19814                 :             :                                                &decl_specifiers.attributes,
   19815                 :             :                                                &odsd, 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                 :     2684356 :   if (declares_class_or_enum && cp_parser_declares_only_class_p (parser))
   19821                 :             :     {
   19822                 :      775347 :       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                 :      775347 :       pop_deferring_access_checks ();
   19827                 :      775347 :       if (type)
   19828                 :      775314 :         do_type_instantiation (type, extension_specifier,
   19829                 :             :                                /*complain=*/tf_error);
   19830                 :             :     }
   19831                 :             :   else
   19832                 :             :     {
   19833                 :     1909009 :       cp_declarator *declarator;
   19834                 :     1909009 :       tree decl;
   19835                 :             : 
   19836                 :             :       /* Parse the declarator.  */
   19837                 :     1909009 :       declarator
   19838                 :     1909009 :         = 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                 :     1909009 :       if (declares_class_or_enum & 2)
   19846                 :           0 :         cp_parser_check_for_definition_in_return_type (declarator,
   19847                 :             :                                                        decl_specifiers.type,
   19848                 :             :                                                        decl_specifiers.locations[ds_type_spec]);
   19849                 :     1909009 :       if (declarator != cp_error_declarator)
   19850                 :             :         {
   19851                 :     1908981 :           if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_inline))
   19852                 :           3 :             permerror (decl_specifiers.locations[ds_inline],
   19853                 :             :                        "explicit instantiation shall not use"
   19854                 :             :                        " %<inline%> specifier");
   19855                 :     1908981 :           if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_constexpr))
   19856                 :           3 :             permerror (decl_specifiers.locations[ds_constexpr],
   19857                 :             :                        "explicit instantiation shall not use"
   19858                 :             :                        " %<constexpr%> specifier");
   19859                 :     1908981 :           if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_consteval))
   19860                 :           1 :             permerror (decl_specifiers.locations[ds_consteval],
   19861                 :             :                        "explicit instantiation shall not use"
   19862                 :             :                        " %<consteval%> specifier");
   19863                 :             : 
   19864                 :     1908981 :           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                 :     1908981 :           pop_deferring_access_checks ();
   19869                 :             :           /* Do the explicit instantiation.  */
   19870                 :     1908981 :           do_decl_instantiation (decl, extension_specifier);
   19871                 :             :         }
   19872                 :             :       else
   19873                 :             :         {
   19874                 :          28 :           pop_deferring_access_checks ();
   19875                 :             :           /* Skip the body of the explicit instantiation.  */
   19876                 :          28 :           cp_parser_skip_to_end_of_statement (parser);
   19877                 :             :         }
   19878                 :             :     }
   19879                 :             :   /* We're done with the instantiation.  */
   19880                 :     2684352 :   end_explicit_instantiation ();
   19881                 :             : 
   19882                 :     2684352 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   19883                 :             : 
   19884                 :     2684352 :   cp_finalize_omp_declare_simd (parser, &odsd);
   19885                 :     2684352 : }
   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                 :             : 
   19900                 :             : static void
   19901                 :     4740366 : cp_parser_explicit_specialization (cp_parser* parser)
   19902                 :             : {
   19903                 :     4740366 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   19904                 :             : 
   19905                 :             :   /* Look for the `template' keyword.  */
   19906                 :     4740366 :   cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
   19907                 :             :   /* Look for the `<'.  */
   19908                 :     4740366 :   cp_parser_require (parser, CPP_LESS, RT_LESS);
   19909                 :             :   /* Look for the `>'.  */
   19910                 :     4740366 :   cp_parser_require (parser, CPP_GREATER, RT_GREATER);
   19911                 :             :   /* We have processed another parameter list.  */
   19912                 :     4740366 :   ++parser->num_template_parameter_lists;
   19913                 :             : 
   19914                 :             :   /* [temp]
   19915                 :             : 
   19916                 :             :      A template ... explicit specialization ... shall not have C
   19917                 :             :      linkage.  */
   19918                 :     4740366 :   bool need_lang_pop = current_lang_name == lang_name_c;
   19919                 :     4740366 :   if (need_lang_pop)
   19920                 :             :     {
   19921                 :           4 :       error_at (token->location, "template specialization with C linkage");
   19922                 :           4 :       maybe_show_extern_c_location ();
   19923                 :             : 
   19924                 :             :       /* Give it C++ linkage to avoid confusing other parts of the
   19925                 :             :          front end.  */
   19926                 :           4 :       push_lang_context (lang_name_cplusplus);
   19927                 :             :     }
   19928                 :             : 
   19929                 :             :   /* Let the front end know that we are beginning a specialization.  */
   19930                 :     4740366 :   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                 :     4740334 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
   19935                 :             :         {
   19936                 :        1189 :           if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS
   19937                 :        1189 :               && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_GREATER)
   19938                 :        1000 :             cp_parser_template_declaration_after_export (parser,
   19939                 :             :                                                          /*member_p=*/false);
   19940                 :             :           else
   19941                 :         189 :             cp_parser_explicit_specialization (parser);
   19942                 :             :         }
   19943                 :             :       else
   19944                 :             :         /* Parse the dependent declaration.  */
   19945                 :     4739145 :         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                 :     4740366 :   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                 :     4740366 :   if (need_lang_pop)
   19958                 :           4 :     pop_lang_context ();
   19959                 :             : 
   19960                 :             :   /* We're done with this parameter list.  */
   19961                 :     4740366 :   --parser->num_template_parameter_lists;
   19962                 :     4740366 : }
   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                 :             : 
   19967                 :             : static 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                 :             : 
   20002                 :             : static tree
   20003                 :  2027033739 : cp_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                 :  2027033739 :   tree type_spec = NULL_TREE;
   20011                 :  2027033739 :   cp_token *token;
   20012                 :  2027033739 :   enum rid keyword;
   20013                 :  2027033739 :   cp_decl_spec ds = ds_last;
   20014                 :             : 
   20015                 :             :   /* Assume this type-specifier does not declare a new type.  */
   20016                 :  2027033739 :   if (declares_class_or_enum)
   20017                 :  1340989248 :     *declares_class_or_enum = 0;
   20018                 :             :   /* And that it does not specify a cv-qualifier.  */
   20019                 :  2027033739 :   if (is_cv_qualifier)
   20020                 :  2017035396 :     *is_cv_qualifier = false;
   20021                 :             :   /* Peek at the next token.  */
   20022                 :  2027033739 :   token = cp_lexer_peek_token (parser->lexer);
   20023                 :             : 
   20024                 :             :   /* If we're looking at a keyword, we can use that to guide the
   20025                 :             :      production we choose.  */
   20026                 :  2027033739 :   keyword = token->keyword;
   20027                 :  2027033739 :   switch (keyword)
   20028                 :             :     {
   20029                 :     1578248 :     case RID_ENUM:
   20030                 :     1578248 :       if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
   20031                 :           3 :         goto elaborated_type_specifier;
   20032                 :             : 
   20033                 :             :       /* Look for the enum-specifier.  */
   20034                 :     1578245 :       type_spec = cp_parser_enum_specifier (parser);
   20035                 :             :       /* If that worked, we're done.  */
   20036                 :     1578245 :       if (type_spec)
   20037                 :             :         {
   20038                 :     1551900 :           if (declares_class_or_enum)
   20039                 :     1551861 :             *declares_class_or_enum = 2;
   20040                 :     1551900 :           if (decl_specs)
   20041                 :     1551900 :             cp_parser_set_decl_spec_type (decl_specs,
   20042                 :             :                                           type_spec,
   20043                 :             :                                           token,
   20044                 :             :                                           /*type_definition_p=*/true);
   20045                 :     1551900 :           return type_spec;
   20046                 :             :         }
   20047                 :             :       else
   20048                 :       26345 :         goto elaborated_type_specifier;
   20049                 :             : 
   20050                 :             :       /* Any of these indicate either a class-specifier, or an
   20051                 :             :          elaborated-type-specifier.  */
   20052                 :    35116355 :     case RID_CLASS:
   20053                 :    35116355 :     case RID_STRUCT:
   20054                 :    35116355 :     case RID_UNION:
   20055                 :    35116355 :       if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
   20056                 :           9 :         goto elaborated_type_specifier;
   20057                 :             : 
   20058                 :             :       /* Parse tentatively so that we can back up if we don't find a
   20059                 :             :          class-specifier.  */
   20060                 :    35116346 :       cp_parser_parse_tentatively (parser);
   20061                 :    35116346 :       if (decl_specs->attributes)
   20062                 :         412 :         vec_safe_push (cp_parser_decl_specs_attrs, decl_specs->attributes);
   20063                 :             :       /* Look for the class-specifier.  */
   20064                 :    35116346 :       type_spec = cp_parser_class_specifier (parser);
   20065                 :    35116322 :       if (decl_specs->attributes)
   20066                 :         412 :         cp_parser_decl_specs_attrs->pop ();
   20067                 :    35116322 :       invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, type_spec);
   20068                 :             :       /* If that worked, we're done.  */
   20069                 :    35116322 :       if (cp_parser_parse_definitely (parser))
   20070                 :             :         {
   20071                 :    23468124 :           if (declares_class_or_enum)
   20072                 :    23467937 :             *declares_class_or_enum = 2;
   20073                 :    23468124 :           if (decl_specs)
   20074                 :    23468124 :             cp_parser_set_decl_spec_type (decl_specs,
   20075                 :             :                                           type_spec,
   20076                 :             :                                           token,
   20077                 :             :                                           /*type_definition_p=*/true);
   20078                 :    23468124 :           return type_spec;
   20079                 :             :         }
   20080                 :             : 
   20081                 :             :       /* Fall through.  */
   20082                 :    11648198 :     elaborated_type_specifier:
   20083                 :             :       /* We're declaring (not defining) a class or enum.  */
   20084                 :    11674555 :       if (declares_class_or_enum)
   20085                 :     7514728 :         *declares_class_or_enum = 1;
   20086                 :             : 
   20087                 :             :       /* Fall through.  */
   20088                 :    37970652 :     case RID_TYPENAME:
   20089                 :             :       /* Look for an elaborated-type-specifier.  */
   20090                 :    37970652 :       type_spec
   20091                 :             :         = (cp_parser_elaborated_type_specifier
   20092                 :    37970652 :            (parser,
   20093                 :    37970652 :             decl_spec_seq_has_spec_p (decl_specs, ds_friend),
   20094                 :             :             is_declaration));
   20095                 :    37970652 :       if (decl_specs)
   20096                 :    37970652 :         cp_parser_set_decl_spec_type (decl_specs,
   20097                 :             :                                       type_spec,
   20098                 :             :                                       token,
   20099                 :             :                                       /*type_definition_p=*/false);
   20100                 :             :       return type_spec;
   20101                 :             : 
   20102                 :    92109235 :     case RID_CONST:
   20103                 :    92109235 :       ds = ds_const;
   20104                 :    92109235 :       if (is_cv_qualifier)
   20105                 :    92109235 :         *is_cv_qualifier = true;
   20106                 :             :       break;
   20107                 :             : 
   20108                 :     1449756 :     case RID_VOLATILE:
   20109                 :     1449756 :       ds = ds_volatile;
   20110                 :     1449756 :       if (is_cv_qualifier)
   20111                 :     1449756 :         *is_cv_qualifier = true;
   20112                 :             :       break;
   20113                 :             : 
   20114                 :          42 :     case RID_RESTRICT:
   20115                 :          42 :       ds = ds_restrict;
   20116                 :          42 :       if (is_cv_qualifier)
   20117                 :          42 :         *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                 :    93559033 :   if (ds != ds_last)
   20131                 :             :     {
   20132                 :    94827880 :       if (decl_specs)
   20133                 :             :         {
   20134                 :    94827880 :           set_and_check_decl_spec_loc (decl_specs, ds, token);
   20135                 :    94827880 :           decl_specs->any_specifiers_p = true;
   20136                 :             :         }
   20137                 :    94827880 :       return cp_lexer_consume_token (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                 :  1869215159 :   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                 :  1869215155 :   if (!type_spec && !(flags & CP_PARSER_FLAGS_OPTIONAL))
   20149                 :             :     {
   20150                 :           0 :       cp_parser_error (parser, "expected type specifier");
   20151                 :           0 :       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                 :             : 
   20203                 :             : static tree
   20204                 :  2698076829 : cp_parser_simple_type_specifier (cp_parser* parser,
   20205                 :             :                                  cp_decl_specifier_seq *decl_specs,
   20206                 :             :                                  cp_parser_flags flags)
   20207                 :             : {
   20208                 :  2698076829 :   tree type = NULL_TREE;
   20209                 :  2698076829 :   cp_token *token;
   20210                 :  2698076829 :   int idx;
   20211                 :             : 
   20212                 :             :   /* Peek at the next token.  */
   20213                 :  2698076829 :   token = cp_lexer_peek_token (parser->lexer);
   20214                 :             : 
   20215                 :             :   /* If we're looking at a keyword, things are easy.  */
   20216                 :  2698076829 :   switch (token->keyword)
   20217                 :             :     {
   20218                 :    19473958 :     case RID_CHAR:
   20219                 :    19473958 :       if (decl_specs)
   20220                 :    19433260 :         decl_specs->explicit_char_p = true;
   20221                 :    19473958 :       type = char_type_node;
   20222                 :    19473958 :       break;
   20223                 :      224499 :     case RID_CHAR8:
   20224                 :      224499 :       type = char8_type_node;
   20225                 :      224499 :       break;
   20226                 :     1002644 :     case RID_CHAR16:
   20227                 :     1002644 :       type = char16_type_node;
   20228                 :     1002644 :       break;
   20229                 :     1070226 :     case RID_CHAR32:
   20230                 :     1070226 :       type = char32_type_node;
   20231                 :     1070226 :       break;
   20232                 :     6081452 :     case RID_WCHAR:
   20233                 :     6081452 :       type = wchar_type_node;
   20234                 :     6081452 :       break;
   20235                 :    33438522 :     case RID_BOOL:
   20236                 :    33438522 :       type = boolean_type_node;
   20237                 :    33438522 :       break;
   20238                 :     1747868 :     case RID_SHORT:
   20239                 :     1747868 :       set_and_check_decl_spec_loc (decl_specs, ds_short, token);
   20240                 :     1747868 :       type = short_integer_type_node;
   20241                 :     1747868 :       break;
   20242                 :    35444727 :     case RID_INT:
   20243                 :    35444727 :       if (decl_specs)
   20244                 :    34165380 :         decl_specs->explicit_int_p = true;
   20245                 :    35444727 :       type = integer_type_node;
   20246                 :    35444727 :       break;
   20247                 :      832095 :     case RID_INT_N_0:
   20248                 :      832095 :     case RID_INT_N_1:
   20249                 :      832095 :     case RID_INT_N_2:
   20250                 :      832095 :     case RID_INT_N_3:
   20251                 :      832095 :       idx = token->keyword - RID_INT_N_0;
   20252                 :      832095 :       if (! int_n_enabled_p [idx])
   20253                 :             :         break;
   20254                 :      832095 :       if (decl_specs)
   20255                 :             :         {
   20256                 :      830143 :           decl_specs->explicit_intN_p = true;
   20257                 :      830143 :           decl_specs->int_n_idx = idx;
   20258                 :             :           /* Check if the alternate "__intN__" form has been used instead of
   20259                 :             :              "__intN".  */
   20260                 :      830143 :           if (startswith (IDENTIFIER_POINTER (token->u.value)
   20261                 :      830143 :                           + (IDENTIFIER_LENGTH (token->u.value) - 2), "__"))
   20262                 :           0 :             decl_specs->int_n_alt = true;
   20263                 :             :         }
   20264                 :      832095 :       type = int_n_trees [idx].signed_type;
   20265                 :      832095 :       break;
   20266                 :    18986385 :     case RID_LONG:
   20267                 :    18986385 :       if (decl_specs)
   20268                 :    18986347 :         set_and_check_decl_spec_loc (decl_specs, ds_long, token);
   20269                 :    18986385 :       type = long_integer_type_node;
   20270                 :    18986385 :       break;
   20271                 :      983733 :     case RID_SIGNED:
   20272                 :      983733 :       set_and_check_decl_spec_loc (decl_specs, ds_signed, token);
   20273                 :      983733 :       type = integer_type_node;
   20274                 :      983733 :       break;
   20275                 :    11924238 :     case RID_UNSIGNED:
   20276                 :    11924238 :       set_and_check_decl_spec_loc (decl_specs, ds_unsigned, token);
   20277                 :    11924238 :       type = unsigned_type_node;
   20278                 :    11924238 :       break;
   20279                 :     7907529 :     case RID_FLOAT:
   20280                 :     7907529 :       type = float_type_node;
   20281                 :     7907529 :       break;
   20282                 :    16555481 :     case RID_DOUBLE:
   20283                 :    16555481 :       type = double_type_node;
   20284                 :    16555481 :       break;
   20285                 :    21773587 :     CASE_RID_FLOATN_NX:
   20286                 :    21773587 :       type = FLOATN_NX_TYPE_NODE (token->keyword - RID_FLOATN_NX_FIRST);
   20287                 :    21773587 :       if (type == NULL_TREE)
   20288                 :           0 :         error ("%<_Float%d%s%> is not supported on this target",
   20289                 :           0 :                floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].n,
   20290                 :           0 :                floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].extended
   20291                 :             :                ? "x" : "");
   20292                 :             :       break;
   20293                 :    28807909 :     case RID_VOID:
   20294                 :    28807909 :       type = void_type_node;
   20295                 :    28807909 :       break;
   20296                 :             : 
   20297                 :     8851248 :     case RID_AUTO:
   20298                 :     8851248 :       maybe_warn_cpp0x (CPP0X_AUTO);
   20299                 :     8851248 :       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                 :      301125 :           bool have_trailing_return_fn_decl = false;
   20304                 :             : 
   20305                 :      301125 :           cp_parser_parse_tentatively (parser);
   20306                 :      301125 :           cp_lexer_consume_token (parser->lexer);
   20307                 :      301125 :           while (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
   20308                 :      806951 :                  && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
   20309                 :             :                  && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
   20310                 :      806957 :                  && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
   20311                 :             :             {
   20312                 :         125 :               if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   20313                 :             :                 {
   20314                 :         125 :                   cp_lexer_consume_token (parser->lexer);
   20315                 :         125 :                   cp_parser_skip_to_closing_parenthesis (parser,
   20316                 :             :                                                          /*recovering*/false,
   20317                 :             :                                                          /*or_comma*/false,
   20318                 :             :                                                          /*consume_paren*/true);
   20319                 :         125 :                   continue;
   20320                 :             :                 }
   20321                 :             : 
   20322                 :             :               if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
   20323                 :             :                 {
   20324                 :             :                   have_trailing_return_fn_decl = true;
   20325                 :             :                   break;
   20326                 :             :                 }
   20327                 :             : 
   20328                 :      505707 :               cp_lexer_consume_token (parser->lexer);
   20329                 :             :             }
   20330                 :      301125 :           cp_parser_abort_tentative_parse (parser);
   20331                 :             : 
   20332                 :      301125 :           if (have_trailing_return_fn_decl)
   20333                 :             :             {
   20334                 :          37 :               type = make_auto ();
   20335                 :          37 :               break;
   20336                 :             :             }
   20337                 :             : 
   20338                 :      301088 :           if (cxx_dialect >= cxx14)
   20339                 :             :             {
   20340                 :      301087 :               type = synthesize_implicit_template_parm (parser, NULL_TREE);
   20341                 :      301087 :               type = TREE_TYPE (type);
   20342                 :             :             }
   20343                 :             :           else
   20344                 :           1 :             type = error_mark_node;
   20345                 :             : 
   20346                 :      601938 :           if (current_class_type && LAMBDA_TYPE_P (current_class_type))
   20347                 :             :             {
   20348                 :      300493 :               if (cxx_dialect < cxx14)
   20349                 :           1 :                 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                 :         595 :           else if (!flag_concepts_ts && parser->in_template_argument_list_p)
   20355                 :           3 :             pedwarn (token->location, 0,
   20356                 :             :                      "use of %<auto%> in template argument "
   20357                 :             :                      "only available with %<-fconcepts-ts%>");
   20358                 :         592 :           else if (!flag_concepts)
   20359                 :          15 :             pedwarn (token->location, 0,
   20360                 :             :                      "use of %<auto%> in parameter declaration "
   20361                 :             :                      "only available with %<-std=c++20%> or %<-fconcepts%>");
   20362                 :         577 :           else if (cxx_dialect < cxx14)
   20363                 :           0 :             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                 :     8550123 :         type = make_auto ();
   20370                 :             :       break;
   20371                 :             : 
   20372                 :     2724231 :     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                 :     2724231 :       cp_parser_decltype (parser);
   20378                 :     2724231 :       cp_lexer_set_token_position (parser->lexer, token);
   20379                 :     2724231 :       break;
   20380                 :             : 
   20381                 :       93694 :     case RID_TYPEOF:
   20382                 :             :       /* Consume the `typeof' token.  */
   20383                 :       93694 :       cp_lexer_consume_token (parser->lexer);
   20384                 :             :       /* Parse the operand to `typeof'.  */
   20385                 :       93694 :       type = cp_parser_sizeof_operand (parser, RID_TYPEOF);
   20386                 :             :       /* If it is not already a TYPE, take its type.  */
   20387                 :       93694 :       if (!TYPE_P (type))
   20388                 :       93690 :         type = finish_typeof (type);
   20389                 :             : 
   20390                 :       93694 :       if (decl_specs)
   20391                 :       93690 :         cp_parser_set_decl_spec_type (decl_specs, type,
   20392                 :             :                                       token,
   20393                 :             :                                       /*type_definition_p=*/false);
   20394                 :             : 
   20395                 :             :       return type;
   20396                 :             : 
   20397                 :  2480152803 :     default:
   20398                 :             :       /* If token is a type-yielding built-in traits, parse it.  */
   20399                 :  2480152803 :       const cp_trait* trait = cp_lexer_peek_trait_type (parser->lexer);
   20400                 :  2480152803 :       if (trait)
   20401                 :             :         {
   20402                 :       70326 :           type = cp_parser_trait (parser, trait);
   20403                 :       70326 :           if (decl_specs)
   20404                 :       70326 :             cp_parser_set_decl_spec_type (decl_specs, type,
   20405                 :             :                                           token,
   20406                 :             :                                           /*type_definition_p=*/false);
   20407                 :             : 
   20408                 :       70326 :           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                 :  2697912809 :   if (token->type == CPP_DECLTYPE
   20417                 :  2697912809 :       && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
   20418                 :             :     {
   20419                 :     2734028 :       type = saved_checks_value (token->u.tree_check_value);
   20420                 :     2734028 :       if (decl_specs)
   20421                 :             :         {
   20422                 :     2724606 :           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                 :     2724606 :           decl_specs->decltype_p = true;
   20429                 :             :         }
   20430                 :     2734028 :       cp_lexer_consume_token (parser->lexer);
   20431                 :     2734028 :       return type;
   20432                 :             :     }
   20433                 :             : 
   20434                 :             :   /* If the type-specifier was for a built-in type, we're done.  */
   20435                 :  2695178781 :   if (type)
   20436                 :             :     {
   20437                 :             :       /* Record the type.  */
   20438                 :   215106101 :       if (decl_specs
   20439                 :   210411427 :           && (token->keyword != RID_SIGNED
   20440                 :             :               && token->keyword != RID_UNSIGNED
   20441                 :             :               && token->keyword != RID_SHORT
   20442                 :             :               && token->keyword != RID_LONG))
   20443                 :   176917079 :         cp_parser_set_decl_spec_type (decl_specs,
   20444                 :             :                                       type,
   20445                 :             :                                       token,
   20446                 :             :                                       /*type_definition_p=*/false);
   20447                 :   210411427 :       if (decl_specs)
   20448                 :   210411427 :         decl_specs->any_specifiers_p = true;
   20449                 :             : 
   20450                 :             :       /* Consume the token.  */
   20451                 :   215106101 :       cp_lexer_consume_token (parser->lexer);
   20452                 :             : 
   20453                 :   215106101 :       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                 :   215106098 :       cp_parser_check_for_invalid_template_id (parser, type, none_type,
   20460                 :             :                                                token->location);
   20461                 :             : 
   20462                 :   215106098 :       return TYPE_NAME (type);
   20463                 :             :     }
   20464                 :             : 
   20465                 :             :   /* The type-specifier must be a user-defined type.  */
   20466                 :  2480072680 :   if (!(flags & CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES))
   20467                 :             :     {
   20468                 :  1907420147 :       bool qualified_p;
   20469                 :  1907420147 :       bool global_p;
   20470                 :  3814840294 :       const bool typename_p = (cxx_dialect >= cxx20
   20471                 :  1907420147 :                                && (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                 :  1907420147 :       if (flags & CP_PARSER_FLAGS_OPTIONAL)
   20476                 :   880712123 :         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                 :  1907420147 :       bool tent = cp_parser_parsing_tentatively (parser);
   20481                 :             : 
   20482                 :  1907420147 :       token = cp_lexer_peek_token (parser->lexer);
   20483                 :             : 
   20484                 :             :       /* Look for the optional `::' operator.  */
   20485                 :  1907420147 :       global_p
   20486                 :  1907420147 :         = (cp_parser_global_scope_opt (parser,
   20487                 :             :                                        /*current_scope_valid_p=*/false)
   20488                 :             :            != NULL_TREE);
   20489                 :             :       /* Look for the nested-name specifier.  */
   20490                 :  1907420147 :       qualified_p
   20491                 :  1907420147 :         = (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                 :  1907420143 :       if (parser->scope
   20500                 :  1907420143 :           && cp_parser_optional_template_keyword (parser))
   20501                 :             :         {
   20502                 :             :           /* Look for the template-id.  */
   20503                 :      347783 :           type = cp_parser_template_id (parser,
   20504                 :             :                                         /*template_keyword_p=*/true,
   20505                 :             :                                         /*check_dependency_p=*/true,
   20506                 :             :                                         none_type,
   20507                 :             :                                         /*is_declaration=*/false);
   20508                 :             :           /* If the template-id did not name a type, we are out of
   20509                 :             :              luck.  */
   20510                 :      347783 :           if (TREE_CODE (type) != TYPE_DECL)
   20511                 :             :             {
   20512                 :             :               /* ...unless we pretend we have seen 'typename'.  */
   20513                 :      347753 :               if (typename_p)
   20514                 :          10 :                 type = cp_parser_make_typename_type (parser, type,
   20515                 :             :                                                      token->location);
   20516                 :             :               else
   20517                 :             :                 {
   20518                 :      347743 :                   cp_parser_error (parser, "expected template-id for type");
   20519                 :      347743 :                   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                 :  1907072360 :       else if (parser->scope
   20527                 :             :                && qualified_p
   20528                 :   130524966 :                && typename_p
   20529                 :  1911329859 :                && cp_lexer_next_token_is (parser->lexer, CPP_TEMPLATE_ID))
   20530                 :             :         {
   20531                 :     2174505 :           cp_parser_parse_tentatively (parser);
   20532                 :             : 
   20533                 :     2174505 :           type = cp_parser_template_id (parser,
   20534                 :             :                                         /*template_keyword_p=*/true,
   20535                 :             :                                         /*check_dependency_p=*/true,
   20536                 :             :                                         none_type,
   20537                 :             :                                         /*is_declaration=*/false);
   20538                 :             :           /* This is handled below, so back off.  */
   20539                 :     2174505 :           if (type && concept_check_p (type))
   20540                 :     2260257 :             cp_parser_simulate_error (parser);
   20541                 :             : 
   20542                 :     2174505 :           if (!cp_parser_parse_definitely (parser))
   20543                 :             :             type = NULL_TREE;
   20544                 :     2088753 :           else if (TREE_CODE (type) == TEMPLATE_ID_EXPR)
   20545                 :           0 :             type = make_typename_type (parser->scope, type, typename_type,
   20546                 :             :                                        /*complain=*/tf_error);
   20547                 :     2088753 :           else if (TREE_CODE (type) != TYPE_DECL)
   20548                 :             :             type = NULL_TREE;
   20549                 :             :         }
   20550                 :             : 
   20551                 :             :       /* Otherwise, look for a type-name.  */
   20552                 :  1905245608 :       if (!type)
   20553                 :             :         {
   20554                 :  1904983614 :           if (cxx_dialect >= cxx17 || flag_concepts)
   20555                 :  1860812390 :             cp_parser_parse_tentatively (parser);
   20556                 :             : 
   20557                 :  1904983614 :           type = cp_parser_type_name (parser, (qualified_p && typename_p));
   20558                 :             : 
   20559                 :    44171734 :           if ((cxx_dialect >= cxx17 || flag_concepts)
   20560                 :  1904984124 :               && !cp_parser_parse_definitely (parser))
   20561                 :             :             type = NULL_TREE;
   20562                 :             :         }
   20563                 :             : 
   20564                 :  1904983614 :       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                 :   134284904 :           cp_parser_parse_tentatively (parser);
   20570                 :             : 
   20571                 :   134284904 :           type = cp_parser_template_id (parser,
   20572                 :             :                                         /*template_keyword_p=*/false,
   20573                 :             :                                         /*check_dependency_p=*/true,
   20574                 :             :                                         none_type,
   20575                 :             :                                         /*is_declaration=*/false);
   20576                 :   134284904 :           if (type && concept_check_p (type))
   20577                 :             :             {
   20578                 :     1290872 :               location_t loc = EXPR_LOCATION (type);
   20579                 :     1290872 :               type = cp_parser_placeholder_type_specifier (parser, loc,
   20580                 :             :                                                            type, tent);
   20581                 :     1290872 :               if (tent && type == error_mark_node)
   20582                 :             :                 /* Perhaps it's a concept-check expression.  */
   20583                 :   134793587 :                 cp_parser_simulate_error (parser);
   20584                 :             :             }
   20585                 :             :           else
   20586                 :   267278936 :             cp_parser_simulate_error (parser);
   20587                 :             : 
   20588                 :   134284904 :           if (!cp_parser_parse_definitely (parser))
   20589                 :             :             type = NULL_TREE;
   20590                 :             :         }
   20591                 :             : 
   20592                 :  1257378631 :       if (!type && cxx_dialect >= cxx17)
   20593                 :             :         {
   20594                 :             :           /* Try class template argument deduction or type-constraint without
   20595                 :             :              template arguments.  */
   20596                 :  1256595996 :           tree name = cp_parser_identifier (parser);
   20597                 :  1256595996 :           if (name && TREE_CODE (name) == IDENTIFIER_NODE
   20598                 :   680753526 :               && parser->scope != error_mark_node)
   20599                 :             :             {
   20600                 :   680753526 :               location_t loc
   20601                 :   680753526 :                 = cp_lexer_previous_token (parser->lexer)->location;
   20602                 :   680753526 :               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                 :   680753526 :               if (tmpl && tmpl != error_mark_node
   20610                 :  1358777711 :                   && ctad_template_p (tmpl))
   20611                 :     7354261 :                 type = make_template_placeholder (tmpl);
   20612                 :   673399265 :               else if (flag_concepts && tmpl && concept_definition_p (tmpl))
   20613                 :     1184209 :                 type = cp_parser_placeholder_type_specifier (parser, loc,
   20614                 :             :                                                              tmpl, tent);
   20615                 :             :               else
   20616                 :             :                 {
   20617                 :   672215056 :                   type = error_mark_node;
   20618                 :   672214967 :                   if (!cp_parser_simulate_error (parser))
   20619                 :          89 :                     cp_parser_name_lookup_error (parser, name, tmpl,
   20620                 :             :                                                  NLE_TYPE, token->location);
   20621                 :             :                 }
   20622                 :             :             }
   20623                 :             :           else
   20624                 :   575842470 :             type = error_mark_node;
   20625                 :             :         }
   20626                 :             : 
   20627                 :             :       /* If it didn't work out, we don't have a TYPE.  */
   20628                 :  1907420143 :       if ((flags & CP_PARSER_FLAGS_OPTIONAL)
   20629                 :  1907420143 :           && !cp_parser_parse_definitely (parser))
   20630                 :             :         type = NULL_TREE;
   20631                 :             : 
   20632                 :             :       /* Keep track of all name-lookups performed in class scopes.  */
   20633                 :  1907420143 :       if (type
   20634                 :  1907420143 :           && !global_p
   20635                 :  1470774751 :           && !qualified_p
   20636                 :  1356615108 :           && TREE_CODE (type) == TYPE_DECL
   20637                 :  2503270455 :           && identifier_p (DECL_NAME (type)))
   20638                 :   595850312 :         maybe_note_name_used_in_class (DECL_NAME (type), type);
   20639                 :             : 
   20640                 :  1907420143 :       if (type && decl_specs)
   20641                 :   647677067 :         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                 :  2480072676 :   if (!type && !(flags & CP_PARSER_FLAGS_OPTIONAL))
   20648                 :             :     {
   20649                 :         370 :       cp_parser_error (parser, "expected type-name");
   20650                 :         370 :       return error_mark_node;
   20651                 :             :     }
   20652                 :             : 
   20653                 :  1471834278 :   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                 :           0 :       if (c_dialect_objc () && !parser->scope
   20662                 :   629296342 :           && (objc_is_id (type) || objc_is_class_name (type)))
   20663                 :             :         {
   20664                 :           0 :           tree protos = cp_parser_objc_protocol_refs_opt (parser);
   20665                 :           0 :           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                 :           0 :           if (decl_specs)
   20670                 :           0 :             decl_specs->type = qual_type;
   20671                 :             : 
   20672                 :           0 :           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                 :   629296342 :       cp_parser_check_for_invalid_template_id (parser, type,
   20679                 :             :                                                none_type,
   20680                 :             :                                                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                 :             : 
   20705                 :             : static tree
   20706                 :     2475081 : cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
   20707                 :             :                                       tree tmpl, bool tentative)
   20708                 :             : {
   20709                 :     2475081 :   if (tmpl == error_mark_node)
   20710                 :             :     return error_mark_node;
   20711                 :             : 
   20712                 :     2475081 :   tree orig_tmpl = tmpl;
   20713                 :             : 
   20714                 :             :   /* Get the arguments as written for subsequent analysis.  */
   20715                 :     2475081 :   tree args = NULL_TREE;
   20716                 :     2475081 :   if (TREE_CODE (tmpl) == TEMPLATE_ID_EXPR)
   20717                 :             :     {
   20718                 :     1290872 :       args = TREE_OPERAND (tmpl, 1);
   20719                 :     1290872 :       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                 :     2475081 :   tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error;
   20726                 :             : 
   20727                 :             :   /* Get the concept and prototype parameter for the constraint.  */
   20728                 :     2475081 :   tree_pair info = finish_type_constraints (tmpl, args, complain);
   20729                 :     2475081 :   tree con = info.first;
   20730                 :     2475081 :   tree proto = info.second;
   20731                 :     2475081 :   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                 :     1977275 :   cp_token *placeholder = NULL, *close_paren = NULL;
   20737                 :     1977275 :   if (cxx_dialect >= cxx20)
   20738                 :             :     {
   20739                 :     1977114 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
   20740                 :       10114 :         placeholder = cp_lexer_consume_token (parser->lexer);
   20741                 :     1967000 :       else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DECLTYPE))
   20742                 :             :         {
   20743                 :          24 :           placeholder = cp_lexer_consume_token (parser->lexer);
   20744                 :          24 :           matching_parens parens;
   20745                 :          24 :           parens.require_open (parser);
   20746                 :          24 :           cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
   20747                 :          24 :           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                 :     1977275 :   if (TREE_CODE (proto) != TYPE_DECL)
   20755                 :             :     {
   20756                 :          26 :       if (!flag_concepts_ts
   20757                 :          14 :           || !processing_template_parmlist)
   20758                 :             :         {
   20759                 :          18 :           if (!tentative)
   20760                 :             :             {
   20761                 :          15 :               error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
   20762                 :          15 :               inform (DECL_SOURCE_LOCATION (con), "concept defined here");
   20763                 :             :             }
   20764                 :          18 :           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                 :     1977257 :   if (processing_template_parmlist && !placeholder)
   20771                 :             :     {
   20772                 :             :       /* In a default argument we may not be creating new parameters.  */
   20773                 :     1687474 :       if (parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
   20774                 :             :         {
   20775                 :             :           /* If this assert turns out to be false, do error() instead.  */
   20776                 :           1 :           gcc_assert (tentative);
   20777                 :           1 :           return error_mark_node;
   20778                 :             :         }
   20779                 :     1687473 :       return build_constrained_parameter (con, proto, args);
   20780                 :             :     }
   20781                 :             : 
   20782                 :             :   /* Diagnose issues placeholder issues.  */
   20783                 :      289783 :   if (!flag_concepts_ts
   20784                 :      289380 :       && !parser->in_result_type_constraint_p
   20785                 :       21013 :       && !placeholder)
   20786                 :             :     {
   20787                 :       10887 :       if (tentative)
   20788                 :             :         /* Perhaps it's a concept-check expression (c++/91073).  */
   20789                 :       10875 :         return error_mark_node;
   20790                 :             : 
   20791                 :          12 :       tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
   20792                 :          12 :       tree expr = DECL_P (orig_tmpl) ? DECL_NAME (con) : id;
   20793                 :          12 :       error_at (input_location,
   20794                 :             :                 "expected %<auto%> or %<decltype(auto)%> after %qE", expr);
   20795                 :             :       /* Fall through. This is an error of omission.  */
   20796                 :          12 :     }
   20797                 :      278896 :   else if (parser->in_result_type_constraint_p && placeholder)
   20798                 :             :     {
   20799                 :             :       /* A trailing return type only allows type-constraints.  */
   20800                 :           0 :       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                 :      278908 :   if (parser->auto_is_implicit_function_template_parm_p)
   20807                 :             :     {
   20808                 :        5157 :       if (close_paren)
   20809                 :             :         {
   20810                 :           1 :           location_t loc = make_location (placeholder->location,
   20811                 :             :                                           placeholder->location,
   20812                 :             :                                           close_paren->location);
   20813                 :           1 :           error_at (loc, "cannot declare a parameter with %<decltype(auto)%>");
   20814                 :           1 :           return error_mark_node;
   20815                 :             :         }
   20816                 :        5156 :       tree parm = build_constrained_parameter (con, proto, args);
   20817                 :        5156 :       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                 :      547502 :   bool decltype_p = placeholder
   20824                 :      273751 :     ? placeholder->keyword == RID_DECLTYPE
   20825                 :      268710 :     : parser->in_result_type_constraint_p;
   20826                 :             : 
   20827                 :             :   /* Otherwise, this is the type of a variable or return type.  */
   20828                 :      273751 :   if (decltype_p)
   20829                 :      268686 :     return make_constrained_decltype_auto (con, args);
   20830                 :             :   else
   20831                 :        5065 :     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                 :             : 
   20859                 :             : static tree
   20860                 :  1905118390 : cp_parser_type_name (cp_parser* parser, bool typename_keyword_p)
   20861                 :             : {
   20862                 :  1905118390 :   tree type_decl;
   20863                 :             : 
   20864                 :             :   /* We can't know yet whether it is a class-name or not.  */
   20865                 :  1905118390 :   cp_parser_parse_tentatively (parser);
   20866                 :             :   /* Try a class-name.  */
   20867                 :  1905118390 :   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                 :  1905118390 :   if (!cp_parser_parse_definitely (parser))
   20876                 :             :     {
   20877                 :  1365588536 :       if (cxx_dialect < cxx11)
   20878                 :             :         /* It must be a typedef-name or an enum-name.  */
   20879                 :     7086400 :         return cp_parser_nonclass_name (parser);
   20880                 :             : 
   20881                 :  1358502136 :       cp_parser_parse_tentatively (parser);
   20882                 :             :       /* It is either a simple-template-id representing an
   20883                 :             :          instantiation of an alias template...  */
   20884                 :  1358502136 :       type_decl = cp_parser_template_id (parser,
   20885                 :             :                                          /*template_keyword_p=*/false,
   20886                 :             :                                          /*check_dependency_p=*/true,
   20887                 :             :                                          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                 :  1358502136 :       if (type_decl != NULL_TREE
   20903                 :  1358502136 :           && TREE_CODE (type_decl) == TYPE_DECL
   20904                 :  1359099495 :           && TYPE_DECL_ALIAS_P (type_decl))
   20905                 :      597359 :         gcc_assert (DECL_TEMPLATE_INSTANTIATION (type_decl));
   20906                 :             :       else
   20907                 :  2716406913 :         cp_parser_simulate_error (parser);
   20908                 :             : 
   20909                 :  1358502136 :       if (!cp_parser_parse_definitely (parser))
   20910                 :             :         /* ... Or a typedef-name or an enum-name.  */
   20911                 :  1357904777 :         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                 :             : 
   20931                 :             : static tree
   20932                 :  1365268715 : cp_parser_nonclass_name (cp_parser* parser)
   20933                 :             : {
   20934                 :  1365268715 :   tree type_decl;
   20935                 :  1365268715 :   tree identifier;
   20936                 :             : 
   20937                 :  1365268715 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   20938                 :  1365268715 :   identifier = cp_parser_identifier (parser);
   20939                 :  1365268715 :   if (identifier == error_mark_node)
   20940                 :             :     return error_mark_node;
   20941                 :             : 
   20942                 :             :   /* Look up the type-name.  */
   20943                 :   774435642 :   type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
   20944                 :             : 
   20945                 :   774435642 :   type_decl = strip_using_decl (type_decl);
   20946                 :             : 
   20947                 :   774435642 :   if (TREE_CODE (type_decl) != TYPE_DECL
   20948                 :   774435642 :       && (objc_is_id (identifier) || objc_is_class_name (identifier)))
   20949                 :             :     {
   20950                 :             :       /* See if this is an Objective-C type.  */
   20951                 :           0 :       tree protos = cp_parser_objc_protocol_refs_opt (parser);
   20952                 :           0 :       tree type = objc_get_protocol_qualified_type (identifier, protos);
   20953                 :           0 :       if (type)
   20954                 :           0 :         type_decl = TYPE_NAME (type);
   20955                 :             :     }
   20956                 :             : 
   20957                 :             :   /* Issue an error if we did not find a type-name.  */
   20958                 :   774435642 :   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                 :   774435642 :       || (objc_is_class_name (TREE_TYPE (type_decl))
   20966                 :           0 :           && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT))
   20967                 :             :     {
   20968                 :   696281600 :       if (!cp_parser_simulate_error (parser))
   20969                 :          85 :         cp_parser_name_lookup_error (parser, identifier, type_decl,
   20970                 :             :                                      NLE_TYPE, token->location);
   20971                 :   696281685 :       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                 :    78153957 :   else if (type_decl != error_mark_node
   20978                 :    78153957 :            && !parser->scope)
   20979                 :    71790878 :     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                 :             : 
   21010                 :             : static tree
   21011                 :    38160237 : cp_parser_elaborated_type_specifier (cp_parser* parser,
   21012                 :             :                                      bool is_friend,
   21013                 :             :                                      bool is_declaration)
   21014                 :             : {
   21015                 :    38160237 :   enum tag_types tag_type;
   21016                 :    38160237 :   tree identifier;
   21017                 :    38160237 :   tree type = NULL_TREE;
   21018                 :    38160237 :   tree attributes = NULL_TREE;
   21019                 :    38160237 :   tree globalscope;
   21020                 :    38160237 :   cp_token *token = NULL;
   21021                 :             : 
   21022                 :             :   /* For class and enum types the location of the class-key or enum-key.  */
   21023                 :    38160237 :   location_t key_loc = cp_lexer_peek_token (parser->lexer)->location;
   21024                 :             :   /* For a scoped enum, the 'class' or 'struct' keyword id.  */
   21025                 :    38160237 :   rid scoped_key = RID_MAX;
   21026                 :             : 
   21027                 :             :   /* See if we're looking at the `enum' keyword.  */
   21028                 :    38160237 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
   21029                 :             :     {
   21030                 :             :       /* Consume the `enum' token.  */
   21031                 :       26348 :       cp_lexer_consume_token (parser->lexer);
   21032                 :             :       /* Remember that it's an enumeration type.  */
   21033                 :       26348 :       tag_type = enum_type;
   21034                 :             :       /* Issue a warning if the `struct' or `class' key (for C++0x scoped
   21035                 :             :          enums) is used here.  */
   21036                 :       26348 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   21037                 :       26348 :       if (cp_parser_is_keyword (token, scoped_key = RID_CLASS)
   21038                 :       26348 :           || cp_parser_is_keyword (token, scoped_key = RID_STRUCT))
   21039                 :             :         {
   21040                 :          79 :           location_t loc = token->location;
   21041                 :          79 :           gcc_rich_location richloc (loc);
   21042                 :          79 :           richloc.add_range (input_location);
   21043                 :          79 :           richloc.add_fixit_remove ();
   21044                 :          79 :           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                 :          79 :           cp_lexer_consume_token (parser->lexer);
   21049                 :             :           /* Create a combined location for the whole scoped-enum-key.  */
   21050                 :          79 :           key_loc = make_location (key_loc, key_loc, loc);
   21051                 :          79 :         }
   21052                 :             :       else
   21053                 :             :         scoped_key = RID_MAX;
   21054                 :             : 
   21055                 :             :       /* Parse the attributes.  */
   21056                 :       26348 :       attributes = cp_parser_attributes_opt (parser);
   21057                 :             :     }
   21058                 :             :   /* Or, it might be `typename'.  */
   21059                 :    38133889 :   else if (cp_lexer_next_token_is_keyword (parser->lexer,
   21060                 :             :                                            RID_TYPENAME))
   21061                 :             :     {
   21062                 :             :       /* Consume the `typename' token.  */
   21063                 :    26485682 :       cp_lexer_consume_token (parser->lexer);
   21064                 :             :       /* Remember that it's a `typename' type.  */
   21065                 :    26485682 :       tag_type = typename_type;
   21066                 :             :     }
   21067                 :             :   /* Otherwise it must be a class-key.  */
   21068                 :             :   else
   21069                 :             :     {
   21070                 :    11648207 :       key_loc = cp_lexer_peek_token (parser->lexer)->location;
   21071                 :    11648207 :       tag_type = cp_parser_class_key (parser);
   21072                 :    11648207 :       if (tag_type == none_type)
   21073                 :           0 :         return error_mark_node;
   21074                 :             :       /* Parse the attributes.  */
   21075                 :    11648207 :       attributes = cp_parser_attributes_opt (parser);
   21076                 :             :     }
   21077                 :             : 
   21078                 :             :   /* Look for the `::' operator.  */
   21079                 :    38160237 :   globalscope =  cp_parser_global_scope_opt (parser,
   21080                 :             :                                              /*current_scope_valid_p=*/false);
   21081                 :             :   /* Look for the nested-name-specifier.  */
   21082                 :    38160237 :   tree nested_name_specifier;
   21083                 :    38160237 :   if (tag_type == typename_type && !globalscope)
   21084                 :             :     {
   21085                 :    26482166 :       nested_name_specifier
   21086                 :    26482166 :         = cp_parser_nested_name_specifier (parser,
   21087                 :             :                                            /*typename_keyword_p=*/true,
   21088                 :             :                                            /*check_dependency_p=*/true,
   21089                 :             :                                            /*type_p=*/true,
   21090                 :             :                                            is_declaration);
   21091                 :    26482166 :       if (!nested_name_specifier)
   21092                 :          96 :         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                 :    11678071 :     nested_name_specifier
   21099                 :    11678071 :       = 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                 :    38160141 :   if (tag_type != enum_type)
   21107                 :             :     {
   21108                 :    38133793 :       bool template_p = false;
   21109                 :    38133793 :       tree decl;
   21110                 :             : 
   21111                 :             :       /* Allow the `template' keyword.  */
   21112                 :    38133793 :       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                 :    38133793 :       if (!template_p)
   21116                 :    38030444 :         cp_parser_parse_tentatively (parser);
   21117                 :             :       /* The `template' keyword must follow a nested-name-specifier.  */
   21118                 :      103349 :       else if (!nested_name_specifier && !globalscope)
   21119                 :             :         {
   21120                 :           8 :           cp_parser_error (parser, "%<template%> must follow a nested-"
   21121                 :             :                            "name-specifier");
   21122                 :           8 :           return error_mark_node;
   21123                 :             :         }
   21124                 :             : 
   21125                 :             :       /* Parse the template-id.  */
   21126                 :    38133785 :       token = cp_lexer_peek_token (parser->lexer);
   21127                 :    38133785 :       decl = cp_parser_template_id (parser, 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                 :    38133785 :       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                 :     1673111 :       else if (tag_type == typename_type && BASELINK_P (decl))
   21142                 :             :         {
   21143                 :           0 :           cp_parser_diagnose_invalid_type_name (parser, decl, token->location);
   21144                 :           0 :           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                 :     1673111 :       else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
   21150                 :      103296 :                && tag_type == typename_type)
   21151                 :      103296 :         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                 :     1569815 :       else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
   21157                 :             :         ;
   21158                 :     1569801 :       else if (TREE_CODE (decl) == TYPE_DECL)
   21159                 :             :         {
   21160                 :     1569779 :           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                 :     1569779 :           if (type != error_mark_node
   21167                 :     1569758 :               && !nested_name_specifier && !is_friend
   21168                 :     2615574 :               && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   21169                 :     1045343 :             check_unqualified_spec_or_inst (type, token->location);
   21170                 :             :         }
   21171                 :          22 :       else if (decl == error_mark_node)
   21172                 :          22 :         type = error_mark_node;
   21173                 :             :     }
   21174                 :             : 
   21175                 :    38160133 :   if (!type)
   21176                 :             :     {
   21177                 :    36487036 :       token = cp_lexer_peek_token (parser->lexer);
   21178                 :    36487036 :       identifier = cp_parser_identifier (parser);
   21179                 :             : 
   21180                 :    36487036 :       if (identifier == error_mark_node)
   21181                 :             :         {
   21182                 :          89 :           parser->scope = NULL_TREE;
   21183                 :          89 :           return error_mark_node;
   21184                 :             :         }
   21185                 :             : 
   21186                 :             :       /* For a `typename', we needn't call xref_tag.  */
   21187                 :    36486947 :       if (tag_type == typename_type
   21188                 :    26360634 :           && TREE_CODE (parser->scope) != NAMESPACE_DECL)
   21189                 :    26358566 :         return cp_parser_make_typename_type (parser, identifier,
   21190                 :    26358566 :                                              token->location);
   21191                 :             : 
   21192                 :             :       /* Template parameter lists apply only if we are not within a
   21193                 :             :          function parameter list.  */
   21194                 :    10128381 :       bool template_parm_lists_apply
   21195                 :    10128381 :           = parser->num_template_parameter_lists;
   21196                 :    10128381 :       if (template_parm_lists_apply)
   21197                 :     5135381 :         for (cp_binding_level *s = current_binding_level;
   21198                 :     5137341 :              s && s->kind != sk_template_parms;
   21199                 :        1960 :              s = s->level_chain)
   21200                 :        1960 :           if (s->kind == sk_function_parms)
   21201                 :        1944 :             template_parm_lists_apply = false;
   21202                 :             : 
   21203                 :             :       /* Look up a qualified name in the usual way.  */
   21204                 :    10128381 :       if (parser->scope)
   21205                 :             :         {
   21206                 :     4376609 :           tree decl;
   21207                 :     4376609 :           tree ambiguous_decls;
   21208                 :             : 
   21209                 :     4376609 :           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                 :     4376609 :           if (ambiguous_decls)
   21220                 :         116 :             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                 :     4376605 :           decl = (cp_parser_maybe_treat_template_as_class
   21244                 :     8753210 :                   (decl, /*tag_name_p=*/is_friend
   21245                 :     4376605 :                          && template_parm_lists_apply));
   21246                 :             : 
   21247                 :     4376605 :           if (TREE_CODE (decl) != TYPE_DECL)
   21248                 :             :             {
   21249                 :          81 :               cp_parser_diagnose_invalid_type_name (parser,
   21250                 :             :                                                     identifier,
   21251                 :             :                                                     token->location);
   21252                 :          81 :               return error_mark_node;
   21253                 :             :             }
   21254                 :             : 
   21255                 :     4376524 :           if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
   21256                 :             :             {
   21257                 :     4375341 :               bool allow_template = (template_parm_lists_apply
   21258                 :     4375341 :                                      || DECL_SELF_REFERENCE_P (decl));
   21259                 :     4375341 :               type = check_elaborated_type_specifier (tag_type, decl,
   21260                 :             :                                                       allow_template);
   21261                 :             : 
   21262                 :     4375341 :               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                 :     4376493 :           if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
   21280                 :      209959 :               && !is_friend && is_declaration
   21281                 :     4376537 :               && !processing_explicit_instantiation)
   21282                 :          32 :             warning (0, "declaration %qD does not declare anything", decl);
   21283                 :             : 
   21284                 :     4376493 :           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                 :     5751772 :           TAG_how how;
   21332                 :             : 
   21333                 :     5751772 :           if (is_friend)
   21334                 :             :             /* Friends have special name lookup rules.  */
   21335                 :             :             how = TAG_how::HIDDEN_FRIEND;
   21336                 :     5108774 :           else if (is_declaration
   21337                 :     5108774 :                    && cp_lexer_next_token_is (parser->lexer,
   21338                 :             :                                               CPP_SEMICOLON))
   21339                 :             :             /* This is a `class-key identifier ;' */
   21340                 :             :             how = TAG_how::CURRENT_ONLY;
   21341                 :             :           else
   21342                 :             :             how = TAG_how::GLOBAL;
   21343                 :             : 
   21344                 :     5751772 :           bool template_p =
   21345                 :             :             (template_parm_lists_apply
   21346                 :     5751772 :              && (cp_parser_next_token_starts_class_definition_p (parser)
   21347                 :     2894913 :                  || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)));
   21348                 :             :           /* An unqualified name was used to reference this type, so
   21349                 :             :              there were no qualifying templates.  */
   21350                 :     2894919 :           if (template_parm_lists_apply
   21351                 :     2894919 :               && !cp_parser_check_template_parameters (parser,
   21352                 :             :                                                        /*num_templates=*/0,
   21353                 :             :                                                        /*template_id*/false,
   21354                 :             :                                                        token->location,
   21355                 :             :                                                        /*declarator=*/NULL))
   21356                 :           4 :             return error_mark_node;
   21357                 :             : 
   21358                 :     5751768 :           type = xref_tag (tag_type, identifier, how, template_p);
   21359                 :             :         }
   21360                 :             :     }
   21361                 :             : 
   21362                 :    11801358 :   if (type == error_mark_node)
   21363                 :             :     return error_mark_node;
   21364                 :             : 
   21365                 :             :   /* Allow attributes on forward declarations of classes.  */
   21366                 :    11801151 :   if (attributes)
   21367                 :             :     {
   21368                 :         104 :       if (TREE_CODE (type) == TYPENAME_TYPE)
   21369                 :           7 :         warning (OPT_Wattributes,
   21370                 :             :                  "attributes ignored on uninstantiated type");
   21371                 :          97 :       else if (tag_type != enum_type
   21372                 :          90 :                && TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM
   21373                 :          87 :                && CLASSTYPE_TEMPLATE_INSTANTIATION (type)
   21374                 :         124 :                && ! processing_explicit_instantiation)
   21375                 :           7 :         warning (OPT_Wattributes,
   21376                 :             :                  "attributes ignored on template instantiation");
   21377                 :          90 :       else if (is_friend && cxx11_attribute_p (attributes))
   21378                 :             :         {
   21379                 :           3 :           if (warning (OPT_Wattributes, "attribute ignored"))
   21380                 :           3 :             inform (input_location, "an attribute that appertains to a friend "
   21381                 :             :                     "declaration that is not a definition is ignored");
   21382                 :             :         }
   21383                 :          87 :       else if (is_declaration && cp_parser_declares_only_class_p (parser))
   21384                 :          68 :         cplus_decl_attributes (&type, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
   21385                 :             :       else
   21386                 :          19 :         warning (OPT_Wattributes,
   21387                 :             :                  "attributes ignored on elaborated-type-specifier that is "
   21388                 :             :                  "not a forward declaration");
   21389                 :             :     }
   21390                 :             : 
   21391                 :    11801151 :   if (tag_type == enum_type)
   21392                 :       26309 :     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                 :    11774842 :       bool decl_class = (is_declaration
   21398                 :    11774842 :                          && cp_parser_declares_only_class_p (parser));
   21399                 :    11774842 :       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                 :    11774842 :       if (CLASS_TYPE_P (type) && !currently_open_class (type))
   21405                 :    11395879 :         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                 :    11801151 :   cp_parser_check_for_invalid_template_id (parser, type, tag_type,
   21411                 :             :                                            token->location);
   21412                 :             : 
   21413                 :    11801151 :   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                 :             : 
   21446                 :             : static tree
   21447                 :     1578245 : cp_parser_enum_specifier (cp_parser* parser)
   21448                 :             : {
   21449                 :     1578245 :   tree identifier;
   21450                 :     1578245 :   tree type = NULL_TREE;
   21451                 :     1578245 :   tree prev_scope;
   21452                 :     1578245 :   tree nested_name_specifier = NULL_TREE;
   21453                 :     1578245 :   tree attributes;
   21454                 :     1578245 :   bool scoped_enum_p = false;
   21455                 :     1578245 :   bool has_underlying_type = false;
   21456                 :     1578245 :   bool nested_being_defined = false;
   21457                 :     1578245 :   bool new_value_list = false;
   21458                 :     1578245 :   bool is_new_type = false;
   21459                 :     1578245 :   bool is_unnamed = false;
   21460                 :     1578245 :   tree underlying_type = NULL_TREE;
   21461                 :     1578245 :   cp_token *type_start_token = NULL;
   21462                 :     1578245 :   auto cleanup = make_temp_override (parser->colon_corrects_to_scope_p, false);
   21463                 :             : 
   21464                 :             :   /* Parse tentatively so that we can back up if we don't find a
   21465                 :             :      enum-specifier.  */
   21466                 :     1578245 :   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                 :     1578245 :   cp_lexer_consume_token (parser->lexer);
   21473                 :             : 
   21474                 :             :   /* Parse the "class" or "struct", which indicates a scoped
   21475                 :             :      enumeration type in C++0x.  */
   21476                 :     1578245 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CLASS)
   21477                 :     1578245 :       || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
   21478                 :             :     {
   21479                 :      251803 :       if (cxx_dialect < cxx11)
   21480                 :           8 :         maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
   21481                 :             : 
   21482                 :             :       /* Consume the `struct' or `class' token.  */
   21483                 :      251803 :       cp_lexer_consume_token (parser->lexer);
   21484                 :             : 
   21485                 :      251803 :       scoped_enum_p = true;
   21486                 :             :     }
   21487                 :             : 
   21488                 :     1578245 :   attributes = cp_parser_attributes_opt (parser);
   21489                 :             : 
   21490                 :             :   /* Clear the qualification.  */
   21491                 :     1578245 :   parser->scope = NULL_TREE;
   21492                 :     1578245 :   parser->qualifying_scope = NULL_TREE;
   21493                 :     1578245 :   parser->object_scope = NULL_TREE;
   21494                 :             : 
   21495                 :             :   /* Figure out in what scope the declaration is being placed.  */
   21496                 :     1578245 :   prev_scope = current_scope ();
   21497                 :             : 
   21498                 :     1578245 :   type_start_token = cp_lexer_peek_token (parser->lexer);
   21499                 :             : 
   21500                 :     1578245 :   push_deferring_access_checks (dk_no_check);
   21501                 :     1578245 :   nested_name_specifier
   21502                 :     1578245 :     = 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                 :     1578245 :   if (nested_name_specifier)
   21509                 :             :     {
   21510                 :         310 :       tree name;
   21511                 :             : 
   21512                 :         310 :       identifier = cp_parser_identifier (parser);
   21513                 :         310 :       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                 :         310 :       if (name && name != error_mark_node)
   21521                 :             :         {
   21522                 :         299 :           type = TREE_TYPE (name);
   21523                 :         299 :           if (TREE_CODE (type) == TYPENAME_TYPE)
   21524                 :             :             {
   21525                 :             :               /* Are template enums allowed in ISO? */
   21526                 :          80 :               if (template_parm_scope_p ())
   21527                 :          21 :                 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                 :          80 :               type = NULL_TREE;
   21532                 :             :             }
   21533                 :             :         }
   21534                 :          11 :       else if (nested_name_specifier == error_mark_node)
   21535                 :             :         /* We already issued an error.  */;
   21536                 :             :       else
   21537                 :             :         {
   21538                 :           8 :           error_at (type_start_token->location,
   21539                 :             :                     "%qD does not name an enumeration in %qT",
   21540                 :             :                     identifier, nested_name_specifier);
   21541                 :           8 :           nested_name_specifier = error_mark_node;
   21542                 :             :         }
   21543                 :             :     }
   21544                 :             :   else
   21545                 :             :     {
   21546                 :     1577935 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   21547                 :      553998 :         identifier = cp_parser_identifier (parser);
   21548                 :             :       else
   21549                 :             :         {
   21550                 :     1023937 :           identifier = make_anon_name ();
   21551                 :     1023937 :           is_unnamed = true;
   21552                 :     1023937 :           if (scoped_enum_p)
   21553                 :           6 :             error_at (type_start_token->location,
   21554                 :             :                       "unnamed scoped enum is not allowed");
   21555                 :             :         }
   21556                 :             :     }
   21557                 :     1578245 :   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                 :     1578245 :   location_t colon_loc = UNKNOWN_LOCATION;
   21562                 :     1578245 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   21563                 :             :     {
   21564                 :      203769 :       cp_decl_specifier_seq type_specifiers;
   21565                 :             : 
   21566                 :             :       /* Consume the `:'.  */
   21567                 :      203769 :       colon_loc = cp_lexer_peek_token (parser->lexer)->location;
   21568                 :      203769 :       cp_lexer_consume_token (parser->lexer);
   21569                 :             : 
   21570                 :      203769 :       auto tdf
   21571                 :      203769 :         = make_temp_override (parser->type_definition_forbidden_message,
   21572                 :      203769 :                               G_("types may not be defined in enum-base"));
   21573                 :             : 
   21574                 :             :       /* Parse the type-specifier-seq.  */
   21575                 :      203769 :       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                 :      203769 :       if (!cp_parser_parse_definitely (parser))
   21582                 :          16 :         return NULL_TREE;
   21583                 :             : 
   21584                 :      203753 :       if (cxx_dialect < cxx11)
   21585                 :           5 :         maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);
   21586                 :             : 
   21587                 :      203753 :       has_underlying_type = true;
   21588                 :             : 
   21589                 :             :       /* If that didn't work, stop.  */
   21590                 :      203753 :       if (type_specifiers.type != error_mark_node)
   21591                 :             :         {
   21592                 :      203753 :           underlying_type = grokdeclarator (NULL, &type_specifiers, TYPENAME,
   21593                 :             :                                             /*initialized=*/0, NULL);
   21594                 :      203753 :           if (underlying_type == error_mark_node
   21595                 :      203753 :               || check_for_bare_parameter_packs (underlying_type))
   21596                 :             :             underlying_type = NULL_TREE;
   21597                 :             :         }
   21598                 :      203769 :     }
   21599                 :             : 
   21600                 :             :   /* Look for the `{' but don't consume it yet.  */
   21601                 :     1578229 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   21602                 :             :     {
   21603                 :       49180 :       if (cxx_dialect < cxx11 || (!scoped_enum_p && !underlying_type))
   21604                 :             :         {
   21605                 :       26259 :           if (has_underlying_type)
   21606                 :           2 :             cp_parser_commit_to_tentative_parse (parser);
   21607                 :       26259 :           cp_parser_error (parser, "expected %<{%>");
   21608                 :       26259 :           if (has_underlying_type)
   21609                 :           2 :             return error_mark_node;
   21610                 :             :         }
   21611                 :             :       /* An opaque-enum-specifier must have a ';' here.  */
   21612                 :       49178 :       if ((scoped_enum_p || underlying_type)
   21613                 :       49178 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   21614                 :             :         {
   21615                 :          93 :           if (has_underlying_type)
   21616                 :          21 :             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                 :          72 :             cp_parser_error (parser, "expected %<;%> or %<{%>");
   21623                 :             :         }
   21624                 :             :     }
   21625                 :             : 
   21626                 :     1578227 :   if (!has_underlying_type && !cp_parser_parse_definitely (parser))
   21627                 :             :     return NULL_TREE;
   21628                 :             : 
   21629                 :     1551898 :   if (nested_name_specifier)
   21630                 :             :     {
   21631                 :         195 :       if (CLASS_TYPE_P (nested_name_specifier))
   21632                 :             :         {
   21633                 :         136 :           nested_being_defined = TYPE_BEING_DEFINED (nested_name_specifier);
   21634                 :         136 :           TYPE_BEING_DEFINED (nested_name_specifier) = 1;
   21635                 :         136 :           push_scope (nested_name_specifier);
   21636                 :             :         }
   21637                 :          59 :       else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
   21638                 :          40 :         push_nested_namespace (nested_name_specifier);
   21639                 :             :     }
   21640                 :             : 
   21641                 :             :   /* Issue an error message if type-definitions are forbidden here.  */
   21642                 :     1551898 :   if (!cp_parser_check_type_definition (parser))
   21643                 :          24 :     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                 :     1551874 :     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                 :     1551898 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   21654                 :             :     {
   21655                 :     1529049 :       auto_timevar tv (TV_PARSE_ENUM);
   21656                 :             : 
   21657                 :     1529049 :       if (nested_name_specifier
   21658                 :         189 :           && 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                 :         178 :           if (!processing_specialization
   21663                 :         169 :               && CLASS_TYPE_P (nested_name_specifier)
   21664                 :         302 :               && CLASSTYPE_USE_TEMPLATE (nested_name_specifier))
   21665                 :           0 :             error_at (type_start_token->location, "cannot add an enumerator "
   21666                 :             :                       "list to a template instantiation");
   21667                 :             : 
   21668                 :         178 :           if (TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
   21669                 :             :             {
   21670                 :           4 :               error_at (type_start_token->location,
   21671                 :             :                         "%<%T::%E%> has not been declared",
   21672                 :           4 :                         TYPE_CONTEXT (nested_name_specifier),
   21673                 :             :                         nested_name_specifier);
   21674                 :           4 :               type = error_mark_node;
   21675                 :             :             }
   21676                 :         174 :           else if (TREE_CODE (nested_name_specifier) != NAMESPACE_DECL
   21677                 :         174 :                    && !CLASS_TYPE_P (nested_name_specifier))
   21678                 :             :             {
   21679                 :           4 :               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                 :           4 :               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                 :         170 :           else if (prev_scope && !is_ancestor (prev_scope,
   21687                 :             :                                                nested_name_specifier))
   21688                 :             :             {
   21689                 :          12 :               if (at_namespace_scope_p ())
   21690                 :           6 :                 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                 :           6 :                 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                 :          12 :               type = error_mark_node;
   21700                 :             :             }
   21701                 :             :           /* If that scope is the scope where the declaration is being placed
   21702                 :             :              the program is invalid.  */
   21703                 :         127 :           else if (CLASS_TYPE_P (nested_name_specifier)
   21704                 :         127 :                    && CLASS_TYPE_P (prev_scope)
   21705                 :         203 :                    && same_type_p (nested_name_specifier, prev_scope))
   21706                 :             :             {
   21707                 :          30 :               permerror (type_start_token->location,
   21708                 :             :                          "extra qualification not allowed");
   21709                 :          30 :               nested_name_specifier = NULL_TREE;
   21710                 :             :             }
   21711                 :             :         }
   21712                 :             : 
   21713                 :     1529049 :       if (scoped_enum_p)
   21714                 :      229826 :         begin_scope (sk_scoped_enum, type);
   21715                 :             : 
   21716                 :             :       /* Consume the opening brace.  */
   21717                 :     1529049 :       matching_braces braces;
   21718                 :     1529049 :       braces.consume_open (parser);
   21719                 :             : 
   21720                 :     1529049 :       if (type == error_mark_node)
   21721                 :             :         ; /* Nothing to add */
   21722                 :     1528990 :       else if (OPAQUE_ENUM_P (type)
   21723                 :     1529013 :                || (cxx_dialect > cxx98 && processing_specialization))
   21724                 :             :         {
   21725                 :     1528979 :           new_value_list = true;
   21726                 :     1528979 :           SET_OPAQUE_ENUM_P (type, false);
   21727                 :     1528979 :           DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
   21728                 :             :         }
   21729                 :             :       else
   21730                 :             :         {
   21731                 :          11 :           error_at (type_start_token->location,
   21732                 :             :                     "multiple definition of %q#T", type);
   21733                 :          11 :           inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
   21734                 :             :                   "previous definition here");
   21735                 :          11 :           type = error_mark_node;
   21736                 :             :         }
   21737                 :             : 
   21738                 :     1529049 :       if (type == error_mark_node)
   21739                 :          70 :         cp_parser_skip_to_end_of_block_or_statement (parser);
   21740                 :             :       /* If the next token is not '}', then there are some enumerators.  */
   21741                 :     1528979 :       else if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   21742                 :             :         {
   21743                 :       25850 :           if (is_unnamed && !scoped_enum_p
   21744                 :             :               /* Don't warn for enum {} a; here.  */
   21745                 :       25850 :               && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SEMICOLON))
   21746                 :           3 :             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                 :     1503129 :           cp_parser_commit_to_tentative_parse (parser);
   21754                 :     1503129 :           cp_parser_enumerator_list (parser, type);
   21755                 :             :         }
   21756                 :             : 
   21757                 :             :       /* Consume the final '}'.  */
   21758                 :     1529049 :       braces.require_close (parser);
   21759                 :             : 
   21760                 :     1529049 :       if (scoped_enum_p)
   21761                 :      229826 :         finish_scope ();
   21762                 :     1529049 :     }
   21763                 :             :   else
   21764                 :             :     {
   21765                 :             :       /* If a ';' follows, then it is an opaque-enum-specifier
   21766                 :             :         and additional restrictions apply.  */
   21767                 :       22849 :       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   21768                 :             :         {
   21769                 :       22828 :           if (is_unnamed)
   21770                 :           0 :             error_at (type_start_token->location,
   21771                 :             :                       "opaque-enum-specifier without name");
   21772                 :       22828 :           else if (nested_name_specifier)
   21773                 :           6 :             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                 :     1551898 :   if (cp_parser_allow_gnu_extensions_p (parser))
   21781                 :             :     {
   21782                 :     1551898 :       tree trailing_attr = cp_parser_gnu_attributes_opt (parser);
   21783                 :     1551898 :       cplus_decl_attributes (&type,
   21784                 :             :                              trailing_attr,
   21785                 :             :                              (int) ATTR_FLAG_TYPE_IN_PLACE);
   21786                 :             :     }
   21787                 :             : 
   21788                 :             :   /* Finish up the enumeration.  */
   21789                 :     1551898 :   if (type != error_mark_node)
   21790                 :             :     {
   21791                 :     1551828 :       if (new_value_list)
   21792                 :     1528979 :         finish_enum_value_list (type);
   21793                 :     1551828 :       if (is_new_type)
   21794                 :     1519456 :         finish_enum (type);
   21795                 :             :     }
   21796                 :             : 
   21797                 :     1551898 :   if (nested_name_specifier)
   21798                 :             :     {
   21799                 :         165 :       if (CLASS_TYPE_P (nested_name_specifier))
   21800                 :             :         {
   21801                 :         106 :           TYPE_BEING_DEFINED (nested_name_specifier) = nested_being_defined;
   21802                 :         106 :           pop_scope (nested_name_specifier);
   21803                 :             :         }
   21804                 :          59 :       else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
   21805                 :          40 :         pop_nested_namespace (nested_name_specifier);
   21806                 :             :     }
   21807                 :     1551898 :   return type;
   21808                 :     1578245 : }
   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                 :             : 
   21817                 :             : static void
   21818                 :     1503129 : cp_parser_enumerator_list (cp_parser* parser, tree type)
   21819                 :             : {
   21820                 :     9862047 :   while (true)
   21821                 :             :     {
   21822                 :             :       /* Parse an enumerator-definition.  */
   21823                 :     9862047 :       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                 :     9862047 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   21828                 :             :         break;
   21829                 :             :       /* Otherwise, consume the `,' and keep going.  */
   21830                 :     8410105 :       cp_lexer_consume_token (parser->lexer);
   21831                 :             :       /* If the next token is a `}', there is a trailing comma.  */
   21832                 :     8410105 :       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   21833                 :             :         {
   21834                 :       51187 :           if (cxx_dialect < cxx11)
   21835                 :          95 :             pedwarn (input_location, OPT_Wpedantic,
   21836                 :             :                      "comma at end of enumerator list");
   21837                 :             :           break;
   21838                 :             :         }
   21839                 :             :     }
   21840                 :     1503129 : }
   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                 :             : 
   21858                 :             : static void
   21859                 :     9862047 : cp_parser_enumerator_definition (cp_parser* parser, tree type)
   21860                 :             : {
   21861                 :     9862047 :   tree identifier;
   21862                 :     9862047 :   tree value;
   21863                 :     9862047 :   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                 :     9862047 :   loc = cp_lexer_peek_token (parser->lexer)->location;
   21868                 :             : 
   21869                 :             :   /* Look for the identifier.  */
   21870                 :     9862047 :   identifier = cp_parser_identifier (parser);
   21871                 :     9862047 :   if (identifier == error_mark_node)
   21872                 :             :     return;
   21873                 :             : 
   21874                 :             :   /* Parse any specified attributes.  */
   21875                 :     9862039 :   tree attrs = cp_parser_attributes_opt (parser);
   21876                 :             : 
   21877                 :             :   /* If the next token is an '=', then there is an explicit value.  */
   21878                 :     9862039 :   if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   21879                 :             :     {
   21880                 :             :       /* Consume the `=' token.  */
   21881                 :     4285518 :       cp_lexer_consume_token (parser->lexer);
   21882                 :             :       /* Parse the value.  */
   21883                 :     4285518 :       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                 :     9862039 :   if (current_lambda_expr ())
   21891                 :             :     {
   21892                 :             :       /* In a lambda it should work, but doesn't currently.  */
   21893                 :         135 :       if (uses_parameter_packs (value))
   21894                 :             :         {
   21895                 :           6 :           sorry ("unexpanded parameter pack in enumerator in lambda");
   21896                 :           6 :           value = error_mark_node;
   21897                 :             :         }
   21898                 :             :     }
   21899                 :     9861904 :   else if (check_for_bare_parameter_packs (value))
   21900                 :           3 :     value = error_mark_node;
   21901                 :             : 
   21902                 :             :   /* Create the enumerator.  */
   21903                 :     9862039 :   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                 :             : 
   21914                 :             : static tree
   21915                 :    90126990 : cp_parser_namespace_name (cp_parser* parser)
   21916                 :             : {
   21917                 :    90126990 :   tree identifier;
   21918                 :    90126990 :   tree namespace_decl;
   21919                 :             : 
   21920                 :    90126990 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   21921                 :             : 
   21922                 :             :   /* Get the name of the namespace.  */
   21923                 :    90126990 :   identifier = cp_parser_identifier (parser);
   21924                 :    90126990 :   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                 :    90126990 :   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                 :    90126990 :   if (namespace_decl == error_mark_node
   21954                 :    90126617 :       || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
   21955                 :             :     {
   21956                 :         818 :       if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
   21957                 :             :         {
   21958                 :          33 :           auto_diagnostic_group d;
   21959                 :          33 :           name_hint hint;
   21960                 :          33 :           if (namespace_decl == error_mark_node
   21961                 :          29 :               && parser->scope && TREE_CODE (parser->scope) == NAMESPACE_DECL)
   21962                 :          26 :             hint = suggest_alternative_in_explicit_scope (token->location,
   21963                 :             :                                                           identifier,
   21964                 :          13 :                                                           parser->scope);
   21965                 :          33 :           if (const char *suggestion = hint.suggestion ())
   21966                 :             :             {
   21967                 :           4 :               gcc_rich_location richloc (token->location);
   21968                 :           4 :               richloc.add_fixit_replace (suggestion);
   21969                 :           4 :               error_at (&richloc,
   21970                 :             :                         "%qD is not a namespace-name; did you mean %qs?",
   21971                 :             :                         identifier, suggestion);
   21972                 :           4 :             }
   21973                 :             :           else
   21974                 :          29 :             error_at (token->location, "%qD is not a namespace-name",
   21975                 :             :                       identifier);
   21976                 :          33 :         }
   21977                 :             :       else
   21978                 :         376 :         cp_parser_error (parser, "expected namespace-name");
   21979                 :         409 :       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                 :             : 
   22004                 :             : static void
   22005                 :     4872784 : cp_parser_namespace_definition (cp_parser* parser)
   22006                 :             : {
   22007                 :     4872784 :   tree identifier;
   22008                 :     4872784 :   int nested_definition_count = 0;
   22009                 :             : 
   22010                 :     4872784 :   cp_ensure_no_omp_declare_simd (parser);
   22011                 :     4872784 :   cp_ensure_no_oacc_routine (parser);
   22012                 :             : 
   22013                 :     4872784 :   bool is_inline = cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE);
   22014                 :     4872784 :   const bool topmost_inline_p = is_inline;
   22015                 :             : 
   22016                 :     4872784 :   if (is_inline)
   22017                 :             :     {
   22018                 :      207858 :       maybe_warn_cpp0x (CPP0X_INLINE_NAMESPACES);
   22019                 :      207858 :       cp_lexer_consume_token (parser->lexer);
   22020                 :             :     }
   22021                 :             : 
   22022                 :             :   /* Look for the `namespace' keyword.  */
   22023                 :     4872784 :   cp_token* token
   22024                 :     4872784 :     = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
   22025                 :             : 
   22026                 :             :   /* Parse any specified attributes before the identifier.  */
   22027                 :     4872784 :   tree attribs = cp_parser_attributes_opt (parser);
   22028                 :             : 
   22029                 :     5009782 :   for (;;)
   22030                 :             :     {
   22031                 :     4941283 :       identifier = NULL_TREE;
   22032                 :             : 
   22033                 :     4941283 :       bool nested_inline_p = cp_lexer_next_token_is_keyword (parser->lexer,
   22034                 :             :                                                              RID_INLINE);
   22035                 :     4941283 :       if (nested_inline_p && nested_definition_count != 0)
   22036                 :             :         {
   22037                 :          13 :           if (pedantic && cxx_dialect < cxx20)
   22038                 :           4 :             pedwarn (cp_lexer_peek_token (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                 :          13 :           cp_lexer_consume_token (parser->lexer);
   22043                 :             :         }
   22044                 :             : 
   22045                 :     4941283 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   22046                 :             :         {
   22047                 :     4939504 :           identifier = cp_parser_identifier (parser);
   22048                 :             : 
   22049                 :     4939504 :           if (cp_next_tokens_can_be_std_attribute_p (parser))
   22050                 :           6 :             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                 :     4939504 :           attribs = attr_chainon (attribs, cp_parser_attributes_opt (parser));
   22056                 :             :         }
   22057                 :             : 
   22058                 :     4941283 :       if (cp_lexer_next_token_is_not (parser->lexer, 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                 :     4872784 :           is_inline |= nested_inline_p;
   22065                 :     4872784 :           break;
   22066                 :             :         }
   22067                 :             : 
   22068                 :       68499 :       if (!nested_definition_count && pedantic && cxx_dialect < cxx17)
   22069                 :           5 :         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                 :      136998 :       if (int count = (identifier
   22076                 :       68499 :                        ? push_namespace (identifier, nested_inline_p)
   22077                 :       68499 :                        : 0))
   22078                 :       68499 :         nested_definition_count += count;
   22079                 :             :       else
   22080                 :           0 :         cp_parser_error (parser, "nested namespace name required");
   22081                 :       68499 :       cp_lexer_consume_token (parser->lexer);
   22082                 :       68499 :     }
   22083                 :             : 
   22084                 :     4872784 :   if (nested_definition_count && !identifier)
   22085                 :           2 :     cp_parser_error (parser, "namespace name required");
   22086                 :             : 
   22087                 :     4872784 :   if (nested_definition_count && attribs)
   22088                 :           8 :     error_at (token->location,
   22089                 :             :               "a nested namespace definition cannot have attributes");
   22090                 :     4872784 :   if (nested_definition_count && topmost_inline_p)
   22091                 :           3 :     error_at (token->location,
   22092                 :             :               "a nested namespace definition cannot be inline");
   22093                 :             : 
   22094                 :             :   /* Start the namespace.  */
   22095                 :     4872784 :   nested_definition_count += push_namespace (identifier, is_inline);
   22096                 :             : 
   22097                 :     4872784 :   bool has_visibility = handle_namespace_attrs (current_namespace, attribs);
   22098                 :             : 
   22099                 :     4872784 :   warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
   22100                 :             : 
   22101                 :             :   /* Look for the `{' to validate starting the namespace.  */
   22102                 :     4872784 :   matching_braces braces;
   22103                 :     4872784 :   if (braces.require_open (parser))
   22104                 :             :     {
   22105                 :             :       /* Parse the body of the namespace.  */
   22106                 :     9745477 :       cp_parser_namespace_body (parser);
   22107                 :             : 
   22108                 :             :       /* Look for the final `}'.  */
   22109                 :     4872734 :       braces.require_close (parser);
   22110                 :             :     }
   22111                 :             : 
   22112                 :     4872775 :   if (has_visibility)
   22113                 :     2453779 :     pop_visibility (1);
   22114                 :             : 
   22115                 :             :   /* Pop the nested namespace definitions.  */
   22116                 :     9814049 :   while (nested_definition_count--)
   22117                 :     4941274 :     pop_namespace ();
   22118                 :     4872775 : }
   22119                 :             : 
   22120                 :             : /* Parse a namespace-body.
   22121                 :             : 
   22122                 :             :    namespace-body:
   22123                 :             :      declaration-seq [opt]  */
   22124                 :             : 
   22125                 :             : static void
   22126                 :     4872743 : cp_parser_namespace_body (cp_parser* parser)
   22127                 :             : {
   22128                 :     4872743 :   cp_parser_declaration_seq_opt (parser);
   22129                 :           0 : }
   22130                 :             : 
   22131                 :             : /* Parse a namespace-alias-definition.
   22132                 :             : 
   22133                 :             :    namespace-alias-definition:
   22134                 :             :      namespace identifier = qualified-namespace-specifier ;  */
   22135                 :             : 
   22136                 :             : static void
   22137                 :       45626 : cp_parser_namespace_alias_definition (cp_parser* parser)
   22138                 :             : {
   22139                 :       45626 :   tree identifier;
   22140                 :       45626 :   tree namespace_specifier;
   22141                 :             : 
   22142                 :       45626 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   22143                 :             : 
   22144                 :             :   /* Look for the `namespace' keyword.  */
   22145                 :       45626 :   cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
   22146                 :             :   /* Look for the identifier.  */
   22147                 :       45626 :   identifier = cp_parser_identifier (parser);
   22148                 :       45626 :   if (identifier == error_mark_node)
   22149                 :             :     return;
   22150                 :             :   /* Look for the `=' token.  */
   22151                 :      136843 :   if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
   22152                 :       45617 :       && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   22153                 :             :     {
   22154                 :           8 :       error_at (token->location, "%<namespace%> definition is not allowed here");
   22155                 :             :       /* Skip the definition.  */
   22156                 :           8 :       cp_lexer_consume_token (parser->lexer);
   22157                 :           8 :       if (cp_parser_skip_to_closing_brace (parser))
   22158                 :           4 :         cp_lexer_consume_token (parser->lexer);
   22159                 :           8 :       return;
   22160                 :             :     }
   22161                 :       45609 :   cp_parser_require (parser, CPP_EQ, RT_EQ);
   22162                 :             :   /* Look for the qualified-namespace-specifier.  */
   22163                 :       45609 :   namespace_specifier
   22164                 :       45609 :     = cp_parser_qualified_namespace_specifier (parser);
   22165                 :       45609 :   cp_warn_deprecated_use_scopes (namespace_specifier);
   22166                 :             :   /* Look for the `;' token.  */
   22167                 :       45609 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   22168                 :             : 
   22169                 :             :   /* Register the alias in the symbol table.  */
   22170                 :       45609 :   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                 :             : 
   22181                 :             : static tree
   22182                 :       45609 : cp_parser_qualified_namespace_specifier (cp_parser* parser)
   22183                 :             : {
   22184                 :             :   /* Look for the optional `::'.  */
   22185                 :       45609 :   cp_parser_global_scope_opt (parser,
   22186                 :             :                               /*current_scope_valid_p=*/false);
   22187                 :             : 
   22188                 :             :   /* Look for the optional nested-name-specifier.  */
   22189                 :       45609 :   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                 :       45609 :   return cp_parser_namespace_name (parser);
   22196                 :             : }
   22197                 :             : 
   22198                 :             : /* Subroutine of cp_parser_using_declaration.  */
   22199                 :             : 
   22200                 :             : static tree
   22201                 :     7290484 : finish_using_decl (tree qscope, tree identifier, bool typename_p = false)
   22202                 :             : {
   22203                 :     7290484 :   tree decl = NULL_TREE;
   22204                 :     7290484 :   if (at_class_scope_p ())
   22205                 :             :     {
   22206                 :             :       /* Create the USING_DECL.  */
   22207                 :     1115098 :       decl = do_class_using_decl (qscope, identifier);
   22208                 :             : 
   22209                 :     1115098 :       if (check_for_bare_parameter_packs (decl))
   22210                 :           3 :         return error_mark_node;
   22211                 :             : 
   22212                 :     1115095 :       if (decl && typename_p)
   22213                 :       18525 :         USING_DECL_TYPENAME_P (decl) = 1;
   22214                 :             : 
   22215                 :             :       /* Add it to the list of members in this class.  */
   22216                 :     1115095 :       finish_member_declaration (decl);
   22217                 :             :     }
   22218                 :             :   else
   22219                 :     6175386 :     finish_nonmember_using_decl (qscope, 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                 :             : 
   22235                 :             : static bool
   22236                 :   115090577 : cp_parser_using_declaration (cp_parser* parser,
   22237                 :             :                              bool access_declaration_p)
   22238                 :             : {
   22239                 :   115090577 :   cp_token *token;
   22240                 :   115090577 :   bool typename_p = false;
   22241                 :   115090577 :   bool global_scope_p;
   22242                 :   115090577 :   tree identifier;
   22243                 :   115090577 :   tree qscope;
   22244                 :   115090577 :   int oldcount = errorcount;
   22245                 :   115090577 :   cp_token *diag_token = NULL;
   22246                 :             : 
   22247                 :   115090577 :   if (access_declaration_p)
   22248                 :             :     {
   22249                 :   108165588 :       diag_token = cp_lexer_peek_token (parser->lexer);
   22250                 :   108165588 :       cp_parser_parse_tentatively (parser);
   22251                 :             :     }
   22252                 :             :   else
   22253                 :             :     {
   22254                 :             :       /* Look for the `using' keyword.  */
   22255                 :     6924989 :       cp_parser_require_keyword (parser, RID_USING, RT_USING);
   22256                 :             : 
   22257                 :     6925004 :  again:
   22258                 :             :       /* Peek at the next token.  */
   22259                 :     6925004 :       token = cp_lexer_peek_token (parser->lexer);
   22260                 :             :       /* See if it's `typename'.  */
   22261                 :     6925004 :       if (token->keyword == RID_TYPENAME)
   22262                 :             :         {
   22263                 :             :           /* Remember that we've seen it.  */
   22264                 :       18533 :           typename_p = true;
   22265                 :             :           /* Consume the `typename' token.  */
   22266                 :       18533 :           cp_lexer_consume_token (parser->lexer);
   22267                 :             :         }
   22268                 :             :     }
   22269                 :             : 
   22270                 :             :   /* Look for the optional global scope qualification.  */
   22271                 :   115090592 :   global_scope_p
   22272                 :   115090592 :     = (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                 :   115090592 :   if (typename_p || !global_scope_p)
   22279                 :             :     {
   22280                 :   109897180 :       qscope = cp_parser_nested_name_specifier (parser, typename_p,
   22281                 :             :                                                 /*check_dependency_p=*/true,
   22282                 :             :                                                 /*type_p=*/false,
   22283                 :             :                                                 /*is_declaration=*/true);
   22284                 :   109897180 :       if (!qscope && !cp_parser_uncommitted_to_tentative_parse_p (parser))
   22285                 :             :         {
   22286                 :         153 :           cp_parser_skip_to_end_of_block_or_statement (parser);
   22287                 :         153 :           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                 :     5193412 :     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                 :   115090439 :   if (!qscope)
   22299                 :   111743470 :     qscope = global_namespace;
   22300                 :             : 
   22301                 :   115090439 :   cp_warn_deprecated_use_scopes (qscope);
   22302                 :             : 
   22303                 :   115090439 :   if (access_declaration_p
   22304                 :   108165588 :       && !MAYBE_CLASS_TYPE_P (qscope)
   22305                 :   223155646 :       && 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                 :   223155646 :     cp_parser_simulate_error (parser);
   22309                 :             : 
   22310                 :   115090439 :   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                 :   108065207 :     return cp_parser_parse_definitely (parser);
   22315                 :             : 
   22316                 :     7025232 :   token = cp_lexer_peek_token (parser->lexer);
   22317                 :             :   /* Parse the unqualified-id.  */
   22318                 :     7025232 :   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                 :     7025232 :   if (access_declaration_p)
   22325                 :             :     {
   22326                 :      100381 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   22327                 :      200610 :         cp_parser_simulate_error (parser);
   22328                 :      100381 :       if (!cp_parser_parse_definitely (parser))
   22329                 :             :         return false;
   22330                 :             :     }
   22331                 :     6924851 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   22332                 :             :     {
   22333                 :        9251 :       cp_token *ell = cp_lexer_consume_token (parser->lexer);
   22334                 :        9251 :       if (cxx_dialect < cxx17)
   22335                 :           4 :         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                 :        9251 :       bool saw_parm_pack = false;
   22345                 :        9251 :       if (uses_parameter_packs (qscope))
   22346                 :             :         {
   22347                 :        9249 :           qscope = make_pack_expansion (qscope);
   22348                 :        9249 :           saw_parm_pack = true;
   22349                 :             :         }
   22350                 :        9251 :       if (identifier_p (identifier)
   22351                 :       18486 :           && IDENTIFIER_CONV_OP_P (identifier)
   22352                 :          12 :           && uses_parameter_packs (TREE_TYPE (identifier)))
   22353                 :             :         {
   22354                 :          10 :           identifier = make_conv_op_name (make_pack_expansion
   22355                 :          10 :                                           (TREE_TYPE (identifier)));
   22356                 :          10 :           saw_parm_pack = true;
   22357                 :             :         }
   22358                 :        9251 :       if (!saw_parm_pack)
   22359                 :             :         {
   22360                 :             :           /* Issue an error in terms using a SCOPE_REF that includes both
   22361                 :             :              components.  */
   22362                 :           0 :           tree name
   22363                 :           0 :             = build_qualified_name (NULL_TREE, qscope, identifier, false);
   22364                 :           0 :           make_pack_expansion (name);
   22365                 :           0 :           gcc_assert (seen_error ());
   22366                 :           0 :           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                 :     6925003 :   if (qscope == error_mark_node || identifier == error_mark_node)
   22373                 :             :     ;
   22374                 :     6924991 :   else if (!identifier_p (identifier)
   22375                 :          19 :            && TREE_CODE (identifier) != BIT_NOT_EXPR)
   22376                 :             :     /* [namespace.udecl]
   22377                 :             : 
   22378                 :             :        A using declaration shall not name a template-id.  */
   22379                 :          16 :     error_at (token->location,
   22380                 :             :               "a template-id may not appear in a using-declaration");
   22381                 :             :   else
   22382                 :             :     {
   22383                 :     6924975 :       tree decl = finish_using_decl (qscope, identifier, typename_p);
   22384                 :             : 
   22385                 :     6924975 :       if (decl == error_mark_node)
   22386                 :             :         {
   22387                 :           3 :           cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   22388                 :           3 :           return false;
   22389                 :             :         }
   22390                 :             :     }
   22391                 :             : 
   22392                 :     6925000 :   if (!access_declaration_p
   22393                 :     6925000 :       && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   22394                 :             :     {
   22395                 :          15 :       cp_token *comma = cp_lexer_consume_token (parser->lexer);
   22396                 :          15 :       if (cxx_dialect < cxx17)
   22397                 :           4 :         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                 :          15 :       goto again;
   22401                 :             :     }
   22402                 :             : 
   22403                 :             :   /* Look for the final `;'.  */
   22404                 :     6924985 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   22405                 :             : 
   22406                 :     6924985 :   if (access_declaration_p && errorcount == oldcount)
   22407                 :         140 :     warning_at (diag_token->location, OPT_Wdeprecated,
   22408                 :             :                 "access declarations are deprecated "
   22409                 :             :                 "in favour 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                 :             : 
   22420                 :             : static void
   22421                 :       13470 : cp_parser_using_enum (cp_parser *parser)
   22422                 :             : {
   22423                 :       13470 :   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                 :       13470 :   gcc_checking_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM));
   22432                 :       13470 :   cp_lexer_consume_token (parser->lexer);
   22433                 :             : 
   22434                 :       13470 :   cp_token *start = cp_lexer_peek_token (parser->lexer);
   22435                 :             : 
   22436                 :       13470 :   tree type = (cp_parser_simple_type_specifier
   22437                 :       13470 :                (parser, NULL, CP_PARSER_FLAGS_TYPENAME_OPTIONAL));
   22438                 :             : 
   22439                 :       13470 :   cp_token *end = cp_lexer_previous_token (parser->lexer);
   22440                 :             : 
   22441                 :       13470 :   if (type == error_mark_node
   22442                 :       13470 :       || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
   22443                 :             :     {
   22444                 :           1 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   22445                 :           1 :       return;
   22446                 :             :     }
   22447                 :       13469 :   if (TREE_CODE (type) == TYPE_DECL)
   22448                 :       13469 :     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                 :       13469 :   const char *msg = nullptr;
   22453                 :       13469 :   if (cxx_dialect < cxx20)
   22454                 :             :     msg = G_("%<using enum%> "
   22455                 :             :              "only available with %<-std=c++20%> or %<-std=gnu++20%>");
   22456                 :       13469 :   else if (dependent_type_p (type))
   22457                 :             :     msg = G_("%<using enum%> of dependent type %qT");
   22458                 :       13468 :   else if (TREE_CODE (type) != ENUMERAL_TYPE)
   22459                 :             :     msg = G_("%<using enum%> of non-enumeration type %q#T");
   22460                 :       13466 :   else if (!COMPLETE_TYPE_P (type))
   22461                 :             :     msg = G_("%<using enum%> of incomplete type %qT");
   22462                 :       13466 :   else if (OPAQUE_ENUM_P (type))
   22463                 :             :     msg = G_("%<using enum%> of %qT before its enum-specifier");
   22464                 :             :   if (msg)
   22465                 :             :     {
   22466                 :           4 :       location_t loc = make_location (start, start, end);
   22467                 :           4 :       auto_diagnostic_group g;
   22468                 :           4 :       error_at (loc, msg, type);
   22469                 :           4 :       loc = location_of (type);
   22470                 :           4 :       if (cxx_dialect < cxx20 || loc == input_location)
   22471                 :             :         ;
   22472                 :           3 :       else if (OPAQUE_ENUM_P (type))
   22473                 :           1 :         inform (loc, "opaque-enum-declaration here");
   22474                 :             :       else
   22475                 :           2 :         inform (loc, "declared here");
   22476                 :           4 :     }
   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                 :       13469 :   if (TREE_CODE (type) == ENUMERAL_TYPE)
   22481                 :      378975 :     for (tree v = TYPE_VALUES (type); v; v = TREE_CHAIN (v))
   22482                 :      365509 :       finish_using_decl (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                 :             : 
   22490                 :             : static tree
   22491                 :    15095580 : cp_parser_alias_declaration (cp_parser* parser)
   22492                 :             : {
   22493                 :    15095580 :   tree id, type, decl, pushed_scope = NULL_TREE, attributes;
   22494                 :    15095580 :   location_t id_location, type_location;
   22495                 :    15095580 :   cp_declarator *declarator;
   22496                 :    15095580 :   cp_decl_specifier_seq decl_specs;
   22497                 :    15095580 :   bool member_p;
   22498                 :    15095580 :   const char *saved_message = NULL;
   22499                 :             : 
   22500                 :             :   /* Look for the `using' keyword.  */
   22501                 :    15095580 :   cp_token *using_token
   22502                 :    15095580 :     = cp_parser_require_keyword (parser, RID_USING, RT_USING);
   22503                 :    15095580 :   if (using_token == NULL)
   22504                 :           0 :     return error_mark_node;
   22505                 :             : 
   22506                 :    15095580 :   id_location = cp_lexer_peek_token (parser->lexer)->location;
   22507                 :    15095580 :   id = cp_parser_identifier (parser);
   22508                 :    15095580 :   if (id == error_mark_node)
   22509                 :             :     return error_mark_node;
   22510                 :             : 
   22511                 :    15077043 :   cp_token *attrs_token = cp_lexer_peek_token (parser->lexer);
   22512                 :    15077043 :   attributes = cp_parser_attributes_opt (parser);
   22513                 :    15077043 :   if (attributes == error_mark_node)
   22514                 :             :     return error_mark_node;
   22515                 :             : 
   22516                 :    15077043 :   cp_parser_require (parser, CPP_EQ, RT_EQ);
   22517                 :             : 
   22518                 :    30154086 :   if (cp_parser_error_occurred (parser))
   22519                 :      832709 :     return error_mark_node;
   22520                 :             : 
   22521                 :    14244334 :   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                 :    14244334 :   if (parser->num_template_parameter_lists)
   22540                 :             :     {
   22541                 :     3415743 :       saved_message = parser->type_definition_forbidden_message;
   22542                 :     3415743 :       parser->type_definition_forbidden_message =
   22543                 :             :         G_("types may not be defined in alias template declarations");
   22544                 :             :     }
   22545                 :             : 
   22546                 :    28488668 :   type = cp_parser_type_id (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
   22547                 :             :                             &type_location);
   22548                 :             : 
   22549                 :             :   /* Restore the error message if need be.  */
   22550                 :    14244334 :   if (parser->num_template_parameter_lists)
   22551                 :     3415743 :     parser->type_definition_forbidden_message = saved_message;
   22552                 :             : 
   22553                 :    14244334 :   if (type == error_mark_node
   22554                 :    14244334 :       || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
   22555                 :             :     {
   22556                 :          84 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   22557                 :          84 :       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                 :    14244250 :   clear_decl_specs (&decl_specs);
   22567                 :    14244250 :   decl_specs.type = type;
   22568                 :    14244250 :   if (attributes != NULL_TREE)
   22569                 :             :     {
   22570                 :       62808 :       decl_specs.attributes = attributes;
   22571                 :       62808 :       set_and_check_decl_spec_loc (&decl_specs,
   22572                 :             :                                    ds_attribute,
   22573                 :             :                                    attrs_token);
   22574                 :             :     }
   22575                 :    14244250 :   set_and_check_decl_spec_loc (&decl_specs,
   22576                 :             :                                ds_typedef,
   22577                 :             :                                using_token);
   22578                 :    14244250 :   set_and_check_decl_spec_loc (&decl_specs,
   22579                 :             :                                ds_alias,
   22580                 :             :                                using_token);
   22581                 :    14244250 :   decl_specs.locations[ds_type_spec] = type_location;
   22582                 :             : 
   22583                 :    14244250 :   if (parser->num_template_parameter_lists
   22584                 :    14244250 :       && !cp_parser_check_template_parameters (parser,
   22585                 :             :                                                /*num_templates=*/0,
   22586                 :             :                                                /*template_id*/false,
   22587                 :             :                                                id_location,
   22588                 :             :                                                /*declarator=*/NULL))
   22589                 :           6 :     return error_mark_node;
   22590                 :             : 
   22591                 :    14244244 :   declarator = make_id_declarator (NULL_TREE, id, sfk_none, id_location);
   22592                 :             : 
   22593                 :    14244244 :   member_p = at_class_scope_p ();
   22594                 :    14244244 :   if (member_p)
   22595                 :     8744162 :     decl = grokfield (declarator, &decl_specs, NULL_TREE, false,
   22596                 :             :                       NULL_TREE, attributes);
   22597                 :             :   else
   22598                 :     5500082 :     decl = start_decl (declarator, &decl_specs, 0,
   22599                 :             :                        attributes, NULL_TREE, &pushed_scope);
   22600                 :    14244244 :   if (decl == error_mark_node)
   22601                 :             :     return decl;
   22602                 :             : 
   22603                 :    14244216 :   cp_finish_decl (decl, NULL_TREE, 0, NULL_TREE, 0);
   22604                 :             : 
   22605                 :    14244216 :   if (pushed_scope)
   22606                 :     2652485 :     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                 :    14244216 :   if (DECL_LANG_SPECIFIC (decl)
   22611                 :    10905702 :       && DECL_TEMPLATE_INFO (decl)
   22612                 :    24049596 :       && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
   22613                 :             :     {
   22614                 :     3415712 :       decl = DECL_TI_TEMPLATE (decl);
   22615                 :     3415712 :       if (member_p)
   22616                 :     1263194 :         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                 :             : 
   22628                 :             : static void
   22629                 :       94664 : cp_parser_using_directive (cp_parser* parser)
   22630                 :             : {
   22631                 :       94664 :   tree namespace_decl;
   22632                 :       94664 :   tree attribs = cp_parser_std_attribute_spec_seq (parser);
   22633                 :       94664 :   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   22634                 :             :     {
   22635                 :             :       /* Error during attribute parsing that resulted in skipping
   22636                 :             :          to next semicolon.  */
   22637                 :           3 :       cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   22638                 :           3 :       return;
   22639                 :             :     }
   22640                 :             : 
   22641                 :             :   /* Look for the `using' keyword.  */
   22642                 :       94661 :   cp_parser_require_keyword (parser, RID_USING, RT_USING);
   22643                 :             :   /* And the `namespace' keyword.  */
   22644                 :       94661 :   cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
   22645                 :             :   /* Look for the optional `::' operator.  */
   22646                 :       94661 :   cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
   22647                 :             :   /* And the optional nested-name-specifier.  */
   22648                 :       94661 :   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                 :       94661 :   namespace_decl = cp_parser_namespace_name (parser);
   22655                 :       94661 :   cp_warn_deprecated_use_scopes (namespace_decl);
   22656                 :             :   /* And any specified GNU attributes.  */
   22657                 :       94661 :   if (cp_next_tokens_can_be_gnu_attribute_p (parser))
   22658                 :           6 :     attribs = chainon (attribs, cp_parser_gnu_attributes_opt (parser));
   22659                 :             : 
   22660                 :             :   /* Update the symbol table.  */
   22661                 :       94661 :   finish_using_directive (namespace_decl, attribs);
   22662                 :             : 
   22663                 :             :   /* Look for the final `;'.  */
   22664                 :       94661 :   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                 :             : 
   22699                 :             : static void
   22700                 :       29781 : cp_parser_asm_definition (cp_parser* parser)
   22701                 :             : {
   22702                 :       29781 :   tree outputs = NULL_TREE;
   22703                 :       29781 :   tree inputs = NULL_TREE;
   22704                 :       29781 :   tree clobbers = NULL_TREE;
   22705                 :       29781 :   tree labels = NULL_TREE;
   22706                 :       29781 :   tree asm_stmt;
   22707                 :       29781 :   bool extended_p = false;
   22708                 :       29781 :   bool invalid_inputs_p = false;
   22709                 :       29781 :   bool invalid_outputs_p = false;
   22710                 :       29781 :   required_token missing = RT_NONE;
   22711                 :       29781 :   tree std_attrs = cp_parser_std_attribute_spec_seq (parser);
   22712                 :       29781 :   location_t asm_loc = cp_lexer_peek_token (parser->lexer)->location;
   22713                 :             : 
   22714                 :             :   /* Look for the `asm' keyword.  */
   22715                 :       29781 :   cp_parser_require_keyword (parser, RID_ASM, RT_ASM);
   22716                 :             : 
   22717                 :             :   /* In C++20, unevaluated inline assembly is permitted in constexpr
   22718                 :             :      functions.  */
   22719                 :       29781 :   if (parser->in_function_body
   22720                 :       16832 :       && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
   22721                 :       29802 :       && cxx_dialect < cxx20)
   22722                 :           4 :     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                 :       29781 :   location_t volatile_loc = UNKNOWN_LOCATION;
   22728                 :       29781 :   location_t inline_loc = UNKNOWN_LOCATION;
   22729                 :       29781 :   location_t goto_loc = UNKNOWN_LOCATION;
   22730                 :       29781 :   location_t first_loc = UNKNOWN_LOCATION;
   22731                 :             : 
   22732                 :       29781 :   if (cp_parser_allow_gnu_extensions_p (parser))
   22733                 :       43444 :     for (;;)
   22734                 :             :       {
   22735                 :       43444 :         cp_token *token = cp_lexer_peek_token (parser->lexer);
   22736                 :       43444 :         location_t loc = token->location;
   22737                 :       43444 :         switch (cp_lexer_peek_token (parser->lexer)->keyword)
   22738                 :             :           {
   22739                 :       13502 :           case RID_VOLATILE:
   22740                 :       13502 :             if (volatile_loc)
   22741                 :             :               {
   22742                 :           6 :                 error_at (loc, "duplicate %<asm%> qualifier %qT",
   22743                 :             :                           token->u.value);
   22744                 :           6 :                 inform (volatile_loc, "first seen here");
   22745                 :             :               }
   22746                 :             :             else
   22747                 :             :               {
   22748                 :       13496 :                 if (!parser->in_function_body)
   22749                 :           1 :                   warning_at (loc, 0, "%<asm%> qualifier %qT ignored "
   22750                 :             :                               "outside of function body", token->u.value);
   22751                 :             :                 volatile_loc = loc;
   22752                 :             :               }
   22753                 :       13502 :             cp_lexer_consume_token (parser->lexer);
   22754                 :       13502 :             continue;
   22755                 :             : 
   22756                 :          39 :           case RID_INLINE:
   22757                 :          39 :             if (inline_loc)
   22758                 :             :               {
   22759                 :           6 :                 error_at (loc, "duplicate %<asm%> qualifier %qT",
   22760                 :             :                           token->u.value);
   22761                 :           6 :                 inform (inline_loc, "first seen here");
   22762                 :             :               }
   22763                 :             :             else
   22764                 :             :               inline_loc = loc;
   22765                 :          39 :             if (!first_loc)
   22766                 :          26 :               first_loc = loc;
   22767                 :          39 :             cp_lexer_consume_token (parser->lexer);
   22768                 :          39 :             continue;
   22769                 :             : 
   22770                 :         119 :           case RID_GOTO:
   22771                 :         119 :             if (goto_loc)
   22772                 :             :               {
   22773                 :           6 :                 error_at (loc, "duplicate %<asm%> qualifier %qT",
   22774                 :             :                           token->u.value);
   22775                 :           6 :                 inform (goto_loc, "first seen here");
   22776                 :             :               }
   22777                 :             :             else
   22778                 :             :               goto_loc = loc;
   22779                 :         119 :             if (!first_loc)
   22780                 :         101 :               first_loc = loc;
   22781                 :         119 :             cp_lexer_consume_token (parser->lexer);
   22782                 :         119 :             continue;
   22783                 :             : 
   22784                 :           3 :           case RID_CONST:
   22785                 :           3 :           case RID_RESTRICT:
   22786                 :           3 :             error_at (loc, "%qT is not an %<asm%> qualifier", token->u.value);
   22787                 :           3 :             cp_lexer_consume_token (parser->lexer);
   22788                 :           3 :             continue;
   22789                 :             : 
   22790                 :             :           default:
   22791                 :             :             break;
   22792                 :             :           }
   22793                 :             :         break;
   22794                 :             :       }
   22795                 :             : 
   22796                 :       29781 :   bool volatile_p = (volatile_loc != UNKNOWN_LOCATION);
   22797                 :       29781 :   bool inline_p = (inline_loc != UNKNOWN_LOCATION);
   22798                 :       29781 :   bool goto_p = (goto_loc != UNKNOWN_LOCATION);
   22799                 :             : 
   22800                 :       29781 :   if (!parser->in_function_body && (inline_p || goto_p))
   22801                 :             :     {
   22802                 :           2 :       error_at (first_loc, "%<asm%> qualifier outside of function body");
   22803                 :           2 :       inline_p = goto_p = false;
   22804                 :             :     }
   22805                 :             : 
   22806                 :             :   /* Look for the opening `('.  */
   22807                 :       29781 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   22808                 :             :     return;
   22809                 :             :   /* Look for the string.  */
   22810                 :       29780 :   tree string = cp_parser_string_literal (parser, /*translate=*/false,
   22811                 :             :                                           /*wide_ok=*/false);
   22812                 :       29780 :   if (string == error_mark_node)
   22813                 :             :     {
   22814                 :          47 :       cp_parser_skip_to_closing_parenthesis (parser, true, false,
   22815                 :             :                                              /*consume_paren=*/true);
   22816                 :          47 :       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                 :       29733 :   if (cp_parser_allow_gnu_extensions_p (parser)
   22825                 :       29733 :       && parser->in_function_body
   22826                 :       16785 :       && (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
   22827                 :        5828 :           || cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)))
   22828                 :             :     {
   22829                 :       16117 :       bool inputs_p = false;
   22830                 :       16117 :       bool clobbers_p = false;
   22831                 :       16117 :       bool labels_p = false;
   22832                 :             : 
   22833                 :             :       /* The extended syntax was used.  */
   22834                 :       16117 :       extended_p = true;
   22835                 :             : 
   22836                 :             :       /* Look for outputs.  */
   22837                 :       16117 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   22838                 :             :         {
   22839                 :             :           /* Consume the `:'.  */
   22840                 :       10957 :           cp_lexer_consume_token (parser->lexer);
   22841                 :             :           /* Parse the output-operands.  */
   22842                 :       10957 :           if (cp_lexer_next_token_is_not (parser->lexer,
   22843                 :             :                                           CPP_COLON)
   22844                 :             :               && cp_lexer_next_token_is_not (parser->lexer,
   22845                 :             :                                              CPP_SCOPE)
   22846                 :             :               && cp_lexer_next_token_is_not (parser->lexer,
   22847                 :             :                                              CPP_CLOSE_PAREN))
   22848                 :             :             {
   22849                 :        9288 :               outputs = cp_parser_asm_operand_list (parser);
   22850                 :        9288 :               if (outputs == error_mark_node)
   22851                 :           8 :                 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 (parser->lexer, CPP_SCOPE))
   22857                 :             :         /* The inputs are coming next.  */
   22858                 :             :         inputs_p = true;
   22859                 :             : 
   22860                 :             :       /* Look for inputs.  */
   22861                 :       16117 :       if (inputs_p
   22862                 :       16117 :           || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   22863                 :             :         {
   22864                 :             :           /* Consume the `:' or `::'.  */
   22865                 :       12793 :           cp_lexer_consume_token (parser->lexer);
   22866                 :             :           /* Parse the output-operands.  */
   22867                 :       12793 :           if (cp_lexer_next_token_is_not (parser->lexer,
   22868                 :             :                                           CPP_COLON)
   22869                 :             :               && cp_lexer_next_token_is_not (parser->lexer,
   22870                 :             :                                              CPP_SCOPE)
   22871                 :             :               && cp_lexer_next_token_is_not (parser->lexer,
   22872                 :             :                                              CPP_CLOSE_PAREN))
   22873                 :             :             {
   22874                 :        7393 :               inputs = cp_parser_asm_operand_list (parser);
   22875                 :        7393 :               if (inputs == error_mark_node)
   22876                 :           4 :                 invalid_inputs_p = true;
   22877                 :             :             }
   22878                 :             :         }
   22879                 :        3324 :       else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
   22880                 :             :         /* The clobbers are coming next.  */
   22881                 :          16 :         clobbers_p = true;
   22882                 :             : 
   22883                 :             :       /* Look for clobbers.  */
   22884                 :       16117 :       if (clobbers_p
   22885                 :       16117 :           || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   22886                 :             :         {
   22887                 :        9728 :           clobbers_p = true;
   22888                 :             :           /* Consume the `:' or `::'.  */
   22889                 :        9728 :           cp_lexer_consume_token (parser->lexer);
   22890                 :             :           /* Parse the clobbers.  */
   22891                 :        9728 :           if (cp_lexer_next_token_is_not (parser->lexer,
   22892                 :             :                                           CPP_COLON)
   22893                 :        9728 :               && cp_lexer_next_token_is_not (parser->lexer,
   22894                 :             :                                              CPP_CLOSE_PAREN))
   22895                 :        9616 :             clobbers = cp_parser_asm_clobber_list (parser);
   22896                 :             :         }
   22897                 :        6389 :       else if (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
   22898                 :             :         /* The labels are coming next.  */
   22899                 :             :         labels_p = true;
   22900                 :             : 
   22901                 :             :       /* Look for labels.  */
   22902                 :       16117 :       if (labels_p
   22903                 :       16117 :           || (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_COLON)))
   22904                 :             :         {
   22905                 :          84 :           labels_p = true;
   22906                 :             :           /* Consume the `:' or `::'.  */
   22907                 :          84 :           cp_lexer_consume_token (parser->lexer);
   22908                 :             :           /* Parse the labels.  */
   22909                 :          84 :           labels = cp_parser_asm_label_list (parser);
   22910                 :             :         }
   22911                 :             : 
   22912                 :       16117 :       if (goto_p && !labels_p)
   22913                 :          24 :         missing = clobbers_p ? RT_COLON : RT_COLON_SCOPE;
   22914                 :             :     }
   22915                 :       13616 :   else if (goto_p)
   22916                 :           4 :     missing = RT_COLON_SCOPE;
   22917                 :             : 
   22918                 :             :   /* Look for the closing `)'.  */
   22919                 :       29761 :   if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN,
   22920                 :             :                           missing ? missing : RT_CLOSE_PAREN))
   22921                 :          44 :     cp_parser_skip_to_closing_parenthesis (parser, true, false,
   22922                 :             :                                            /*consume_paren=*/true);
   22923                 :       29733 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   22924                 :             : 
   22925                 :       29733 :   if (!invalid_inputs_p && !invalid_outputs_p)
   22926                 :             :     {
   22927                 :             :       /* Create the ASM_EXPR.  */
   22928                 :       29721 :       if (parser->in_function_body)
   22929                 :             :         {
   22930                 :       16773 :           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                 :       16773 :           if (!extended_p)
   22934                 :             :             {
   22935                 :         668 :               tree temp = asm_stmt;
   22936                 :         668 :               if (TREE_CODE (temp) == CLEANUP_POINT_EXPR)
   22937                 :         640 :                 temp = TREE_OPERAND (temp, 0);
   22938                 :             : 
   22939                 :         668 :               ASM_INPUT_P (temp) = 1;
   22940                 :             :             }
   22941                 :             :         }
   22942                 :             :       else
   22943                 :       12948 :         symtab->finalize_toplevel_asm (string);
   22944                 :             :     }
   22945                 :             : 
   22946                 :       29733 :   if (std_attrs && any_nonignored_attribute_p (std_attrs))
   22947                 :          27 :     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                 :             : 
   22954                 :             : static tree
   22955                 :     5576699 : strip_declarator_types (tree type, cp_declarator *declarator)
   22956                 :             : {
   22957                 :     6237319 :   for (cp_declarator *d = declarator; d;)
   22958                 :     6237319 :     switch (d->kind)
   22959                 :             :       {
   22960                 :             :       case cdk_id:
   22961                 :             :       case cdk_decomp:
   22962                 :             :       case cdk_error:
   22963                 :             :         d = NULL;
   22964                 :             :         break;
   22965                 :             : 
   22966                 :      660620 :       default:
   22967                 :      660620 :         if (TYPE_PTRMEMFUNC_P (type))
   22968                 :           9 :           type = TYPE_PTRMEMFUNC_FN_TYPE (type);
   22969                 :      660620 :         type = TREE_TYPE (type);
   22970                 :      660620 :         d = d->declarator;
   22971                 :      660620 :         break;
   22972                 :             :       }
   22973                 :             : 
   22974                 :     5576699 :   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                 :             : 
   22982                 :             : static void
   22983                 :    70627010 : warn_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                 :    70627010 :   if (!at_function_scope_p ())
   22988                 :    70626885 :     return;
   22989                 :             : 
   22990                 :             :   /* And only if there is no storage class specified.  */
   22991                 :       30058 :   if (decl_specifiers->storage_class != sc_none
   22992                 :       30058 :       || decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
   22993                 :       11826 :     return;
   22994                 :             : 
   22995                 :       18232 :   if (declarator->kind != cdk_function
   22996                 :       18228 :       || !declarator->declarator
   22997                 :       18228 :       || declarator->declarator->kind != cdk_id
   22998                 :    70663341 :       || !identifier_p (get_unqualified_id
   22999                 :             :                         (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                 :       18228 :   if (declarator->parenthesized != UNKNOWN_LOCATION)
   23006                 :             :     return;
   23007                 :             : 
   23008                 :       18162 :   tree type;
   23009                 :       18162 :   if (decl_specifiers->type)
   23010                 :             :     {
   23011                 :       18142 :       type = decl_specifiers->type;
   23012                 :       18142 :       if (TREE_CODE (type) == TYPE_DECL)
   23013                 :         232 :         type = TREE_TYPE (type);
   23014                 :             : 
   23015                 :             :       /* If the return type is void there is no ambiguity.  */
   23016                 :       18142 :       if (same_type_p (type, void_type_node))
   23017                 :             :         return;
   23018                 :             :     }
   23019                 :          20 :   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                 :          16 :     type = integer_type_node;
   23023                 :             :   else
   23024                 :             :     return;
   23025                 :             : 
   23026                 :         445 :   auto_diagnostic_group d;
   23027                 :         445 :   location_t loc = declarator->u.function.parens_loc;
   23028                 :         445 :   tree params = declarator->u.function.parameters;
   23029                 :         445 :   const bool has_list_ctor_p = CLASS_TYPE_P (type) && TYPE_HAS_LIST_CTOR (type);
   23030                 :             : 
   23031                 :             :   /* The T t() case.  */
   23032                 :         445 :   if (params == void_list_node)
   23033                 :             :     {
   23034                 :         117 :       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                 :         117 :           if (!CLASS_TYPE_P (type) || TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
   23043                 :             :             {
   23044                 :          93 :               gcc_rich_location iloc (loc);
   23045                 :          93 :               iloc.add_fixit_remove ();
   23046                 :          93 :               inform (&iloc, "remove parentheses to default-initialize "
   23047                 :             :                       "a variable");
   23048                 :          93 :               if (cxx_dialect >= cxx11 && !has_list_ctor_p)
   23049                 :             :                 {
   23050                 :          69 :                   if (CP_AGGREGATE_TYPE_P (type))
   23051                 :          18 :                     inform (loc, "or replace parentheses with braces to "
   23052                 :             :                             "aggregate-initialize a variable");
   23053                 :             :                   else
   23054                 :          51 :                     inform (loc, "or replace parentheses with braces to "
   23055                 :             :                             "value-initialize a variable");
   23056                 :             :                 }
   23057                 :          93 :             }
   23058                 :             :         }
   23059                 :         117 :       return;
   23060                 :             :     }
   23061                 :             : 
   23062                 :             :   /* If we had (...) or the parameter-list wasn't parenthesized,
   23063                 :             :      we're done.  */
   23064                 :         648 :   if (params == NULL_TREE || !PARENTHESIZED_LIST_P (params))
   23065                 :             :     return;
   23066                 :             : 
   23067                 :             :   /* The T t(X()) case.  */
   23068                 :         125 :   if (list_length (params) == 2)
   23069                 :             :     {
   23070                 :          87 :       if (warning_at (loc, OPT_Wvexing_parse,
   23071                 :             :                       "parentheses were disambiguated as a function "
   23072                 :             :                       "declaration"))
   23073                 :             :         {
   23074                 :          85 :           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                 :          85 :           if (cxx_dialect >= cxx11 && !has_list_ctor_p)
   23080                 :             :             {
   23081                 :          63 :               iloc.add_fixit_replace (get_start (loc), "{");
   23082                 :          63 :               iloc.add_fixit_replace (get_finish (loc), "}");
   23083                 :          63 :               inform (&iloc, "replace parentheses with braces to declare a "
   23084                 :             :                       "variable");
   23085                 :             :             }
   23086                 :             :           else
   23087                 :             :             {
   23088                 :          22 :               iloc.add_fixit_insert_after (get_start (loc), "(");
   23089                 :          22 :               iloc.add_fixit_insert_before (get_finish (loc), ")");
   23090                 :          22 :               inform (&iloc, "add parentheses to declare a variable");
   23091                 :             :             }
   23092                 :          85 :         }
   23093                 :             :     }
   23094                 :             :   /* The T t(X(), X()) case.  */
   23095                 :          38 :   else if (warning_at (loc, OPT_Wvexing_parse,
   23096                 :             :                        "parentheses were disambiguated as a function "
   23097                 :             :                        "declaration"))
   23098                 :             :     {
   23099                 :          36 :       gcc_rich_location iloc (loc);
   23100                 :          36 :       if (cxx_dialect >= cxx11 && !has_list_ctor_p)
   23101                 :             :         {
   23102                 :          30 :           iloc.add_fixit_replace (get_start (loc), "{");
   23103                 :          30 :           iloc.add_fixit_replace (get_finish (loc), "}");
   23104                 :          30 :           inform (&iloc, "replace parentheses with braces to declare a "
   23105                 :             :                   "variable");
   23106                 :             :         }
   23107                 :          36 :     }
   23108                 :         445 : }
   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                 :             : 
   23114                 :             : static void
   23115                 :   192427833 : cp_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                 :   192427833 :   if (cxx_dialect >= cxx17
   23121                 :   187699451 :       && *ctor_dtor_or_conv_p <= 0
   23122                 :   164598082 :       && !decl_specs->type
   23123                 :     2452432 :       && !decl_specs->any_type_specifiers_p
   23124                 :   193239437 :       && function_declarator_p (declarator))
   23125                 :             :     {
   23126                 :      811596 :       cp_declarator *id = get_id_declarator (declarator);
   23127                 :      811596 :       tree name = id->u.id.unqualified_name;
   23128                 :      811596 :       parser->scope = id->u.id.qualifying_scope;
   23129                 :      811596 :       tree tmpl = cp_parser_lookup_name_simple (parser, name, id->id_loc);
   23130                 :      811596 :       if (tmpl
   23131                 :      811596 :           && (DECL_CLASS_TEMPLATE_P (tmpl)
   23132                 :         223 :               || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)))
   23133                 :             :         {
   23134                 :      811375 :           id->u.id.unqualified_name = dguide_name (tmpl);
   23135                 :      811375 :           id->u.id.sfk = sfk_deduction_guide;
   23136                 :      811375 :           *ctor_dtor_or_conv_p = 1;
   23137                 :             :         }
   23138                 :             :     }
   23139                 :   192427833 : }
   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                 :             : 
   23199                 :             : static tree
   23200                 :   150179644 : cp_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                 :   150179644 :   cp_token *token = NULL, *asm_spec_start_token = NULL,
   23213                 :   150179644 :            *attributes_start_token = NULL;
   23214                 :   150179644 :   cp_declarator *declarator;
   23215                 :   150179644 :   tree prefix_attributes;
   23216                 :   150179644 :   tree attributes = NULL;
   23217                 :   150179644 :   tree asm_specification;
   23218                 :   150179644 :   tree initializer;
   23219                 :   150179644 :   tree decl = NULL_TREE;
   23220                 :   150179644 :   tree scope;
   23221                 :   150179644 :   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                 :   150179644 :   enum cpp_ttype initialization_kind;
   23226                 :   150179644 :   bool is_direct_init = false;
   23227                 :   150179644 :   bool is_non_constant_init;
   23228                 :   150179644 :   int ctor_dtor_or_conv_p;
   23229                 :   300359288 :   bool friend_p = cp_parser_friend_p (decl_specifiers);
   23230                 :   150179644 :   bool static_p = decl_specifiers->storage_class == sc_static;
   23231                 :   150179644 :   tree pushed_scope = NULL_TREE;
   23232                 :   150179644 :   bool range_for_decl_p = false;
   23233                 :   150179644 :   bool saved_default_arg_ok_p = parser->default_arg_ok_p;
   23234                 :   150179644 :   location_t tmp_init_loc = UNKNOWN_LOCATION;
   23235                 :             : 
   23236                 :   150179644 :   if (decl_spec_seq_has_spec_p (decl_specifiers, ds_consteval))
   23237                 :       54427 :     flags |= CP_PARSER_FLAGS_CONSTEVAL;
   23238                 :             : 
   23239                 :             :   /* Assume that this is not the declarator for a function
   23240                 :             :      definition.  */
   23241                 :   150179644 :   if (function_definition_p)
   23242                 :   150179644 :     *function_definition_p = false;
   23243                 :             : 
   23244                 :             :   /* Default arguments are only permitted for function parameters.  */
   23245                 :   150179644 :   if (decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
   23246                 :    12511588 :     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                 :   150179644 :   resume_deferring_access_checks ();
   23252                 :             : 
   23253                 :   150179644 :   token = cp_lexer_peek_token (parser->lexer);
   23254                 :             : 
   23255                 :             :   /* Parse the declarator.  */
   23256                 :   150179644 :   declarator
   23257                 :   150179644 :     = 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                 :   150179644 :   stop_deferring_access_checks ();
   23263                 :             : 
   23264                 :   150179644 :   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                 :   150179644 :   if (declarator == cp_error_declarator)
   23269                 :      256482 :     return error_mark_node;
   23270                 :             : 
   23271                 :             :   /* Check that the number of template-parameter-lists is OK.  */
   23272                 :   149923162 :   if (!cp_parser_check_declarator_template_parameters (parser, declarator,
   23273                 :             :                                                        token->location))
   23274                 :          58 :     return error_mark_node;
   23275                 :             : 
   23276                 :   149923104 :   if (declares_class_or_enum & 2)
   23277                 :      534367 :     cp_parser_check_for_definition_in_return_type (declarator,
   23278                 :             :                                                    decl_specifiers->type,
   23279                 :             :                                                    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                 :   149923104 :   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                 :   149923104 :   decl_specifiers->type
   23289                 :   149923104 :     = maybe_update_decl_type (decl_specifiers->type, scope);
   23290                 :             : 
   23291                 :             :   /* If we're allowing GNU extensions, look for an
   23292                 :             :      asm-specification.  */
   23293                 :   149923104 :   if (cp_parser_allow_gnu_extensions_p (parser))
   23294                 :             :     {
   23295                 :             :       /* Look for an asm-specification.  */
   23296                 :   149923104 :       asm_spec_start_token = cp_lexer_peek_token (parser->lexer);
   23297                 :   149923104 :       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                 :   149923104 :   prefix_attributes = decl_specifiers->attributes;
   23305                 :             : 
   23306                 :             :   /* Look for attributes.  */
   23307                 :   149923104 :   attributes_start_token = cp_lexer_peek_token (parser->lexer);
   23308                 :   149923104 :   attributes = cp_parser_attributes_opt (parser);
   23309                 :             : 
   23310                 :             :   /* Peek at the next token.  */
   23311                 :   149923104 :   token = cp_lexer_peek_token (parser->lexer);
   23312                 :             : 
   23313                 :   149923104 :   bool bogus_implicit_tmpl = false;
   23314                 :             : 
   23315                 :   149923104 :   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                 :    87209097 :       cp_parser_maybe_adjust_declarator_for_dguide (parser,
   23321                 :             :                                                     decl_specifiers,
   23322                 :             :                                                     declarator,
   23323                 :             :                                                     &ctor_dtor_or_conv_p);
   23324                 :             : 
   23325                 :    87209097 :       if (!member_p && !cp_parser_error_occurred (parser))
   23326                 :    70627010 :         warn_about_ambiguous_parse (decl_specifiers, declarator);
   23327                 :             : 
   23328                 :             :       /* Check to see if the token indicates the start of a
   23329                 :             :          function-definition.  */
   23330                 :    87209097 :       if (cp_parser_token_starts_function_definition_p (token))
   23331                 :             :         {
   23332                 :    49384645 :           if (!function_definition_allowed_p)
   23333                 :             :             {
   23334                 :             :               /* If a function-definition should not appear here, issue an
   23335                 :             :                  error message.  */
   23336                 :          14 :               cp_parser_error (parser,
   23337                 :             :                                "a function-definition is not allowed here");
   23338                 :          14 :               return error_mark_node;
   23339                 :             :             }
   23340                 :             : 
   23341                 :    49384631 :           location_t func_brace_location
   23342                 :    49384631 :             = cp_lexer_peek_token (parser->lexer)->location;
   23343                 :             : 
   23344                 :             :           /* Neither attributes nor an asm-specification are allowed
   23345                 :             :              on a function-definition.  */
   23346                 :    49384631 :           if (asm_specification)
   23347                 :           0 :             error_at (asm_spec_start_token->location,
   23348                 :             :                       "an %<asm%> specification is not allowed "
   23349                 :             :                       "on a function-definition");
   23350                 :    49384631 :           if (attributes)
   23351                 :           0 :             error_at (attributes_start_token->location,
   23352                 :             :                       "attributes are not allowed "
   23353                 :             :                       "on a function-definition");
   23354                 :             :           /* This is a function-definition.  */
   23355                 :    49384631 :           *function_definition_p = true;
   23356                 :             : 
   23357                 :             :           /* Parse the function definition.  */
   23358                 :    49384631 :           if (member_p)
   23359                 :    12995002 :             decl = cp_parser_save_member_function_body (parser,
   23360                 :             :                                                         decl_specifiers,
   23361                 :             :                                                         declarator,
   23362                 :             :                                                         prefix_attributes);
   23363                 :             :           else
   23364                 :    36389629 :             decl =
   23365                 :             :               (cp_parser_function_definition_from_specifiers_and_declarator
   23366                 :    36389629 :                (parser, decl_specifiers, prefix_attributes, declarator));
   23367                 :             : 
   23368                 :    98768845 :           if (decl != error_mark_node && DECL_STRUCT_FUNCTION (decl))
   23369                 :             :             {
   23370                 :             :               /* This is where the prologue starts...  */
   23371                 :    36389248 :               DECL_STRUCT_FUNCTION (decl)->function_start_locus
   23372                 :    36389248 :                 = func_brace_location;
   23373                 :             :             }
   23374                 :             : 
   23375                 :    49384606 :           return decl;
   23376                 :             :         }
   23377                 :             :     }
   23378                 :    62714007 :   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                 :           0 :       bogus_implicit_tmpl = true;
   23389                 :           0 :       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                 :   100538459 :   if (!decl_specifiers->any_specifiers_p && ctor_dtor_or_conv_p <= 0)
   23401                 :             :     {
   23402                 :          47 :       cp_parser_error (parser,
   23403                 :             :                        "expected constructor, destructor, or type conversion");
   23404                 :          47 :       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                 :   100538412 :   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                 :    44659397 :       if (token->type == CPP_OPEN_PAREN
   23417                 :    44659397 :           && cp_parser_uncommitted_to_tentative_parse_p (parser))
   23418                 :             :         {
   23419                 :          25 :           cp_lexer_save_tokens (parser->lexer);
   23420                 :          25 :           cp_lexer_consume_token (parser->lexer);
   23421                 :          25 :           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                 :          25 :           bool ok = (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
   23429                 :          25 :                      || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
   23430                 :          25 :           cp_lexer_rollback_tokens (parser->lexer);
   23431                 :          25 :           if (UNLIKELY (!ok))
   23432                 :             :             /* Not an init-declarator.  */
   23433                 :          16 :             return error_mark_node;
   23434                 :             :         }
   23435                 :    44659381 :       is_initialized = SD_INITIALIZED;
   23436                 :    44659381 :       initialization_kind = token->type;
   23437                 :    44659381 :       declarator->init_loc = token->location;
   23438                 :    44659381 :       if (maybe_range_for_decl)
   23439                 :     3426102 :         *maybe_range_for_decl = error_mark_node;
   23440                 :    44659381 :       tmp_init_loc = token->location;
   23441                 :    44659381 :       if (init_loc && *init_loc == UNKNOWN_LOCATION)
   23442                 :    41606645 :         *init_loc = tmp_init_loc;
   23443                 :             : 
   23444                 :    44659381 :       if (token->type == CPP_EQ
   23445                 :    44659381 :           && function_declarator_p (declarator))
   23446                 :             :         {
   23447                 :      547507 :           cp_token *t2 = cp_lexer_peek_nth_token (parser->lexer, 2);
   23448                 :      547507 :           if (t2->keyword == RID_DEFAULT)
   23449                 :             :             is_initialized = SD_DEFAULTED;
   23450                 :      525872 :           else if (t2->keyword == RID_DELETE)
   23451                 :   100470286 :             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                 :      257183 :           if (maybe_range_for_decl && *maybe_range_for_decl != error_mark_node)
   23462                 :             :             range_for_decl_p = true;
   23463                 :             :           else
   23464                 :             :             {
   23465                 :       68104 :               if (!maybe_range_for_decl)
   23466                 :       68104 :                 cp_parser_error (parser, "expected initializer");
   23467                 :       68110 :               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                 :   100470286 :   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                 :   100470286 :   if (!member_p)
   23483                 :             :     {
   23484                 :    96792077 :       if (parser->in_unbraced_linkage_specification_p)
   23485                 :      309408 :         decl_specifiers->storage_class = sc_extern;
   23486                 :   193395081 :       decl = start_decl (declarator, decl_specifiers,
   23487                 :             :                          range_for_decl_p? SD_INITIALIZED : is_initialized,
   23488                 :             :                          attributes, prefix_attributes, &pushed_scope);
   23489                 :    96792073 :       cp_finalize_omp_declare_simd (parser, decl);
   23490                 :    96792073 :       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                 :    96792073 :       if (DECL_P (decl)
   23495                 :    96789058 :           && declarator->id_loc != UNKNOWN_LOCATION
   23496                 :   193576353 :           && DECL_SOURCE_LOCATION (decl) == input_location)
   23497                 :    56747234 :         DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
   23498                 :             :     }
   23499                 :     3678209 :   else if (scope)
   23500                 :             :     /* Enter the SCOPE.  That way unqualified names appearing in the
   23501                 :             :        initializer will be looked up in SCOPE.  */
   23502                 :       44729 :     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                 :   100470282 :   if (!member_p && decl)
   23507                 :             :     {
   23508                 :    96792073 :       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                 :    96792073 :       if (TREE_CODE (decl) == FUNCTION_DECL)
   23514                 :             :         {
   23515                 :    34200336 :           saved_current_function_decl = current_function_decl;
   23516                 :    34200336 :           current_function_decl = decl;
   23517                 :             :         }
   23518                 :             : 
   23519                 :             :       /* Perform access checks for template parameters.  */
   23520                 :    96792073 :       cp_parser_perform_template_parameter_access_checks (checks);
   23521                 :             : 
   23522                 :             :       /* Perform the access control checks for the declarator and the
   23523                 :             :          decl-specifiers.  */
   23524                 :    96792073 :       perform_deferred_access_checks (tf_warning_or_error);
   23525                 :             : 
   23526                 :             :       /* Restore the saved value.  */
   23527                 :    96792073 :       if (TREE_CODE (decl) == FUNCTION_DECL)
   23528                 :    34200336 :         current_function_decl = saved_current_function_decl;
   23529                 :             :     }
   23530                 :             : 
   23531                 :             :   /* Parse the initializer.  */
   23532                 :   100470282 :   initializer = NULL_TREE;
   23533                 :   100470282 :   is_direct_init = false;
   23534                 :   100470282 :   is_non_constant_init = true;
   23535                 :   100470282 :   if (is_initialized)
   23536                 :             :     {
   23537                 :    44659381 :       if (function_declarator_p (declarator))
   23538                 :             :         {
   23539                 :      547515 :            if (initialization_kind == CPP_EQ)
   23540                 :      547507 :              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                 :           8 :                if (decl != error_mark_node)
   23547                 :           8 :                  error_at (tmp_init_loc, "initializer provided for function");
   23548                 :           8 :                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                 :    44111866 :           bool has_lambda_scope = false;
   23563                 :             : 
   23564                 :    44111866 :           if (decl != error_mark_node
   23565                 :    44111614 :               && !member_p
   23566                 :    88132420 :               && (processing_template_decl || DECL_NAMESPACE_SCOPE_P (decl)))
   23567                 :    41992494 :             has_lambda_scope = true;
   23568                 :             : 
   23569                 :    41992494 :           if (has_lambda_scope)
   23570                 :    41992494 :             start_lambda_scope (decl);
   23571                 :    44111866 :           initializer = cp_parser_initializer (parser,
   23572                 :             :                                                &is_direct_init,
   23573                 :             :                                                &is_non_constant_init);
   23574                 :    44111863 :           if (has_lambda_scope)
   23575                 :    41992491 :             finish_lambda_scope ();
   23576                 :    44111863 :           if (initializer == error_mark_node)
   23577                 :        1669 :             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                 :   100470279 :   if (cp_parser_allow_gnu_extensions_p (parser)
   23586                 :   100470279 :       && initialization_kind == CPP_OPEN_PAREN
   23587                 :     4423456 :       && cp_parser_attributes_opt (parser)
   23588                 :           4 :       && permerror (input_location,
   23589                 :             :                     "attributes after parenthesized initializer ignored"))
   23590                 :             :     {
   23591                 :           4 :       static bool hint;
   23592                 :           4 :       if (flag_permissive && !hint)
   23593                 :             :         {
   23594                 :           4 :           hint = true;
   23595                 :           4 :           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                 :   100470279 :   if (bogus_implicit_tmpl && decl != error_mark_node)
   23602                 :           0 :     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                 :   100470279 :   if (member_p)
   23608                 :             :     {
   23609                 :     3678209 :       if (pushed_scope)
   23610                 :             :         {
   23611                 :       44725 :           pop_scope (pushed_scope);
   23612                 :       44725 :           pushed_scope = NULL_TREE;
   23613                 :             :         }
   23614                 :     3678209 :       decl = grokfield (declarator, decl_specifiers,
   23615                 :     3678209 :                         initializer, !is_non_constant_init,
   23616                 :             :                         /*asmspec=*/NULL_TREE,
   23617                 :             :                         attr_chainon (attributes, prefix_attributes));
   23618                 :     3678209 :       if (decl && TREE_CODE (decl) == FUNCTION_DECL)
   23619                 :     3586974 :         cp_parser_save_default_args (parser, decl);
   23620                 :     3678209 :       cp_finalize_omp_declare_simd (parser, decl);
   23621                 :     3678209 :       cp_finalize_oacc_routine (parser, decl, false);
   23622                 :             :     }
   23623                 :             : 
   23624                 :             :   /* Finish processing the declaration.  But, skip member
   23625                 :             :      declarations.  */
   23626                 :   100470279 :   if (!member_p && decl && decl != error_mark_node && !range_for_decl_p)
   23627                 :             :     {
   23628                 :    96599982 :       cp_finish_decl (decl,
   23629                 :    96599982 :                       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                 :    91223749 :                       ((is_direct_init || !is_initialized)
   23636                 :             :                        ? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
   23637                 :             :     }
   23638                 :     3870297 :   else if ((cxx_dialect != cxx98) && friend_p
   23639                 :     3859714 :            && 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                 :      961490 :     check_default_tmpl_args (decl, current_template_parms, /*is_primary=*/true,
   23644                 :             :                              /*is_partial=*/false, /*is_friend_decl=*/1);
   23645                 :             : 
   23646                 :   100470279 :   if (!friend_p && pushed_scope)
   23647                 :    13263601 :     pop_scope (pushed_scope);
   23648                 :             : 
   23649                 :   100470279 :   if (function_declarator_p (declarator)
   23650                 :   100470279 :       && parser->fully_implicit_function_template_p)
   23651                 :             :     {
   23652                 :          65 :       if (member_p)
   23653                 :           0 :         decl = finish_fully_implicit_template (parser, decl);
   23654                 :             :       else
   23655                 :          65 :         finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
   23656                 :             :     }
   23657                 :             : 
   23658                 :    41769441 :   if (auto_result && is_initialized && decl_specifiers->type
   23659                 :   141644450 :       && type_uses_auto (decl_specifiers->type))
   23660                 :     5576699 :     *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                 :             : 
   23710                 :             : static cp_declarator *
   23711                 :   970806835 : cp_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                 :   970806835 :   cp_declarator *declarator;
   23719                 :   970806835 :   enum tree_code code;
   23720                 :   970806835 :   cp_cv_quals cv_quals;
   23721                 :   970806835 :   tree class_type;
   23722                 :   970806835 :   tree gnu_attributes = NULL_TREE, std_attributes = NULL_TREE;
   23723                 :             : 
   23724                 :             :   /* Assume this is not a constructor, destructor, or type-conversion
   23725                 :             :      operator.  */
   23726                 :   970806835 :   if (ctor_dtor_or_conv_p)
   23727                 :   256110165 :     *ctor_dtor_or_conv_p = 0;
   23728                 :             : 
   23729                 :   970806835 :   if (cp_parser_allow_gnu_extensions_p (parser))
   23730                 :   970806835 :     gnu_attributes = cp_parser_gnu_attributes_opt (parser);
   23731                 :             : 
   23732                 :             :   /* Check for the ptr-operator production.  */
   23733                 :   970806835 :   cp_parser_parse_tentatively (parser);
   23734                 :             :   /* Parse the ptr-operator.  */
   23735                 :   970806835 :   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                 :   970806835 :   if (cp_parser_parse_definitely (parser))
   23742                 :             :     {
   23743                 :             :       /* If a ptr-operator was found, then this declarator was not
   23744                 :             :          parenthesized.  */
   23745                 :   166467645 :       if (parenthesized_p)
   23746                 :   115074537 :         *parenthesized_p = false;
   23747                 :             :       /* The dependent declarator is optional if we are parsing an
   23748                 :             :          abstract-declarator.  */
   23749                 :   166467645 :       if (dcl_kind != CP_PARSER_DECLARATOR_NAMED)
   23750                 :   133116542 :         cp_parser_parse_tentatively (parser);
   23751                 :             : 
   23752                 :             :       /* Parse the dependent declarator.  */
   23753                 :   166467645 :       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                 :   166467645 :       if (dcl_kind != CP_PARSER_DECLARATOR_NAMED
   23761                 :   166467645 :           && !cp_parser_parse_definitely (parser))
   23762                 :             :         declarator = NULL;
   23763                 :             : 
   23764                 :   166467645 :       declarator = cp_parser_make_indirect_declarator
   23765                 :   166467645 :         (code, class_type, cv_quals, declarator, std_attributes);
   23766                 :             :     }
   23767                 :             :   /* Everything else is a direct-declarator.  */
   23768                 :             :   else
   23769                 :             :     {
   23770                 :   804339190 :       if (parenthesized_p)
   23771                 :   110098083 :         *parenthesized_p = cp_lexer_next_token_is (parser->lexer,
   23772                 :             :                                                    CPP_OPEN_PAREN);
   23773                 :   804339190 :       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                 :   970806835 :   if (gnu_attributes && declarator && declarator != cp_error_declarator)
   23779                 :       10917 :     declarator->attributes = gnu_attributes;
   23780                 :   970806835 :   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                 :             : 
   23814                 :             : static cp_declarator *
   23815                 :   804339190 : cp_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                 :   804339190 :   cp_token *token;
   23822                 :   804339190 :   cp_declarator *declarator = NULL;
   23823                 :   804339190 :   tree scope = NULL_TREE;
   23824                 :   804339190 :   bool saved_default_arg_ok_p = parser->default_arg_ok_p;
   23825                 :   804339190 :   bool saved_in_declarator_p = parser->in_declarator_p;
   23826                 :   804339190 :   bool first = true;
   23827                 :   804339190 :   tree pushed_scope = NULL_TREE;
   23828                 :   804339190 :   cp_token *open_paren = NULL, *close_paren = NULL;
   23829                 :             : 
   23830                 :  1444471517 :   while (true)
   23831                 :             :     {
   23832                 :             :       /* Peek at the next token.  */
   23833                 :  1444471517 :       token = cp_lexer_peek_token (parser->lexer);
   23834                 :  1444471517 :       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                 :   167163814 :           if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
   23875                 :             :             {
   23876                 :   166217184 :               tree params;
   23877                 :   166217184 :               bool is_declarator = false;
   23878                 :             : 
   23879                 :   166217184 :               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                 :   166217184 :               if (!member_p)
   23888                 :    81211555 :                 cp_parser_parse_tentatively (parser);
   23889                 :             : 
   23890                 :             :               /* Consume the `('.  */
   23891                 :   166217184 :               const location_t parens_start = token->location;
   23892                 :   166217184 :               matching_parens parens;
   23893                 :   166217184 :               parens.consume_open (parser);
   23894                 :   166217184 :               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                 :     2589016 :                   parser->default_arg_ok_p = false;
   23899                 :     2589016 :                   parser->in_declarator_p = true;
   23900                 :             :                 }
   23901                 :             : 
   23902                 :   166217184 :               begin_scope (sk_function_parms, NULL_TREE);
   23903                 :             : 
   23904                 :             :               /* Parse the parameter-declaration-clause.  */
   23905                 :   166217184 :               params
   23906                 :   166217184 :                 = cp_parser_parameter_declaration_clause (parser, flags);
   23907                 :   166217184 :               const location_t parens_end
   23908                 :   166217184 :                 = cp_lexer_peek_token (parser->lexer)->location;
   23909                 :             : 
   23910                 :             :               /* Consume the `)'.  */
   23911                 :   166217184 :               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                 :   338985337 :               if (cp_parser_error_occurred (parser)
   23921                 :     6550969 :                   && parser->fully_implicit_function_template_p
   23922                 :             :                   /* Don't do this for the inner ().  */
   23923                 :          83 :                   && parser->default_arg_ok_p)
   23924                 :          20 :                 abort_fully_implicit_template (parser);
   23925                 :             : 
   23926                 :             :               /* If all went well, parse the cv-qualifier-seq,
   23927                 :             :                  ref-qualifier and the exception-specification.  */
   23928                 :   166217184 :               if (member_p || cp_parser_parse_definitely (parser))
   23929                 :             :                 {
   23930                 :   159666215 :                   cp_cv_quals cv_quals;
   23931                 :   159666215 :                   cp_virt_specifiers virt_specifiers;
   23932                 :   159666215 :                   cp_ref_qualifier ref_qual;
   23933                 :   159666215 :                   tree exception_specification;
   23934                 :   159666215 :                   tree late_return;
   23935                 :   159666215 :                   tree attrs;
   23936                 :   159666215 :                   bool memfn = (member_p || (pushed_scope
   23937                 :     8644584 :                                              && CLASS_TYPE_P (pushed_scope)));
   23938                 :   159666215 :                   unsigned char local_variables_forbidden_p
   23939                 :             :                     = parser->local_variables_forbidden_p;
   23940                 :             :                   /* 'this' is not allowed in static member functions.  */
   23941                 :   159666215 :                   if (static_p || friend_p)
   23942                 :    12065766 :                     parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
   23943                 :             : 
   23944                 :   159666215 :                   is_declarator = true;
   23945                 :             : 
   23946                 :   159666215 :                   if (ctor_dtor_or_conv_p)
   23947                 :   135874843 :                     *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
   23948                 :   159666215 :                   first = false;
   23949                 :             : 
   23950                 :             :                   /* Parse the cv-qualifier-seq.  */
   23951                 :   159666215 :                   cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
   23952                 :             :                   /* Parse the ref-qualifier. */
   23953                 :   159666215 :                   ref_qual = cp_parser_ref_qualifier_opt (parser);
   23954                 :             :                   /* Parse the tx-qualifier.  */
   23955                 :   159666215 :                   tree tx_qual = cp_parser_tx_qualifier_opt (parser);
   23956                 :             : 
   23957                 :   159666215 :                   tree save_ccp = current_class_ptr;
   23958                 :   159666215 :                   tree save_ccr = current_class_ref;
   23959                 :   159666215 :                   if (memfn && !friend_p && !static_p)
   23960                 :             :                     /* DR 1207: 'this' is in scope after the cv-quals.  */
   23961                 :    82081342 :                     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                 :   159666215 :                   if (declarator == NULL || declarator->kind != cdk_id)
   23966                 :     2306948 :                     flags &= ~CP_PARSER_FLAGS_DELAY_NOEXCEPT;
   23967                 :             : 
   23968                 :             :                   /* Parse the exception-specification.  */
   23969                 :   159666215 :                   exception_specification
   23970                 :   159666215 :                     = cp_parser_exception_specification_opt (parser,
   23971                 :             :                                                              flags);
   23972                 :             : 
   23973                 :   159666215 :                   attrs = cp_parser_std_attribute_spec_seq (parser);
   23974                 :             : 
   23975                 :   159666215 :                   cp_omp_declare_simd_data odsd;
   23976                 :   159666215 :                   if ((flag_openmp || flag_openmp_simd)
   23977                 :      156833 :                       && declarator
   23978                 :      156627 :                       && declarator->std_attributes
   23979                 :         154 :                       && declarator->kind == cdk_id)
   23980                 :             :                     {
   23981                 :         154 :                       tree *pa = &declarator->std_attributes;
   23982                 :         154 :                       cp_parser_handle_directive_omp_attributes (parser, pa,
   23983                 :             :                                                                  &odsd, 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                 :   159666215 :                   tree gnu_attrs = NULL_TREE;
   23990                 :   159666215 :                   tree requires_clause = NULL_TREE;
   23991                 :   159666215 :                   late_return
   23992                 :   159666215 :                     = cp_parser_late_return_type_opt (parser, declarator,
   23993                 :             :                                                       requires_clause);
   23994                 :             : 
   23995                 :   159666215 :                   cp_finalize_omp_declare_simd (parser, &odsd);
   23996                 :             : 
   23997                 :             :                   /* Parse the virt-specifier-seq.  */
   23998                 :   159666215 :                   virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
   23999                 :             : 
   24000                 :   159666215 :                   location_t parens_loc = make_location (parens_start,
   24001                 :             :                                                          parens_start,
   24002                 :             :                                                          parens_end);
   24003                 :             :                   /* Create the function-declarator.  */
   24004                 :   159666215 :                   declarator = make_call_declarator (declarator,
   24005                 :             :                                                      params,
   24006                 :             :                                                      cv_quals,
   24007                 :             :                                                      virt_specifiers,
   24008                 :             :                                                      ref_qual,
   24009                 :             :                                                      tx_qual,
   24010                 :             :                                                      exception_specification,
   24011                 :             :                                                      late_return,
   24012                 :             :                                                      requires_clause,
   24013                 :             :                                                      attrs,
   24014                 :             :                                                      parens_loc);
   24015                 :   159666215 :                   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                 :   159666215 :                   parser->default_arg_ok_p = false;
   24020                 :             : 
   24021                 :   159666215 :                   current_class_ptr = save_ccp;
   24022                 :   159666215 :                   current_class_ref = save_ccr;
   24023                 :             : 
   24024                 :             :                   /* Restore the state of local_variables_forbidden_p.  */
   24025                 :   159666215 :                   parser->local_variables_forbidden_p
   24026                 :   159666215 :                     = local_variables_forbidden_p;
   24027                 :             :                 }
   24028                 :             : 
   24029                 :             :               /* Remove the function parms from scope.  */
   24030                 :   166217184 :               pop_bindings_and_leave_scope ();
   24031                 :             : 
   24032                 :   166217184 :               if (is_declarator)
   24033                 :             :                 /* Repeat the main loop.  */
   24034                 :   159666215 :                 continue;
   24035                 :             :             }
   24036                 :             : 
   24037                 :             :           /* If this is the first, we can try a parenthesized
   24038                 :             :              declarator.  */
   24039                 :     7497599 :           if (first)
   24040                 :             :             {
   24041                 :     3062833 :               bool saved_in_type_id_in_expr_p;
   24042                 :             : 
   24043                 :     3062833 :               parser->default_arg_ok_p = saved_default_arg_ok_p;
   24044                 :     3062833 :               parser->in_declarator_p = saved_in_declarator_p;
   24045                 :             : 
   24046                 :     3062833 :               open_paren = token;
   24047                 :             :               /* Consume the `('.  */
   24048                 :     3062833 :               matching_parens parens;
   24049                 :     3062833 :               parens.consume_open (parser);
   24050                 :             :               /* Parse the nested declarator.  */
   24051                 :     3062833 :               saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
   24052                 :     3062833 :               parser->in_type_id_in_expr_p = true;
   24053                 :     3062833 :               declarator
   24054                 :     3062833 :                 = 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                 :     3062833 :               parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
   24060                 :     3062833 :               first = false;
   24061                 :             :               /* Expect a `)'.  */
   24062                 :     3062833 :               close_paren = cp_lexer_peek_token (parser->lexer);
   24063                 :     3062833 :               if (!parens.require_close (parser))
   24064                 :      579198 :                 declarator = cp_error_declarator;
   24065                 :     3062833 :               if (declarator == cp_error_declarator)
   24066                 :             :                 break;
   24067                 :             : 
   24068                 :     2368975 :               goto handle_declarator;
   24069                 :             :             }
   24070                 :             :           /* Otherwise, we must be done.  */
   24071                 :             :           else
   24072                 :             :             break;
   24073                 :             :         }
   24074                 :  1277307703 :       else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
   24075                 :  1019282280 :                && token->type == CPP_OPEN_SQUARE
   24076                 :  1280339742 :                && !cp_next_tokens_can_be_attribute_p (parser))
   24077                 :             :         {
   24078                 :             :           /* Parse an array-declarator.  */
   24079                 :     3032036 :           tree bounds, attrs;
   24080                 :             : 
   24081                 :     3032036 :           if (ctor_dtor_or_conv_p)
   24082                 :     1485612 :             *ctor_dtor_or_conv_p = 0;
   24083                 :             : 
   24084                 :     3032036 :           open_paren = NULL;
   24085                 :     3032036 :           first = false;
   24086                 :     3032036 :           parser->default_arg_ok_p = false;
   24087                 :     3032036 :           parser->in_declarator_p = true;
   24088                 :             :           /* Consume the `['.  */
   24089                 :     3032036 :           cp_lexer_consume_token (parser->lexer);
   24090                 :             :           /* Peek at the next token.  */
   24091                 :     3032036 :           token = cp_lexer_peek_token (parser->lexer);
   24092                 :             :           /* If the next token is `]', then there is no
   24093                 :             :              constant-expression.  */
   24094                 :     3032036 :           if (token->type != CPP_CLOSE_SQUARE)
   24095                 :             :             {
   24096                 :     2298454 :               bool non_constant_p;
   24097                 :     2298454 :               bounds
   24098                 :     2298454 :                 = cp_parser_constant_expression (parser,
   24099                 :             :                                                  /*allow_non_constant=*/true,
   24100                 :             :                                                  &non_constant_p);
   24101                 :     2298454 :               if (!non_constant_p)
   24102                 :             :                 /* OK */;
   24103                 :        1660 :               else if (error_operand_p (bounds))
   24104                 :             :                 /* Already gave an error.  */;
   24105                 :     2298454 :               else if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
   24106                 :             :                 /* Let compute_array_index_type diagnose this.  */;
   24107                 :         282 :               else if (!parser->in_function_body
   24108                 :         282 :                        || 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                 :           9 :                   cp_parser_error (parser,
   24115                 :             :                                    "array bound is not an integer constant");
   24116                 :           9 :                   bounds = error_mark_node;
   24117                 :             :                 }
   24118                 :         273 :               else if (processing_template_decl
   24119                 :         273 :                        && !type_dependent_expression_p (bounds))
   24120                 :             :                 {
   24121                 :             :                   /* Remember this wasn't a constant-expression.  */
   24122                 :           6 :                   bounds = build_nop (TREE_TYPE (bounds), bounds);
   24123                 :           6 :                   TREE_SIDE_EFFECTS (bounds) = 1;
   24124                 :             :                 }
   24125                 :             :             }
   24126                 :             :           else
   24127                 :             :             bounds = NULL_TREE;
   24128                 :             :           /* Look for the closing `]'.  */
   24129                 :     3032036 :           if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
   24130                 :             :             {
   24131                 :          12 :               declarator = cp_error_declarator;
   24132                 :          12 :               break;
   24133                 :             :             }
   24134                 :             : 
   24135                 :     3032024 :           attrs = cp_parser_std_attribute_spec_seq (parser);
   24136                 :     3032024 :           declarator = make_array_declarator (declarator, bounds);
   24137                 :     3032024 :           declarator->std_attributes = attrs;
   24138                 :             :         }
   24139                 :  1274275667 :       else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
   24140                 :             :         {
   24141                 :   495153438 :           {
   24142                 :   495153438 :             tree qualifying_scope;
   24143                 :   495153438 :             tree unqualified_name;
   24144                 :   495153438 :             tree attrs;
   24145                 :   495153438 :             special_function_kind sfk;
   24146                 :   495153438 :             bool abstract_ok;
   24147                 :   495153438 :             bool pack_expansion_p = false;
   24148                 :   495153438 :             cp_token *declarator_id_start_token;
   24149                 :             : 
   24150                 :             :             /* Parse a declarator-id */
   24151                 :   495153438 :             abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
   24152                 :   495153438 :             if (abstract_ok)
   24153                 :             :               {
   24154                 :   237128015 :                 cp_parser_parse_tentatively (parser);
   24155                 :             : 
   24156                 :             :                 /* If we see an ellipsis, we should be looking at a
   24157                 :             :                    parameter pack. */
   24158                 :   237128015 :                 if (token->type == CPP_ELLIPSIS)
   24159                 :             :                   {
   24160                 :             :                     /* Consume the `...' */
   24161                 :     4471100 :                     cp_lexer_consume_token (parser->lexer);
   24162                 :             : 
   24163                 :     4471100 :                     pack_expansion_p = true;
   24164                 :             :                   }
   24165                 :             :               }
   24166                 :             : 
   24167                 :   495153438 :             declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
   24168                 :   495153438 :             unqualified_name
   24169                 :   495153438 :               = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
   24170                 :   495153438 :             qualifying_scope = parser->scope;
   24171                 :   495153438 :             if (abstract_ok)
   24172                 :             :               {
   24173                 :   237128015 :                 bool okay = false;
   24174                 :             : 
   24175                 :   237128015 :                 if (!unqualified_name && pack_expansion_p)
   24176                 :             :                   {
   24177                 :             :                     /* Check whether an error occurred. */
   24178                 :     2703584 :                     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                 :     1351792 :                     cp_parser_abort_tentative_parse (parser);
   24185                 :             :                   }
   24186                 :             :                 else
   24187                 :   235776223 :                   okay = cp_parser_parse_definitely (parser);
   24188                 :             : 
   24189                 :   237128015 :                 if (!okay)
   24190                 :           1 :                   unqualified_name = error_mark_node;
   24191                 :   237128014 :                 else if (unqualified_name
   24192                 :   237128014 :                          && (qualifying_scope
   24193                 :   495153450 :                              || (!identifier_p (unqualified_name))))
   24194                 :             :                   {
   24195                 :          12 :                     cp_parser_error (parser, "expected unqualified-id");
   24196                 :          12 :                     unqualified_name = error_mark_node;
   24197                 :             :                   }
   24198                 :             :               }
   24199                 :             : 
   24200                 :   495153438 :             if (!unqualified_name)
   24201                 :             :               return NULL;
   24202                 :   475467167 :             if (unqualified_name == error_mark_node)
   24203                 :             :               {
   24204                 :      214974 :                 declarator = cp_error_declarator;
   24205                 :      214974 :                 pack_expansion_p = false;
   24206                 :      214974 :                 declarator->parameter_pack_p = false;
   24207                 :      214974 :                 break;
   24208                 :             :               }
   24209                 :             : 
   24210                 :   475252193 :             attrs = cp_parser_std_attribute_spec_seq (parser);
   24211                 :             : 
   24212                 :     9278177 :             if (qualifying_scope && at_namespace_scope_p ()
   24213                 :   484257973 :                 && 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                 :          21 :                 tree type;
   24232                 :             : 
   24233                 :             :                 /* Resolve the TYPENAME_TYPE.  */
   24234                 :          21 :                 type = resolve_typename_type (qualifying_scope,
   24235                 :             :                                               /*only_current_p=*/false);
   24236                 :             :                 /* If that failed, the declarator is invalid.  */
   24237                 :          21 :                 if (TREE_CODE (type) == TYPENAME_TYPE)
   24238                 :             :                   {
   24239                 :          21 :                     if (typedef_variant_p (type))
   24240                 :           6 :                       error_at (declarator_id_start_token->location,
   24241                 :             :                                 "cannot define member of dependent typedef "
   24242                 :             :                                 "%qT", type);
   24243                 :             :                     else
   24244                 :          30 :                       error_at (declarator_id_start_token->location,
   24245                 :             :                                 "%<%T::%E%> is not a type",
   24246                 :          15 :                                 TYPE_CONTEXT (qualifying_scope),
   24247                 :          15 :                                 TYPE_IDENTIFIER (qualifying_scope));
   24248                 :             :                   }
   24249                 :             :                 qualifying_scope = type;
   24250                 :             :               }
   24251                 :             : 
   24252                 :   475252193 :             sfk = sfk_none;
   24253                 :             : 
   24254                 :   475252193 :             if (unqualified_name)
   24255                 :             :               {
   24256                 :   475252193 :                 tree class_type;
   24257                 :             : 
   24258                 :   475252193 :                 if (qualifying_scope
   24259                 :   475252193 :                     && CLASS_TYPE_P (qualifying_scope))
   24260                 :             :                   class_type = qualifying_scope;
   24261                 :             :                 else
   24262                 :   466249842 :                   class_type = current_class_type;
   24263                 :             : 
   24264                 :   475252193 :                 if (TREE_CODE (unqualified_name) == TYPE_DECL)
   24265                 :             :                   {
   24266                 :         126 :                     tree name_type = TREE_TYPE (unqualified_name);
   24267                 :             : 
   24268                 :         126 :                     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                 :          76 :                         cp_parser_error (parser, "invalid declarator");
   24275                 :          76 :                         declarator = cp_error_declarator;
   24276                 :          76 :                         break;
   24277                 :             :                       }
   24278                 :          50 :                     else if (qualifying_scope
   24279                 :          50 :                              && CLASSTYPE_USE_TEMPLATE (name_type))
   24280                 :             :                       {
   24281                 :           0 :                         error_at (declarator_id_start_token->location,
   24282                 :             :                                   "invalid use of constructor as a template");
   24283                 :           0 :                         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                 :           0 :                                 DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
   24288                 :             :                                 class_type, name_type);
   24289                 :           0 :                         declarator = cp_error_declarator;
   24290                 :           0 :                         break;
   24291                 :             :                       }
   24292                 :          50 :                     unqualified_name = constructor_name (class_type);
   24293                 :             :                   }
   24294                 :             : 
   24295                 :   475252117 :                 if (class_type)
   24296                 :             :                   {
   24297                 :   255330944 :                     if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
   24298                 :             :                       sfk = sfk_destructor;
   24299                 :   252514266 :                     else if (identifier_p (unqualified_name)
   24300                 :   485131386 :                              && IDENTIFIER_CONV_OP_P (unqualified_name))
   24301                 :             :                       sfk = sfk_conversion;
   24302                 :   251995106 :                     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                 :   251995106 :                              !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                 :   251995098 :                              && (!friend_p || class_type == qualifying_scope)
   24323                 :   500627381 :                              && constructor_name_p (unqualified_name,
   24324                 :             :                                                     class_type))
   24325                 :             :                       sfk = sfk_constructor;
   24326                 :   231926736 :                     else if (is_overloaded_fn (unqualified_name)
   24327                 :   231953705 :                              && DECL_CONSTRUCTOR_P (get_first_fn
   24328                 :             :                                                     (unqualified_name)))
   24329                 :             :                       sfk = sfk_constructor;
   24330                 :             : 
   24331                 :   255330944 :                     if (ctor_dtor_or_conv_p && sfk != sfk_none)
   24332                 :    23404040 :                       *ctor_dtor_or_conv_p = -1;
   24333                 :             :                   }
   24334                 :             :               }
   24335                 :   475252117 :             declarator = make_id_declarator (qualifying_scope,
   24336                 :             :                                              unqualified_name,
   24337                 :             :                                              sfk, token->location);
   24338                 :   475252117 :             declarator->std_attributes = attrs;
   24339                 :   475252117 :             declarator->parameter_pack_p = pack_expansion_p;
   24340                 :             : 
   24341                 :   475252117 :             if (pack_expansion_p)
   24342                 :     3119308 :               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                 :   475252117 :             if (cxx_dialect >= cxx20
   24350                 :   115074745 :                 && (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL)
   24351                 :    39025215 :                 && declarator->kind == cdk_id
   24352                 :    39025215 :                 && !at_class_scope_p ()
   24353                 :   483187785 :                 && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   24354                 :             :               {
   24355                 :             :                 /* ...whose declarator-id is qualified.  If it isn't, never
   24356                 :             :                    assume the parameters to refer to types.  */
   24357                 :     7065527 :                 if (qualifying_scope == NULL_TREE)
   24358                 :     5475992 :                   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                 :     1589535 :                     tree decl
   24369                 :     1589535 :                       = 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                 :     1589535 :                     if (!is_overloaded_fn (decl)
   24378                 :             :                         /* Allow
   24379                 :             :                            template<typename T>
   24380                 :             :                            A<T>::A(T::type) { }  */
   24381                 :     1589583 :                         && !(MAYBE_CLASS_TYPE_P (qualifying_scope)
   24382                 :          48 :                              && constructor_name_p (unqualified_name,
   24383                 :             :                                                     qualifying_scope)))
   24384                 :          51 :                       flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
   24385                 :             :                   }
   24386                 :             :               }
   24387                 :             :           }
   24388                 :             : 
   24389                 :   477621092 :         handle_declarator:;
   24390                 :   477621092 :           scope = get_scope_of_declarator (declarator);
   24391                 :   477621092 :           if (scope)
   24392                 :             :             {
   24393                 :             :               /* Any names that appear after the declarator-id for a
   24394                 :             :                  member are looked up in the containing scope.  */
   24395                 :     9278289 :               if (at_function_scope_p ())
   24396                 :             :                 {
   24397                 :             :                   /* But declarations with qualified-ids can't appear in a
   24398                 :             :                      function.  */
   24399                 :      187004 :                   cp_parser_error (parser, "qualified-id in declaration");
   24400                 :      187004 :                   declarator = cp_error_declarator;
   24401                 :      187004 :                   break;
   24402                 :             :                 }
   24403                 :     9091285 :               pushed_scope = push_scope (scope);
   24404                 :             :             }
   24405                 :   477434088 :           parser->in_declarator_p = true;
   24406                 :   477434088 :           if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
   24407                 :   454030048 :               || (declarator && declarator->kind == cdk_id))
   24408                 :             :             /* Default args are only allowed on function
   24409                 :             :                declarations.  */
   24410                 :   475162483 :             parser->default_arg_ok_p = saved_default_arg_ok_p;
   24411                 :             :           else
   24412                 :     2271605 :             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                 :   784652919 :   if (!declarator)
   24424                 :   305243515 :     cp_parser_error (parser, "expected declarator");
   24425                 :   479409404 :   else if (open_paren)
   24426                 :             :     {
   24427                 :             :       /* Record overly parenthesized declarator so we can give a
   24428                 :             :          diagnostic about confusing decl/expr disambiguation.  */
   24429                 :      791478 :       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                 :          40 :           expanded_location open = expand_location (open_paren->location);
   24434                 :          40 :           expanded_location close = expand_location (close_paren->location);
   24435                 :          40 :           if (open.line != close.line || open.file != close.file)
   24436                 :           8 :             open_paren = NULL;
   24437                 :             :         }
   24438                 :           8 :       if (open_paren)
   24439                 :      791470 :         declarator->parenthesized = make_location (open_paren->location,
   24440                 :             :                                                    open_paren->location,
   24441                 :             :                                                    close_paren->location);
   24442                 :             :     }
   24443                 :             : 
   24444                 :             :   /* If we entered a scope, we must exit it now.  */
   24445                 :   784652919 :   if (pushed_scope)
   24446                 :     9091213 :     pop_scope (pushed_scope);
   24447                 :             : 
   24448                 :   784652919 :   parser->default_arg_ok_p = saved_default_arg_ok_p;
   24449                 :   784652919 :   parser->in_declarator_p = saved_in_declarator_p;
   24450                 :             : 
   24451                 :   784652919 :   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. */
   24478                 :             : static enum tree_code
   24479                 :   972887773 : cp_parser_ptr_operator (cp_parser* parser,
   24480                 :             :                         tree* type,
   24481                 :             :                         cp_cv_quals *cv_quals,
   24482                 :             :                         tree *attributes)
   24483                 :             : {
   24484                 :   972887773 :   enum tree_code code = ERROR_MARK;
   24485                 :   972887773 :   cp_token *token;
   24486                 :   972887773 :   tree attrs = NULL_TREE;
   24487                 :             : 
   24488                 :             :   /* Assume that it's not a pointer-to-member.  */
   24489                 :   972887773 :   *type = NULL_TREE;
   24490                 :             :   /* And that there are no cv-qualifiers.  */
   24491                 :   972887773 :   *cv_quals = TYPE_UNQUALIFIED;
   24492                 :             : 
   24493                 :             :   /* Peek at the next token.  */
   24494                 :   972887773 :   token = cp_lexer_peek_token (parser->lexer);
   24495                 :             : 
   24496                 :             :   /* If it's a `*', `&' or `&&' we have a pointer or reference.  */
   24497                 :   972887773 :   if (token->type == CPP_MULT)
   24498                 :             :     code = INDIRECT_REF;
   24499                 :   915278292 :   else if (token->type == CPP_AND)
   24500                 :             :     code = ADDR_EXPR;
   24501                 :   823198213 :   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                 :   165438326 :       cp_lexer_consume_token (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                 :   165438326 :       if (code == INDIRECT_REF
   24515                 :   165438326 :           || cp_parser_allow_gnu_extensions_p (parser))
   24516                 :   165438326 :         *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
   24517                 :             : 
   24518                 :   165438326 :       attrs = cp_parser_std_attribute_spec_seq (parser);
   24519                 :   165438326 :       if (attributes != NULL)
   24520                 :   165438326 :         *attributes = attrs;
   24521                 :             :     }
   24522                 :             :   else
   24523                 :             :     {
   24524                 :             :       /* Try the pointer-to-member case.  */
   24525                 :   807449447 :       cp_parser_parse_tentatively (parser);
   24526                 :             :       /* Look for the optional `::' operator.  */
   24527                 :   807449447 :       cp_parser_global_scope_opt (parser,
   24528                 :             :                                   /*current_scope_valid_p=*/false);
   24529                 :             :       /* Look for the nested-name specifier.  */
   24530                 :   807449447 :       token = cp_lexer_peek_token (parser->lexer);
   24531                 :   807449447 :       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                 :  1625324211 :       if (!cp_parser_error_occurred (parser)
   24539                 :    10425317 :           && cp_parser_require (parser, CPP_MULT, RT_MULT))
   24540                 :             :         {
   24541                 :             :           /* Indicate that the `*' operator was used.  */
   24542                 :     1111609 :           code = INDIRECT_REF;
   24543                 :             : 
   24544                 :     1111609 :           if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
   24545                 :           8 :             error_at (token->location, "%qD is a namespace", parser->scope);
   24546                 :     1111601 :           else if (TREE_CODE (parser->scope) == ENUMERAL_TYPE)
   24547                 :           3 :             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                 :     1111598 :               *type = parser->scope;
   24554                 :             :               /* The next name will not be qualified.  */
   24555                 :     1111598 :               parser->scope = NULL_TREE;
   24556                 :     1111598 :               parser->qualifying_scope = NULL_TREE;
   24557                 :     1111598 :               parser->object_scope = NULL_TREE;
   24558                 :             :               /* Look for optional c++11 attributes.  */
   24559                 :     1111598 :               attrs = cp_parser_std_attribute_spec_seq (parser);
   24560                 :     1111598 :               if (attributes != NULL)
   24561                 :     1111598 :                 *attributes = attrs;
   24562                 :             :               /* Look for the optional cv-qualifier-seq.  */
   24563                 :     1111598 :               *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                 :   807449447 :       if (!cp_parser_parse_definitely (parser))
   24568                 :   806337838 :         cp_parser_error (parser, "expected ptr-operator");
   24569                 :             :     }
   24570                 :             : 
   24571                 :   972887773 :   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                 :             : 
   24590                 :             : static cp_cv_quals
   24591                 :   326216139 : cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
   24592                 :             : {
   24593                 :   326216139 :   cp_cv_quals cv_quals = TYPE_UNQUALIFIED;
   24594                 :             : 
   24595                 :   361148283 :   while (true)
   24596                 :             :     {
   24597                 :   361148283 :       cp_token *token;
   24598                 :   361148283 :       cp_cv_quals cv_qualifier;
   24599                 :             : 
   24600                 :             :       /* Peek at the next token.  */
   24601                 :   361148283 :       token = cp_lexer_peek_token (parser->lexer);
   24602                 :             :       /* See if it's a cv-qualifier.  */
   24603                 :   361148283 :       switch (token->keyword)
   24604                 :             :         {
   24605                 :             :         case RID_CONST:
   24606                 :             :           cv_qualifier = TYPE_QUAL_CONST;
   24607                 :             :           break;
   24608                 :             : 
   24609                 :     1411267 :         case RID_VOLATILE:
   24610                 :     1411267 :           cv_qualifier = TYPE_QUAL_VOLATILE;
   24611                 :     1411267 :           break;
   24612                 :             : 
   24613                 :     7459112 :         case RID_RESTRICT:
   24614                 :     7459112 :           cv_qualifier = TYPE_QUAL_RESTRICT;
   24615                 :     7459112 :           break;
   24616                 :             : 
   24617                 :   326216139 :         default:
   24618                 :   326216139 :           cv_qualifier = TYPE_UNQUALIFIED;
   24619                 :   326216139 :           break;
   24620                 :             :         }
   24621                 :             : 
   24622                 :     8870379 :       if (!cv_qualifier)
   24623                 :             :         break;
   24624                 :             : 
   24625                 :    34932144 :       if (cv_quals & cv_qualifier)
   24626                 :             :         {
   24627                 :           4 :           gcc_rich_location richloc (token->location);
   24628                 :           4 :           richloc.add_fixit_remove ();
   24629                 :           4 :           error_at (&richloc, "duplicate cv-qualifier");
   24630                 :           4 :           cp_lexer_purge_token (parser->lexer);
   24631                 :           4 :         }
   24632                 :             :       else
   24633                 :             :         {
   24634                 :    34932140 :           cp_lexer_consume_token (parser->lexer);
   24635                 :    34932140 :           cv_quals |= cv_qualifier;
   24636                 :             :         }
   24637                 :             :     }
   24638                 :             : 
   24639                 :   326216139 :   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                 :             : 
   24650                 :             : static cp_ref_qualifier
   24651                 :   159722010 : cp_parser_ref_qualifier_opt (cp_parser* parser)
   24652                 :             : {
   24653                 :   159722010 :   cp_ref_qualifier ref_qual = REF_QUAL_NONE;
   24654                 :             : 
   24655                 :             :   /* Don't try to parse bitwise '&' as a ref-qualifier (c++/57532).  */
   24656                 :   159722010 :   if (cxx_dialect < cxx11 && cp_parser_parsing_tentatively (parser))
   24657                 :             :     return ref_qual;
   24658                 :             : 
   24659                 :   160304811 :   while (true)
   24660                 :             :     {
   24661                 :   160304811 :       cp_ref_qualifier curr_ref_qual = REF_QUAL_NONE;
   24662                 :   160304811 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   24663                 :             : 
   24664                 :   160304811 :       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                 :      464107 :       if (!curr_ref_qual)
   24680                 :             :         break;
   24681                 :      925314 :       else if (ref_qual)
   24682                 :             :         {
   24683                 :           6 :           error_at (token->location, "multiple ref-qualifiers");
   24684                 :           6 :           cp_lexer_purge_token (parser->lexer);
   24685                 :             :         }
   24686                 :             :       else
   24687                 :             :         {
   24688                 :      925308 :           ref_qual = curr_ref_qual;
   24689                 :      925308 :           cp_lexer_consume_token (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                 :             : 
   24702                 :             : static tree
   24703                 :   160194925 : cp_parser_tx_qualifier_opt (cp_parser *parser)
   24704                 :             : {
   24705                 :   160194925 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   24706                 :   160194925 :   if (token->type == CPP_NAME)
   24707                 :             :     {
   24708                 :       85626 :       tree name = token->u.value;
   24709                 :       85626 :       const char *p = IDENTIFIER_POINTER (name);
   24710                 :       85626 :       const int len = strlen ("transaction_safe");
   24711                 :       85626 :       if (startswith (p, "transaction_safe"))
   24712                 :             :         {
   24713                 :         152 :           p += len;
   24714                 :         152 :           if (*p == '\0'
   24715                 :          31 :               || !strcmp (p, "_dynamic"))
   24716                 :             :             {
   24717                 :         152 :               cp_lexer_consume_token (parser->lexer);
   24718                 :         152 :               if (!flag_tm)
   24719                 :             :                 {
   24720                 :           0 :                   error ("%qE requires %<-fgnu-tm%>", name);
   24721                 :           0 :                   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                 :             : 
   24742                 :             : static cp_virt_specifiers
   24743                 :   194782561 : cp_parser_virt_specifier_seq_opt (cp_parser* parser)
   24744                 :             : {
   24745                 :   194782561 :   cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
   24746                 :             : 
   24747                 :   195028904 :   while (true)
   24748                 :             :     {
   24749                 :   195028904 :       cp_token *token;
   24750                 :   195028904 :       cp_virt_specifiers virt_specifier;
   24751                 :             : 
   24752                 :             :       /* Peek at the next token.  */
   24753                 :   195028904 :       token = cp_lexer_peek_token (parser->lexer);
   24754                 :             :       /* See if it's a virt-specifier-qualifier.  */
   24755                 :   195028904 :       if (token->type != CPP_NAME)
   24756                 :             :         break;
   24757                 :      792083 :       if (id_equal (token->u.value, "override"))
   24758                 :             :         {
   24759                 :      144343 :           maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
   24760                 :      144343 :           virt_specifier = VIRT_SPEC_OVERRIDE;
   24761                 :             :         }
   24762                 :      647740 :       else if (id_equal (token->u.value, "final"))
   24763                 :             :         {
   24764                 :      101999 :           maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
   24765                 :      101999 :           virt_specifier = VIRT_SPEC_FINAL;
   24766                 :             :         }
   24767                 :      545741 :       else if (id_equal (token->u.value, "__final"))
   24768                 :             :         {
   24769                 :             :           virt_specifier = VIRT_SPEC_FINAL;
   24770                 :             :         }
   24771                 :             :       else
   24772                 :             :         break;
   24773                 :             : 
   24774                 :      246343 :       if (virt_specifiers & virt_specifier)
   24775                 :             :         {
   24776                 :          12 :           gcc_rich_location richloc (token->location);
   24777                 :          12 :           richloc.add_fixit_remove ();
   24778                 :          12 :           error_at (&richloc, "duplicate virt-specifier");
   24779                 :          12 :           cp_lexer_purge_token (parser->lexer);
   24780                 :          12 :         }
   24781                 :             :       else
   24782                 :             :         {
   24783                 :      246331 :           cp_lexer_consume_token (parser->lexer);
   24784                 :      246331 :           virt_specifiers |= virt_specifier;
   24785                 :             :         }
   24786                 :             :     }
   24787                 :   194782561 :   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                 :             : 
   24793                 :             : void
   24794                 :    84279246 : inject_this_parameter (tree ctype, cp_cv_quals quals)
   24795                 :             : {
   24796                 :    84279246 :   tree this_parm;
   24797                 :             : 
   24798                 :    84279246 :   if (current_class_ptr)
   24799                 :             :     {
   24800                 :             :       /* We don't clear this between NSDMIs.  Is it already what we want?  */
   24801                 :      409260 :       tree type = TREE_TYPE (TREE_TYPE (current_class_ptr));
   24802                 :      409260 :       if (DECL_P (current_class_ptr)
   24803                 :      409260 :           && DECL_CONTEXT (current_class_ptr) == NULL_TREE
   24804                 :      409260 :           && same_type_ignoring_top_level_qualifiers_p (ctype, type)
   24805                 :      770590 :           && cp_type_quals (type) == quals)
   24806                 :             :         return;
   24807                 :             :     }
   24808                 :             : 
   24809                 :    83917916 :   this_parm = build_this_parm (NULL_TREE, ctype, quals);
   24810                 :             :   /* Clear this first to avoid shortcut in cp_build_indirect_ref.  */
   24811                 :    83917916 :   current_class_ptr = NULL_TREE;
   24812                 :    83917916 :   current_class_ref
   24813                 :    83917916 :     = cp_build_fold_indirect_ref (this_parm);
   24814                 :    83917916 :   current_class_ptr = this_parm;
   24815                 :             : }
   24816                 :             : 
   24817                 :             : /* Return true iff our current scope is a non-static data member
   24818                 :             :    initializer.  */
   24819                 :             : 
   24820                 :             : bool
   24821                 :  1368212863 : parsing_nsdmi (void)
   24822                 :             : {
   24823                 :             :   /* We recognize NSDMI context by the context-less 'this' pointer set up
   24824                 :             :      by the function above.  */
   24825                 :  1368212863 :   if (current_class_ptr
   24826                 :   566141596 :       && TREE_CODE (current_class_ptr) == PARM_DECL
   24827                 :  1934354459 :       && DECL_CONTEXT (current_class_ptr) == NULL_TREE)
   24828                 :         629 :     return true;
   24829                 :             :   return false;
   24830                 :             : }
   24831                 :             : 
   24832                 :             : /* True if we're parsing a function declarator.  */
   24833                 :             : 
   24834                 :             : bool
   24835                 :      847852 : parsing_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                 :      847852 :   return (current_binding_level->kind == sk_function_parms
   24840                 :      847852 :           && !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                 :             : 
   24856                 :             : static tree
   24857                 :   159666215 : cp_parser_late_return_type_opt (cp_parser* parser, cp_declarator *declarator,
   24858                 :             :                                 tree& requires_clause)
   24859                 :             : {
   24860                 :   159666215 :   cp_token *token;
   24861                 :   159666215 :   tree type = NULL_TREE;
   24862                 :   319332430 :   bool declare_simd_p = (parser->omp_declare_simd
   24863                 :        2430 :                          && declarator
   24864                 :   159668645 :                          && declarator->kind == cdk_id);
   24865                 :             : 
   24866                 :   319332430 :   bool oacc_routine_p = (parser->oacc_routine
   24867                 :         651 :                          && declarator
   24868                 :   159666866 :                          && declarator->kind == cdk_id);
   24869                 :             : 
   24870                 :             :   /* Peek at the next token.  */
   24871                 :   159666215 :   token = cp_lexer_peek_token (parser->lexer);
   24872                 :             :   /* A late-specified return type is indicated by an initial '->'. */
   24873                 :   159666215 :   if (token->type != CPP_DEREF
   24874                 :   157142199 :       && token->keyword != RID_REQUIRES
   24875                 :   156189398 :       && !(token->type == CPP_NAME
   24876                 :      146696 :            && token->u.value == ridpointers[RID_REQUIRES])
   24877                 :   156189398 :       && !(declare_simd_p || oacc_routine_p))
   24878                 :             :     return NULL_TREE;
   24879                 :             : 
   24880                 :     3479895 :   if (token->type == CPP_DEREF)
   24881                 :             :     {
   24882                 :             :       /* Consume the ->.  */
   24883                 :     2524016 :       cp_lexer_consume_token (parser->lexer);
   24884                 :             : 
   24885                 :     2524016 :       type = cp_parser_trailing_type_id (parser);
   24886                 :             :     }
   24887                 :             : 
   24888                 :             :   /* Function declarations may be followed by a trailing
   24889                 :             :      requires-clause.  */
   24890                 :     3479895 :   requires_clause = cp_parser_requires_clause_opt (parser, false);
   24891                 :             : 
   24892                 :     3479895 :   if (declare_simd_p)
   24893                 :        2430 :     declarator->attributes
   24894                 :        2430 :       = cp_parser_late_parsing_omp_declare_simd (parser,
   24895                 :             :                                                  declarator->attributes);
   24896                 :     3479895 :   if (oacc_routine_p)
   24897                 :         650 :     declarator->attributes
   24898                 :         650 :       = 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                 :             : 
   24917                 :             : static tree
   24918                 :   495153438 : cp_parser_declarator_id (cp_parser* parser, bool optional_p)
   24919                 :             : {
   24920                 :   495153438 :   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                 :   495153438 :   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                 :   495153438 :   if (id && BASELINK_P (id))
   24942                 :         313 :     id = BASELINK_FUNCTIONS (id);
   24943                 :   495153438 :   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                 :             : 
   24960                 :             : static tree
   24961                 :   344583059 : cp_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                 :   344583059 :   cp_decl_specifier_seq type_specifier_seq;
   24966                 :   344583059 :   cp_declarator *abstract_declarator;
   24967                 :             : 
   24968                 :             :   /* Parse the type-specifier-seq.  */
   24969                 :   344583059 :   cp_parser_type_specifier_seq (parser, flags,
   24970                 :             :                                 /*is_declaration=*/false,
   24971                 :             :                                 is_trailing_return,
   24972                 :             :                                 &type_specifier_seq);
   24973                 :   344583059 :   if (type_location)
   24974                 :    14244334 :     *type_location = type_specifier_seq.locations[ds_type_spec];
   24975                 :             : 
   24976                 :   294951445 :   if (is_template_arg && type_specifier_seq.type
   24977                 :   293511182 :       && TREE_CODE (type_specifier_seq.type) == TEMPLATE_TYPE_PARM
   24978                 :   351755037 :       && 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                 :           0 :       gcc_assert (cp_parser_uncommitted_to_tentative_parse_p (parser));
   24983                 :     7171850 :       cp_parser_simulate_error (parser);
   24984                 :     7171850 :       return error_mark_node;
   24985                 :             :     }
   24986                 :   337411209 :   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                 :   306109512 :   cp_parser_parse_tentatively (parser);
   24991                 :             :   /* Look for the declarator.  */
   24992                 :   306109512 :   abstract_declarator
   24993                 :   306109512 :     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT,
   24994                 :             :                             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                 :   306109512 :   if (!cp_parser_parse_definitely (parser))
   25001                 :   291052672 :     abstract_declarator = NULL;
   25002                 :             : 
   25003                 :   306109512 :   bool auto_typeid_ok = false;
   25004                 :             :   /* The concepts TS allows 'auto' as a type-id.  */
   25005                 :   306109512 :   if (flag_concepts_ts)
   25006                 :       58765 :     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                 :   306050747 :   else if (flag_concepts)
   25012                 :    83791709 :     auto_typeid_ok = (!parser->in_type_id_in_expr_p
   25013                 :    83791709 :                       && !parser->in_template_argument_list_p);
   25014                 :             : 
   25015                 :   306109512 :   if (type_specifier_seq.type
   25016                 :   303371471 :       && !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                 :   295743297 :       && !(cxx_dialect >= cxx14 && is_trailing_return))
   25020                 :   293867384 :     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                 :         204 :         if (abstract_declarator
   25028                 :          77 :             && abstract_declarator->kind == cdk_function
   25029                 :          26 :             && abstract_declarator->u.function.late_return_type)
   25030                 :             :           /* OK */;
   25031                 :         186 :         else if (parser->in_result_type_constraint_p)
   25032                 :             :           /* OK */;
   25033                 :             :         else
   25034                 :             :           {
   25035                 :         130 :             if (!cp_parser_simulate_error (parser))
   25036                 :             :               {
   25037                 :          56 :                 location_t loc = type_specifier_seq.locations[ds_type_spec];
   25038                 :          56 :                 if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
   25039                 :             :                   {
   25040                 :           0 :                     auto_diagnostic_group g;
   25041                 :           0 :                     gcc_rich_location richloc (loc);
   25042                 :           0 :                     richloc.add_fixit_insert_after ("<>");
   25043                 :           0 :                     error_at (&richloc, "missing template arguments after %qE",
   25044                 :             :                               tmpl);
   25045                 :           0 :                     inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
   25046                 :             :                             tmpl);
   25047                 :           0 :                   }
   25048                 :          56 :                 else if (parser->in_template_argument_list_p)
   25049                 :           0 :                   error_at (loc, "%qT not permitted in template argument",
   25050                 :             :                             auto_node);
   25051                 :             :                 else
   25052                 :          56 :                   error_at (loc, "invalid use of %qT", auto_node);
   25053                 :             :               }
   25054                 :         186 :             return error_mark_node;
   25055                 :             :           }
   25056                 :             :       }
   25057                 :             : 
   25058                 :   306109326 :   return groktypename (&type_specifier_seq, abstract_declarator,
   25059                 :   306109326 :                        is_template_arg);
   25060                 :             : }
   25061                 :             : 
   25062                 :             : /* Wrapper for cp_parser_type_id_1.  */
   25063                 :             : 
   25064                 :             : static tree
   25065                 :    46768982 : cp_parser_type_id (cp_parser *parser, cp_parser_flags flags,
   25066                 :             :                    location_t *type_location)
   25067                 :             : {
   25068                 :    43368956 :   return cp_parser_type_id_1 (parser, flags, false, false, type_location);
   25069                 :             : }
   25070                 :             : 
   25071                 :             : /* Wrapper for cp_parser_type_id_1.  */
   25072                 :             : 
   25073                 :             : static tree
   25074                 :   294951445 : cp_parser_template_type_arg (cp_parser *parser)
   25075                 :             : {
   25076                 :   294951445 :   const char *saved_message = parser->type_definition_forbidden_message;
   25077                 :   294951445 :   parser->type_definition_forbidden_message
   25078                 :   294951445 :     = G_("types may not be defined in template arguments");
   25079                 :   294951445 :   tree r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE,
   25080                 :             :                                 /*is_template_arg=*/true,
   25081                 :             :                                 /*is_trailing_return=*/false, nullptr);
   25082                 :   294951445 :   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                 :   294951445 :   if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r))
   25086                 :             :     {
   25087                 :           4 :       error ("invalid use of %<auto%> in template argument");
   25088                 :           4 :       r = error_mark_node;
   25089                 :             :     }
   25090                 :   294951445 :   return r;
   25091                 :             : }
   25092                 :             : 
   25093                 :             : /* Wrapper for cp_parser_type_id_1.  */
   25094                 :             : 
   25095                 :             : static tree
   25096                 :     2862632 : cp_parser_trailing_type_id (cp_parser *parser)
   25097                 :             : {
   25098                 :     2862632 :   return cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
   25099                 :     2862632 :                               false, 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                 :             : 
   25122                 :             : static void
   25123                 :   347273818 : cp_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                 :   347273818 :   bool seen_type_specifier = false;
   25130                 :   347273818 :   cp_token *start_token = NULL;
   25131                 :             : 
   25132                 :             :   /* Clear the TYPE_SPECIFIER_SEQ.  */
   25133                 :   347273818 :   clear_decl_specs (type_specifier_seq);
   25134                 :             : 
   25135                 :   347273818 :   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                 :   347273818 :   if (is_trailing_return)
   25140                 :     2862632 :     flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;
   25141                 :             : 
   25142                 :             :   /* Parse the type-specifiers and attributes.  */
   25143                 :   676046806 :   while (true)
   25144                 :             :     {
   25145                 :   676046806 :       tree type_specifier;
   25146                 :   676046806 :       bool is_cv_qualifier;
   25147                 :             : 
   25148                 :             :       /* Check for attributes first.  */
   25149                 :   676046806 :       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                 :         658 :           if (seen_type_specifier && is_trailing_return
   25155                 :         658 :               && cp_next_tokens_can_be_gnu_attribute_p (parser))
   25156                 :             :             {
   25157                 :           6 :               size_t n = cp_parser_skip_attributes_opt (parser, 1);
   25158                 :           6 :               cp_token *tok = cp_lexer_peek_nth_token (parser->lexer, n);
   25159                 :           6 :               if (tok->type == CPP_SEMICOLON || tok->type == CPP_COMMA
   25160                 :             :                   || tok->type == CPP_EQ || tok->type == CPP_OPEN_BRACE)
   25161                 :             :                 break;
   25162                 :             :             }
   25163                 :         652 :           type_specifier_seq->attributes
   25164                 :         652 :             = attr_chainon (type_specifier_seq->attributes,
   25165                 :             :                             cp_parser_attributes_opt (parser));
   25166                 :         652 :           continue;
   25167                 :         652 :         }
   25168                 :             : 
   25169                 :             :       /* record the token of the beginning of the type specifier seq,
   25170                 :             :          for error reporting purposes*/
   25171                 :   676046148 :      if (!start_token)
   25172                 :             :        start_token = cp_lexer_peek_token (parser->lexer);
   25173                 :             : 
   25174                 :             :       /* Look for the type-specifier.  */
   25175                 :   676046148 :       type_specifier = cp_parser_type_specifier (parser,
   25176                 :             :                                                  flags,
   25177                 :             :                                                  type_specifier_seq,
   25178                 :             :                                                  /*is_declaration=*/false,
   25179                 :             :                                                  NULL,
   25180                 :             :                                                  &is_cv_qualifier);
   25181                 :   676046148 :       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                 :   347273812 :           if (!seen_type_specifier)
   25186                 :             :             {
   25187                 :             :               /* Set in_declarator_p to avoid skipping to the semicolon.  */
   25188                 :    31320148 :               int in_decl = parser->in_declarator_p;
   25189                 :    31320148 :               parser->in_declarator_p = true;
   25190                 :             : 
   25191                 :    62640396 :               if (cp_parser_uncommitted_to_tentative_parse_p (parser)
   25192                 :         218 :                   || !cp_parser_parse_and_diagnose_invalid_type_name (parser))
   25193                 :    31320030 :                 cp_parser_error (parser, "expected type-specifier");
   25194                 :             : 
   25195                 :    31320148 :               parser->in_declarator_p = in_decl;
   25196                 :             : 
   25197                 :    31320148 :               type_specifier_seq->type = error_mark_node;
   25198                 :    31320148 :               return;
   25199                 :             :             }
   25200                 :             :           /* If subsequent type-specifiers could not be found, the
   25201                 :             :              type-specifier-seq is complete.  */
   25202                 :             :           break;
   25203                 :             :         }
   25204                 :             : 
   25205                 :   328772336 :       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                 :   328772336 :       if (is_declaration && !is_cv_qualifier)
   25223                 :      470321 :         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                 :             : 
   25230                 :             : static bool
   25231                 :   264336133 : function_being_declared_is_template_p (cp_parser* parser)
   25232                 :             : {
   25233                 :   264336133 :   if (!current_template_parms || processing_template_parmlist)
   25234                 :             :     return false;
   25235                 :             : 
   25236                 :   164404774 :   if (parser->implicit_template_scope)
   25237                 :             :     return true;
   25238                 :             : 
   25239                 :   164278881 :   if (at_class_scope_p ()
   25240                 :   164278881 :       && TYPE_BEING_DEFINED (current_class_type))
   25241                 :    82455590 :     return parser->num_template_parameter_lists != 0;
   25242                 :             : 
   25243                 :    81823291 :   return ((int) parser->num_template_parameter_lists > template_class_depth
   25244                 :    81823291 :           (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                 :             : 
   25259                 :             : static tree
   25260                 :   166894569 : cp_parser_parameter_declaration_clause (cp_parser* parser,
   25261                 :             :                                         cp_parser_flags flags)
   25262                 :             : {
   25263                 :   166894569 :   tree parameters;
   25264                 :   166894569 :   cp_token *token;
   25265                 :   166894569 :   bool ellipsis_p;
   25266                 :             : 
   25267                 :   166894569 :   auto cleanup = make_temp_override
   25268                 :   166894569 :     (parser->auto_is_implicit_function_template_parm_p);
   25269                 :             : 
   25270                 :   166894569 :   if (!processing_specialization
   25271                 :   166351585 :       && !processing_template_parmlist
   25272                 :   166312841 :       && !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                 :   164403909 :       && parser->default_arg_ok_p)
   25276                 :   159868065 :     if (!current_function_decl
   25277                 :   163186354 :         || (current_class_type && LAMBDA_TYPE_P (current_class_type)))
   25278                 :   155152226 :       parser->auto_is_implicit_function_template_parm_p = true;
   25279                 :             : 
   25280                 :             :   /* Peek at the next token.  */
   25281                 :   166894569 :   token = cp_lexer_peek_token (parser->lexer);
   25282                 :             :   /* Check for trivial parameter-declaration-clauses.  */
   25283                 :   166894569 :   if (token->type == CPP_ELLIPSIS)
   25284                 :             :     {
   25285                 :             :       /* Consume the `...' token.  */
   25286                 :      250124 :       cp_lexer_consume_token (parser->lexer);
   25287                 :      250124 :       return NULL_TREE;
   25288                 :             :     }
   25289                 :   166644445 :   else if (token->type == CPP_CLOSE_PAREN)
   25290                 :             :     /* There are no parameters.  */
   25291                 :    29674984 :     return void_list_node;
   25292                 :             :   /* Check for `(void)', too, which is a special case.  */
   25293                 :   136969461 :   else if (token->keyword == RID_VOID
   25294                 :   136969461 :            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
   25295                 :             :                == CPP_CLOSE_PAREN))
   25296                 :             :     {
   25297                 :             :       /* Consume the `void' token.  */
   25298                 :     1113193 :       cp_lexer_consume_token (parser->lexer);
   25299                 :             :       /* There are no parameters.  */
   25300                 :     1113193 :       return explicit_void_list_node;
   25301                 :             :     }
   25302                 :             : 
   25303                 :             :   /* A vector of parameters that haven't been pushed yet.  */
   25304                 :   135856268 :   auto_vec<tree> pending_decls;
   25305                 :             : 
   25306                 :             :   /* Parse the parameter-declaration-list.  */
   25307                 :   135856268 :   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                 :   135856268 :   if (parameters == error_mark_node)
   25313                 :             :     return NULL_TREE;
   25314                 :             : 
   25315                 :             :   /* Peek at the next token.  */
   25316                 :   129305360 :   token = cp_lexer_peek_token (parser->lexer);
   25317                 :             :   /* If it's a `,', the clause should terminate with an ellipsis.  */
   25318                 :   129305360 :   if (token->type == CPP_COMMA)
   25319                 :             :     {
   25320                 :             :       /* Consume the `,'.  */
   25321                 :      483019 :       cp_lexer_consume_token (parser->lexer);
   25322                 :             :       /* Expect an ellipsis.  */
   25323                 :      483019 :       ellipsis_p
   25324                 :      483019 :         = (cp_parser_require (parser, CPP_ELLIPSIS, RT_ELLIPSIS) != NULL);
   25325                 :             :     }
   25326                 :             :   /* It might also be `...' if the optional trailing `,' was
   25327                 :             :      omitted.  */
   25328                 :   128822341 :   else if (token->type == CPP_ELLIPSIS)
   25329                 :             :     {
   25330                 :             :       /* Consume the `...' token.  */
   25331                 :      315246 :       cp_lexer_consume_token (parser->lexer);
   25332                 :             :       /* And remember that we saw it.  */
   25333                 :      315246 :       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                 :   129305360 :   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
   25344                 :             :     {
   25345                 :   129305177 :       for (tree p : pending_decls)
   25346                 :          16 :         pushdecl (p);
   25347                 :             : 
   25348                 :             :       /* Delayed checking of auto parameters.  */
   25349                 :   129305129 :       if (!parser->auto_is_implicit_function_template_parm_p
   25350                 :     4489757 :           && cxx_dialect >= cxx14)
   25351                 :    10735985 :         for (tree p = parameters; p; p = TREE_CHAIN (p))
   25352                 :     6316101 :           if (type_uses_auto (TREE_TYPE (TREE_VALUE (p))))
   25353                 :             :             {
   25354                 :          54 :               error_at (location_of (TREE_VALUE (p)),
   25355                 :             :                         "%<auto%> parameter not permitted in this context");
   25356                 :          54 :               TREE_TYPE (TREE_VALUE (p)) = error_mark_node;
   25357                 :             :             }
   25358                 :             :     }
   25359                 :             : 
   25360                 :             :   /* Finish the parameter list.  */
   25361                 :   129305360 :   if (!ellipsis_p)
   25362                 :   128507095 :     parameters = chainon (parameters, void_list_node);
   25363                 :             : 
   25364                 :             :   return parameters;
   25365                 :   135856268 : }
   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                 :             : 
   25380                 :             : static tree
   25381                 :   135856294 : cp_parser_parameter_declaration_list (cp_parser* parser,
   25382                 :             :                                       cp_parser_flags flags,
   25383                 :             :                                       auto_vec<tree> *pending_decls)
   25384                 :             : {
   25385                 :   135856294 :   tree parameters = NULL_TREE;
   25386                 :   135856294 :   tree *tail = &parameters;
   25387                 :   135856294 :   bool saved_in_unbraced_linkage_specification_p;
   25388                 :   135856294 :   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                 :   135856294 :   saved_in_unbraced_linkage_specification_p
   25394                 :   135856294 :     = parser->in_unbraced_linkage_specification_p;
   25395                 :   135856294 :   parser->in_unbraced_linkage_specification_p = false;
   25396                 :             : 
   25397                 :             :   /* Look for more parameters.  */
   25398                 :   366622916 :   while (true)
   25399                 :             :     {
   25400                 :   251239605 :       cp_parameter_declarator *parameter;
   25401                 :   251239605 :       tree decl = error_mark_node;
   25402                 :   251239605 :       bool parenthesized_p = false;
   25403                 :             : 
   25404                 :             :       /* Parse the parameter.  */
   25405                 :   251239605 :       parameter
   25406                 :   251239605 :         = 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                 :   251239605 :       deprecated_state = UNAVAILABLE_DEPRECATED_SUPPRESS;
   25413                 :             : 
   25414                 :   251239605 :       if (parameter && !cp_parser_error_occurred (parser))
   25415                 :             :         {
   25416                 :   489377652 :           decl = grokdeclarator (parameter->declarator,
   25417                 :             :                                  &parameter->decl_specifiers,
   25418                 :             :                                  PARM,
   25419                 :   244688826 :                                  parameter->default_argument != NULL_TREE,
   25420                 :             :                                  &parameter->decl_specifiers.attributes);
   25421                 :   244688826 :           if (decl != error_mark_node && parameter->loc != UNKNOWN_LOCATION)
   25422                 :   244688697 :             DECL_SOURCE_LOCATION (decl) = parameter->loc;
   25423                 :             :         }
   25424                 :             : 
   25425                 :   251239605 :       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                 :   251239605 :       if (decl == error_mark_node)
   25430                 :             :         {
   25431                 :     6550908 :           parameters = error_mark_node;
   25432                 :     6550908 :           break;
   25433                 :             :         }
   25434                 :             : 
   25435                 :   244688697 :       if (parameter->decl_specifiers.attributes)
   25436                 :      207743 :         cplus_decl_attributes (&decl,
   25437                 :             :                                parameter->decl_specifiers.attributes,
   25438                 :             :                                0);
   25439                 :   244688697 :       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                 :   205935781 :           if (pending_decls
   25458                 :   206229461 :               && 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                 :   206229492 :               && [parameters, decl] {
   25462                 :      354386 :                    for (tree p = parameters; p; p = TREE_CHAIN (p))
   25463                 :       60706 :                      if (DECL_NAME (decl) == DECL_NAME (TREE_VALUE (p)))
   25464                 :             :                        return true;
   25465                 :             :                    return false;
   25466                 :      293711 :                  }())
   25467                 :          31 :             pending_decls->safe_push (decl);
   25468                 :             :           else
   25469                 :   205935750 :             decl = pushdecl (decl);
   25470                 :             :         }
   25471                 :             : 
   25472                 :   244688697 :       if (decl != error_mark_node)
   25473                 :             :         {
   25474                 :   244688629 :           retrofit_lang_decl (decl);
   25475                 :   244688629 :           DECL_PARM_INDEX (decl) = ++index;
   25476                 :   244688629 :           DECL_PARM_LEVEL (decl) = function_parm_depth ();
   25477                 :             :         }
   25478                 :             : 
   25479                 :             :       /* Add the new parameter to the list.  */
   25480                 :   244688697 :       *tail = build_tree_list (parameter->default_argument, decl);
   25481                 :   244688697 :       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                 :   244688697 :       if (index == 1 || PARENTHESIZED_LIST_P (parameters))
   25487                 :   129430537 :         PARENTHESIZED_LIST_P (parameters) = parenthesized_p;
   25488                 :             : 
   25489                 :             :       /* Peek at the next token.  */
   25490                 :   244688697 :       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
   25491                 :             :           || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)
   25492                 :             :           /* These are for Objective-C++ */
   25493                 :             :           || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
   25494                 :             :           || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   25495                 :             :         /* The parameter-declaration-list is complete.  */
   25496                 :             :         break;
   25497                 :             :       else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   25498                 :             :         {
   25499                 :   115866330 :           cp_token *token;
   25500                 :             : 
   25501                 :             :           /* Peek at the next token.  */
   25502                 :   115866330 :           token = cp_lexer_peek_nth_token (parser->lexer, 2);
   25503                 :             :           /* If it's an ellipsis, then the list is complete.  */
   25504                 :   115866330 :           if (token->type == CPP_ELLIPSIS)
   25505                 :             :             break;
   25506                 :             :           /* Otherwise, there must be more parameters.  Consume the
   25507                 :             :              `,'.  */
   25508                 :   115383311 :           cp_lexer_consume_token (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                 :   115383311 :           if (!parser->in_template_argument_list_p
   25522                 :   115269951 :               && !parser->in_type_id_in_expr_p
   25523                 :   118870704 :               && 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                 :   118870704 :               && !parenthesized_p)
   25529                 :     3428404 :             cp_parser_commit_to_tentative_parse (parser);
   25530                 :             :         }
   25531                 :             :       else
   25532                 :             :         {
   25533                 :          80 :           cp_parser_error (parser, "expected %<,%> or %<...%>");
   25534                 :   135856416 :           if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
   25535                 :          42 :             cp_parser_skip_to_closing_parenthesis (parser,
   25536                 :             :                                                    /*recovering=*/true,
   25537                 :             :                                                    /*or_comma=*/false,
   25538                 :             :                                                    /*consume_paren=*/false);
   25539                 :             :           break;
   25540                 :             :         }
   25541                 :   115383311 :     }
   25542                 :             : 
   25543                 :   135856294 :   parser->in_unbraced_linkage_specification_p
   25544                 :   135856294 :     = 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                 :   135856294 :   if (cp_binding_level *its = parser->implicit_template_scope)
   25552                 :      187859 :     if (cp_binding_level *maybe_its = current_binding_level->level_chain)
   25553                 :             :       {
   25554                 :      187925 :         while (maybe_its->kind == sk_class)
   25555                 :          66 :           maybe_its = maybe_its->level_chain;
   25556                 :      187859 :         if (maybe_its == its)
   25557                 :             :           {
   25558                 :      187780 :             parser->implicit_template_parms = 0;
   25559                 :      187780 :             parser->implicit_template_scope = 0;
   25560                 :             :           }
   25561                 :             :       }
   25562                 :             : 
   25563                 :   135856294 :   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                 :             : 
   25585                 :             : static cp_parameter_declarator *
   25586                 :   264336067 : cp_parser_parameter_declaration (cp_parser *parser,
   25587                 :             :                                  cp_parser_flags flags,
   25588                 :             :                                  bool template_parm_p,
   25589                 :             :                                  bool *parenthesized_p)
   25590                 :             : {
   25591                 :   264336067 :   int declares_class_or_enum;
   25592                 :   264336067 :   cp_decl_specifier_seq decl_specifiers;
   25593                 :   264336067 :   cp_declarator *declarator;
   25594                 :   264336067 :   tree default_argument;
   25595                 :   264336067 :   cp_token *token = NULL, *declarator_token_start = NULL;
   25596                 :   264336067 :   const char *saved_message;
   25597                 :   264336067 :   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                 :   264336067 :   saved_message = parser->type_definition_forbidden_message;
   25610                 :   264336067 :   parser->type_definition_forbidden_message
   25611                 :   264336067 :     = G_("types may not be defined in parameter types");
   25612                 :             : 
   25613                 :   264336067 :   int template_parm_idx = (function_being_declared_is_template_p (parser) ?
   25614                 :   100963216 :                            TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
   25615                 :   264336067 :                                             (current_template_parms)) : 0);
   25616                 :             : 
   25617                 :             :   /* Parse the declaration-specifiers.  */
   25618                 :   264336067 :   cp_token *decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
   25619                 :   264336067 :   cp_parser_decl_specifier_seq (parser,
   25620                 :             :                                 flags | CP_PARSER_FLAGS_PARAMETER,
   25621                 :             :                                 &decl_specifiers,
   25622                 :             :                                 &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                 :   264336067 :   auto cleanup = make_temp_override
   25631                 :   264336067 :     (parser->auto_is_implicit_function_template_parm_p, false);
   25632                 :             : 
   25633                 :             :   /* Complain about missing 'typename' or other invalid type names.  */
   25634                 :   264336067 :   if (!decl_specifiers.any_type_specifiers_p
   25635                 :   264336067 :       && cp_parser_parse_and_diagnose_invalid_type_name (parser))
   25636                 :          29 :     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                 :   528672134 :   if (cp_parser_error_occurred (parser))
   25641                 :             :     {
   25642                 :     6540425 :       parser->type_definition_forbidden_message = saved_message;
   25643                 :     6540425 :       return NULL;
   25644                 :             :     }
   25645                 :             : 
   25646                 :             :   /* Peek at the next token.  */
   25647                 :   257795642 :   token = cp_lexer_peek_token (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                 :   257795642 :   if (token->type == CPP_CLOSE_PAREN
   25653                 :             :       || token->type == CPP_COMMA
   25654                 :             :       || token->type == CPP_EQ
   25655                 :             :       || token->type == CPP_GREATER)
   25656                 :             :     {
   25657                 :    21115448 :       declarator = NULL;
   25658                 :    21115448 :       if (parenthesized_p)
   25659                 :    19526560 :         *parenthesized_p = false;
   25660                 :             :     }
   25661                 :             :   /* Otherwise, there should be a declarator.  */
   25662                 :             :   else
   25663                 :             :     {
   25664                 :   236680194 :       bool saved_default_arg_ok_p = parser->default_arg_ok_p;
   25665                 :   236680194 :       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                 :   236680194 :       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                 :   235633642 :           && !parser->in_type_id_in_expr_p
   25680                 :   300843608 :           && cp_parser_uncommitted_to_tentative_parse_p (parser)
   25681                 :   300843608 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
   25682                 :             :         {
   25683                 :    63718580 :           if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   25684                 :             :             {
   25685                 :         169 :               if (decl_specifiers.type
   25686                 :         169 :                   && template_placeholder_p (decl_specifiers.type))
   25687                 :             :                 /* This is a CTAD expression, not a parameter declaration.  */
   25688                 :   236680196 :                 cp_parser_simulate_error (parser);
   25689                 :             :             }
   25690                 :             :           else
   25691                 :    63718411 :             cp_parser_commit_to_tentative_parse (parser);
   25692                 :             :         }
   25693                 :             :       /* Parse the declarator.  */
   25694                 :   236680194 :       declarator_token_start = token;
   25695                 :   236680194 :       declarator = cp_parser_declarator (parser,
   25696                 :             :                                          CP_PARSER_DECLARATOR_EITHER,
   25697                 :             :                                          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                 :   236680194 :       parser->default_arg_ok_p = saved_default_arg_ok_p;
   25704                 :             :       /* After the declarator, allow more attributes.  */
   25705                 :   236680194 :       decl_specifiers.attributes
   25706                 :   236680194 :         = attr_chainon (decl_specifiers.attributes,
   25707                 :             :                         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                 :   236680194 :       if (template_parm_p && declarator && declarator->parameter_pack_p)
   25713                 :             :         {
   25714                 :      569013 :           declarator->parameter_pack_p = false;
   25715                 :      569013 :           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                 :   257795642 :   token = cp_lexer_peek_token (parser->lexer);
   25726                 :             : 
   25727                 :   257795642 :   bool xobj_param_p
   25728                 :   257795642 :     = decl_spec_seq_has_spec_p (&decl_specifiers, ds_this);
   25729                 :   257795642 :   if (xobj_param_p && template_parm_p)
   25730                 :             :     {
   25731                 :           8 :       error_at (decl_specifiers.locations[ds_this],
   25732                 :             :                 "%<this%> specifier in template parameter declaration");
   25733                 :           8 :       xobj_param_p = false;
   25734                 :           8 :       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                 :   257795642 :   if (parser->implicit_template_parms
   25741                 :   257795642 :       && ((token->type == CPP_ELLIPSIS
   25742                 :          99 :            && declarator_can_be_parameter_pack (declarator))
   25743                 :      313515 :           || (declarator && declarator->parameter_pack_p)))
   25744                 :             :     {
   25745                 :       30191 :       int latest_template_parm_idx = TREE_VEC_LENGTH
   25746                 :             :         (INNERMOST_TEMPLATE_PARMS (current_template_parms));
   25747                 :             : 
   25748                 :       30191 :       if (latest_template_parm_idx != template_parm_idx)
   25749                 :       30188 :         decl_specifiers.type
   25750                 :       30188 :           = convert_generic_types_to_packs (decl_specifiers.type,
   25751                 :             :                                             template_parm_idx,
   25752                 :             :                                             latest_template_parm_idx);
   25753                 :             :     }
   25754                 :             : 
   25755                 :   257795642 :   if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   25756                 :             :     {
   25757                 :     1351806 :       tree type = decl_specifiers.type;
   25758                 :             : 
   25759                 :     1351806 :       if (type && DECL_P (type))
   25760                 :     1331841 :         type = TREE_TYPE (type);
   25761                 :             : 
   25762                 :     1331841 :       if (((type
   25763                 :     1351794 :             && TREE_CODE (type) != TYPE_PACK_EXPANSION
   25764                 :     1351794 :             && (template_parm_p || uses_parameter_packs (type)))
   25765                 :         121 :            || (!type && template_parm_p))
   25766                 :     2683538 :           && declarator_can_be_parameter_pack (declarator))
   25767                 :             :         {
   25768                 :             :           /* Consume the `...'. */
   25769                 :     1351697 :           cp_lexer_consume_token (parser->lexer);
   25770                 :     1351697 :           maybe_warn_variadic_templates ();
   25771                 :             : 
   25772                 :             :           /* Build a pack expansion type */
   25773                 :     1351697 :           if (template_parm_p)
   25774                 :             :             template_parameter_pack_p = true;
   25775                 :     1338406 :           else if (declarator)
   25776                 :      131158 :             declarator->parameter_pack_p = true;
   25777                 :             :           else
   25778                 :     1207248 :             decl_specifiers.type = make_pack_expansion (type);
   25779                 :             :         }
   25780                 :             :     }
   25781                 :             : 
   25782                 :   257795642 :   if (xobj_param_p
   25783                 :        9383 :       && (declarator ? declarator->parameter_pack_p
   25784                 :         324 :                      : PACK_EXPANSION_P (decl_specifiers.type)))
   25785                 :             :     {
   25786                 :          80 :       location_t xobj_param
   25787                 :          80 :         = make_location (decl_specifiers.locations[ds_this],
   25788                 :             :                          decl_spec_token_start->location,
   25789                 :             :                          input_location);
   25790                 :          80 :       error_at (xobj_param,
   25791                 :             :                 "an explicit object parameter cannot "
   25792                 :             :                 "be a function parameter pack");
   25793                 :          80 :       xobj_param_p = false;
   25794                 :          80 :       decl_specifiers.locations[ds_this] = 0;
   25795                 :             :     }
   25796                 :             : 
   25797                 :             :   /* The restriction on defining new types applies only to the type
   25798                 :             :      of the parameter, not to the default argument.  */
   25799                 :   257795642 :   parser->type_definition_forbidden_message = saved_message;
   25800                 :   257795642 :   cp_token *eq_token = NULL;
   25801                 :             :   /* If the next token is `=', then process a default argument.  */
   25802                 :   257795642 :   if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   25803                 :             :     {
   25804                 :     9108778 :       tree type = decl_specifiers.type;
   25805                 :     9108778 :       token = cp_lexer_peek_token (parser->lexer);
   25806                 :             :       /* Used for diagnostics with an xobj parameter.  */
   25807                 :     9108778 :       eq_token = token;
   25808                 :     9108778 :       if (declarator)
   25809                 :     7209408 :         declarator->init_loc = token->location;
   25810                 :             :       /* If we are defining a class, then the tokens that make up the
   25811                 :             :          default argument must be saved and processed later.  */
   25812                 :     6997128 :       if (!template_parm_p && at_class_scope_p ()
   25813                 :     5501946 :           && TYPE_BEING_DEFINED (current_class_type)
   25814                 :    20112384 :           && !LAMBDA_TYPE_P (current_class_type))
   25815                 :     5501768 :         default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false);
   25816                 :             : 
   25817                 :             :       /* A constrained-type-specifier may declare a type
   25818                 :             :          template-parameter.  */
   25819                 :     3607010 :       else if (declares_constrained_type_template_parameter (type))
   25820                 :      101212 :         default_argument
   25821                 :      101212 :           = cp_parser_default_type_template_argument (parser);
   25822                 :             : 
   25823                 :             :       /* A constrained-type-specifier may declare a
   25824                 :             :          template-template-parameter.  */
   25825                 :     3505798 :       else if (declares_constrained_template_template_parameter (type))
   25826                 :           1 :         default_argument
   25827                 :           1 :           = cp_parser_default_template_template_argument (parser);
   25828                 :             : 
   25829                 :             :       /* Outside of a class definition, we can just parse the
   25830                 :             :          assignment-expression.  */
   25831                 :             :       else
   25832                 :     3505797 :         default_argument
   25833                 :     3505797 :           = cp_parser_default_argument (parser, template_parm_p);
   25834                 :             : 
   25835                 :     9108778 :       if (!parser->default_arg_ok_p)
   25836                 :             :         {
   25837                 :           8 :           permerror (token->location,
   25838                 :             :                      "default arguments are only "
   25839                 :             :                      "permitted for function parameters");
   25840                 :             :         }
   25841                 :     9108770 :       else if ((declarator && declarator->parameter_pack_p)
   25842                 :     9108767 :                || template_parameter_pack_p
   25843                 :     9108757 :                || (decl_specifiers.type
   25844                 :     9044052 :                    && PACK_EXPANSION_P (decl_specifiers.type)))
   25845                 :             :         {
   25846                 :             :           /* Find the name of the parameter pack.  */
   25847                 :             :           cp_declarator *id_declarator = declarator;
   25848                 :          22 :           while (id_declarator && id_declarator->kind != cdk_id)
   25849                 :           6 :             id_declarator = id_declarator->declarator;
   25850                 :             : 
   25851                 :          16 :           if (id_declarator && id_declarator->kind == cdk_id)
   25852                 :          11 :             error_at (declarator_token_start->location,
   25853                 :             :                       template_parm_p
   25854                 :             :                       ? G_("template parameter pack %qD "
   25855                 :             :                            "cannot have a default argument")
   25856                 :             :                       : G_("parameter pack %qD cannot have "
   25857                 :             :                            "a default argument"),
   25858                 :             :                       id_declarator->u.id.unqualified_name);
   25859                 :             :           else
   25860                 :          11 :             error_at (declarator_token_start->location,
   25861                 :             :                       template_parm_p
   25862                 :             :                       ? G_("template parameter pack cannot have "
   25863                 :             :                            "a default argument")
   25864                 :             :                       : G_("parameter pack cannot have a "
   25865                 :             :                            "default argument"));
   25866                 :             : 
   25867                 :             :           default_argument = NULL_TREE;
   25868                 :             :         }
   25869                 :             :     }
   25870                 :             :   else
   25871                 :             :     default_argument = NULL_TREE;
   25872                 :             : 
   25873                 :     9108762 :   if (default_argument)
   25874                 :     9108762 :     STRIP_ANY_LOCATION_WRAPPER (default_argument);
   25875                 :             : 
   25876                 :   257795642 :   if (xobj_param_p)
   25877                 :             :     {
   25878                 :        8979 :       if (default_argument)
   25879                 :             :         {
   25880                 :             :           /* If there is a default_argument, eq_token should always be set.  */
   25881                 :          12 :           gcc_assert (eq_token);
   25882                 :          12 :           location_t param_with_init_loc
   25883                 :          12 :             = make_location (eq_token->location,
   25884                 :             :                              decl_spec_token_start->location,
   25885                 :             :                              input_location);
   25886                 :          12 :           error_at (param_with_init_loc,
   25887                 :             :                     "an explicit object parameter "
   25888                 :             :                     "may not have a default argument");
   25889                 :             :         }
   25890                 :             :       /* Xobj parameters can not have default arguments, thus
   25891                 :             :          we can reuse the default argument field to flag the param as such.  */
   25892                 :        8979 :       default_argument = this_identifier;
   25893                 :             :     }
   25894                 :             : 
   25895                 :             :   /* Generate a location for the parameter, ranging from the start of the
   25896                 :             :      initial token to the end of the final token (using input_location for
   25897                 :             :      the latter, set up by cp_lexer_set_source_position_from_token when
   25898                 :             :      consuming tokens).
   25899                 :             : 
   25900                 :             :      If we have a identifier, then use it for the caret location, e.g.
   25901                 :             : 
   25902                 :             :        extern int callee (int one, int (*two)(int, int), float three);
   25903                 :             :                                    ~~~~~~^~~~~~~~~~~~~~
   25904                 :             : 
   25905                 :             :      otherwise, reuse the start location for the caret location e.g.:
   25906                 :             : 
   25907                 :             :        extern int callee (int one, int (*)(int, int), float three);
   25908                 :             :                                    ^~~~~~~~~~~~~~~~~
   25909                 :             : 
   25910                 :             :   */
   25911                 :   235459387 :   location_t caret_loc = (declarator && declarator->id_loc != UNKNOWN_LOCATION
   25912                 :   276055967 :                           ? declarator->id_loc
   25913                 :             :                           : decl_spec_token_start->location);
   25914                 :   257795642 :   location_t param_loc = make_location (caret_loc,
   25915                 :             :                                         decl_spec_token_start->location,
   25916                 :             :                                         input_location);
   25917                 :             : 
   25918                 :   257795642 :   return make_parameter_declarator (&decl_specifiers,
   25919                 :             :                                     declarator,
   25920                 :             :                                     default_argument,
   25921                 :             :                                     param_loc,
   25922                 :   257795642 :                                     template_parameter_pack_p);
   25923                 :   264336067 : }
   25924                 :             : 
   25925                 :             : /* Parse a default argument and return it.
   25926                 :             : 
   25927                 :             :    TEMPLATE_PARM_P is true if this is a default argument for a
   25928                 :             :    non-type template parameter.  */
   25929                 :             : static tree
   25930                 :     3505797 : cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
   25931                 :             : {
   25932                 :     3505797 :   tree default_argument = NULL_TREE;
   25933                 :     3505797 :   bool saved_greater_than_is_operator_p;
   25934                 :     3505797 :   unsigned char saved_local_variables_forbidden_p;
   25935                 :             : 
   25936                 :             :   /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
   25937                 :             :      set correctly.  */
   25938                 :     3505797 :   saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
   25939                 :     3505797 :   parser->greater_than_is_operator_p = !template_parm_p;
   25940                 :     3505797 :   auto odsd = make_temp_override (parser->omp_declare_simd, NULL);
   25941                 :     3505797 :   auto ord = make_temp_override (parser->oacc_routine, NULL);
   25942                 :     3505797 :   auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false);
   25943                 :             : 
   25944                 :             :   /* Local variable names (and the `this' keyword) may not
   25945                 :             :      appear in a default argument.  */
   25946                 :     3505797 :   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
   25947                 :     3505797 :   parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
   25948                 :             :   /* Parse the assignment-expression.  */
   25949                 :     3505797 :   if (template_parm_p)
   25950                 :     2010437 :     push_deferring_access_checks (dk_no_deferred);
   25951                 :     3505797 :   tree saved_class_ptr = NULL_TREE;
   25952                 :     3505797 :   tree saved_class_ref = NULL_TREE;
   25953                 :             :   /* The "this" pointer is not valid in a default argument.  */
   25954                 :     3505797 :   if (cfun)
   25955                 :             :     {
   25956                 :          82 :       saved_class_ptr = current_class_ptr;
   25957                 :          82 :       cp_function_chain->x_current_class_ptr = NULL_TREE;
   25958                 :          82 :       saved_class_ref = current_class_ref;
   25959                 :          82 :       cp_function_chain->x_current_class_ref = NULL_TREE;
   25960                 :             :     }
   25961                 :     3505797 :   default_argument = cp_parser_initializer (parser);
   25962                 :             :   /* Restore the "this" pointer.  */
   25963                 :     3505797 :   if (cfun)
   25964                 :             :     {
   25965                 :          82 :       cp_function_chain->x_current_class_ptr = saved_class_ptr;
   25966                 :          82 :       cp_function_chain->x_current_class_ref = saved_class_ref;
   25967                 :             :     }
   25968                 :     3505797 :   if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
   25969                 :       84754 :     maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   25970                 :     3505797 :   if (template_parm_p)
   25971                 :     2010437 :     pop_deferring_access_checks ();
   25972                 :     3505797 :   parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
   25973                 :     3505797 :   parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
   25974                 :             : 
   25975                 :     3505797 :   return default_argument;
   25976                 :     3505797 : }
   25977                 :             : 
   25978                 :             : /* Parse a function-body.
   25979                 :             : 
   25980                 :             :    function-body:
   25981                 :             :      compound_statement  */
   25982                 :             : 
   25983                 :             : static void
   25984                 :    98549646 : cp_parser_function_body (cp_parser *parser, bool in_function_try_block)
   25985                 :             : {
   25986                 :   196570291 :   cp_parser_compound_statement (parser, NULL, (in_function_try_block
   25987                 :             :                                                ? BCS_TRY_BLOCK : BCS_NORMAL),
   25988                 :             :                                 true);
   25989                 :    98020940 : }
   25990                 :             : 
   25991                 :             : /* Parse a ctor-initializer-opt followed by a function-body.  Return
   25992                 :             :    true if a ctor-initializer was present.  When IN_FUNCTION_TRY_BLOCK
   25993                 :             :    is true we are parsing a function-try-block.  */
   25994                 :             : 
   25995                 :             : static void
   25996                 :    98020965 : cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
   25997                 :             :                                                   bool in_function_try_block)
   25998                 :             : {
   25999                 :    98020965 :   tree body, list;
   26000                 :    98020965 :   const bool check_body_p
   26001                 :    98020965 :      = (DECL_CONSTRUCTOR_P (current_function_decl)
   26002                 :    98020965 :         && DECL_DECLARED_CONSTEXPR_P (current_function_decl));
   26003                 :    98020965 :   tree last = NULL;
   26004                 :             : 
   26005                 :    98020965 :   if (in_function_try_block
   26006                 :         320 :       && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
   26007                 :    98021019 :       && cxx_dialect < cxx20)
   26008                 :             :     {
   26009                 :          36 :       if (DECL_CONSTRUCTOR_P (current_function_decl))
   26010                 :          18 :         pedwarn (input_location, OPT_Wc__20_extensions,
   26011                 :             :                  "function-try-block body of %<constexpr%> constructor only "
   26012                 :             :                  "available with %<-std=c++20%> or %<-std=gnu++20%>");
   26013                 :             :       else
   26014                 :          18 :         pedwarn (input_location, OPT_Wc__20_extensions,
   26015                 :             :                  "function-try-block body of %<constexpr%> function only "
   26016                 :             :                  "available with %<-std=c++20%> or %<-std=gnu++20%>");
   26017                 :             :     }
   26018                 :             : 
   26019                 :             :   /* Begin the function body.  */
   26020                 :    98020965 :   body = begin_function_body ();
   26021                 :             :   /* Parse the optional ctor-initializer.  */
   26022                 :    98020965 :   cp_parser_ctor_initializer_opt (parser);
   26023                 :             : 
   26024                 :             :   /* If we're parsing a constexpr constructor definition, we need
   26025                 :             :      to check that the constructor body is indeed empty.  However,
   26026                 :             :      before we get to cp_parser_function_body lot of junk has been
   26027                 :             :      generated, so we can't just check that we have an empty block.
   26028                 :             :      Rather we take a snapshot of the outermost block, and check whether
   26029                 :             :      cp_parser_function_body changed its state.  */
   26030                 :    98020965 :   if (check_body_p)
   26031                 :             :     {
   26032                 :     2837380 :       list = cur_stmt_list;
   26033                 :     2837380 :       if (STATEMENT_LIST_TAIL (list))
   26034                 :     2782910 :         last = STATEMENT_LIST_TAIL (list)->stmt;
   26035                 :             :     }
   26036                 :             :   /* Parse the function-body.  */
   26037                 :    98020965 :   cp_parser_function_body (parser, in_function_try_block);
   26038                 :    98020940 :   if (check_body_p)
   26039                 :     2837380 :     check_constexpr_ctor_body (last, list, /*complain=*/true);
   26040                 :             :   /* Finish the function body.  */
   26041                 :    98020940 :   finish_function_body (body);
   26042                 :    98020940 : }
   26043                 :             : 
   26044                 :             : /* Parse an initializer.
   26045                 :             : 
   26046                 :             :    initializer:
   26047                 :             :      = initializer-clause
   26048                 :             :      ( expression-list )
   26049                 :             : 
   26050                 :             :    Returns an expression representing the initializer.  If no
   26051                 :             :    initializer is present, NULL_TREE is returned.
   26052                 :             : 
   26053                 :             :    *IS_DIRECT_INIT is set to FALSE if the `= initializer-clause'
   26054                 :             :    production is used, and TRUE otherwise.  *IS_DIRECT_INIT is
   26055                 :             :    set to TRUE if there is no initializer present.  If there is an
   26056                 :             :    initializer, and it is not a constant-expression, *NON_CONSTANT_P
   26057                 :             :    is set to true; otherwise it is set to false.  */
   26058                 :             : 
   26059                 :             : static tree
   26060                 :    54046693 : cp_parser_initializer (cp_parser *parser, bool *is_direct_init /*=nullptr*/,
   26061                 :             :                        bool *non_constant_p /*=nullptr*/, bool subexpression_p)
   26062                 :             : {
   26063                 :    54046693 :   cp_token *token;
   26064                 :    54046693 :   tree init;
   26065                 :             : 
   26066                 :             :   /* Peek at the next token.  */
   26067                 :    54046693 :   token = cp_lexer_peek_token (parser->lexer);
   26068                 :             : 
   26069                 :             :   /* Let our caller know whether or not this initializer was
   26070                 :             :      parenthesized.  */
   26071                 :    54046693 :   if (is_direct_init)
   26072                 :    44167521 :     *is_direct_init = (token->type != CPP_EQ);
   26073                 :             :   /* Assume that the initializer is constant.  */
   26074                 :    54046693 :   if (non_constant_p)
   26075                 :    44168291 :     *non_constant_p = false;
   26076                 :             : 
   26077                 :    54046693 :   if (token->type == CPP_EQ)
   26078                 :             :     {
   26079                 :             :       /* Consume the `='.  */
   26080                 :    48538591 :       cp_lexer_consume_token (parser->lexer);
   26081                 :             :       /* Parse the initializer-clause.  */
   26082                 :    48538591 :       init = cp_parser_initializer_clause (parser, non_constant_p);
   26083                 :             :     }
   26084                 :     5508102 :   else if (token->type == CPP_OPEN_PAREN)
   26085                 :             :     {
   26086                 :     4423575 :       vec<tree, va_gc> *vec;
   26087                 :     4423575 :       vec = cp_parser_parenthesized_expression_list (parser, non_attr,
   26088                 :             :                                                      /*cast_p=*/false,
   26089                 :             :                                                      /*allow_expansion_p=*/true,
   26090                 :             :                                                      non_constant_p);
   26091                 :     4423575 :       if (vec == NULL)
   26092                 :          14 :         return error_mark_node;
   26093                 :     4423561 :       init = build_tree_list_vec (vec);
   26094                 :     4423561 :       release_tree_vector (vec);
   26095                 :             :     }
   26096                 :     1084527 :   else if (token->type == CPP_OPEN_BRACE)
   26097                 :             :     {
   26098                 :     1084527 :       cp_lexer_set_source_position (parser->lexer);
   26099                 :     1084527 :       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   26100                 :     1084527 :       init = cp_parser_braced_list (parser, non_constant_p);
   26101                 :     1084527 :       CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
   26102                 :             :     }
   26103                 :             :   else
   26104                 :             :     {
   26105                 :             :       /* Anything else is an error.  */
   26106                 :           0 :       cp_parser_error (parser, "expected initializer");
   26107                 :           0 :       init = error_mark_node;
   26108                 :             :     }
   26109                 :             : 
   26110                 :    54046676 :   if (!subexpression_p && check_for_bare_parameter_packs (init))
   26111                 :          16 :     init = error_mark_node;
   26112                 :             : 
   26113                 :             :   return init;
   26114                 :             : }
   26115                 :             : 
   26116                 :             : /* Parse an initializer-clause.
   26117                 :             : 
   26118                 :             :    initializer-clause:
   26119                 :             :      assignment-expression
   26120                 :             :      braced-init-list
   26121                 :             : 
   26122                 :             :    Returns an expression representing the initializer.
   26123                 :             : 
   26124                 :             :    If the `assignment-expression' production is used the value
   26125                 :             :    returned is simply a representation for the expression.
   26126                 :             : 
   26127                 :             :    Otherwise, calls cp_parser_braced_list.  */
   26128                 :             : 
   26129                 :             : static cp_expr
   26130                 :   113206670 : cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
   26131                 :             : {
   26132                 :   113206670 :   cp_expr initializer;
   26133                 :             : 
   26134                 :             :   /* Assume the expression is constant.  */
   26135                 :   113206670 :   if (non_constant_p)
   26136                 :    48510896 :     *non_constant_p = false;
   26137                 :             : 
   26138                 :             :   /* If it is not a `{', then we are looking at an
   26139                 :             :      assignment-expression.  */
   26140                 :   113206670 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
   26141                 :             :     {
   26142                 :   110387805 :       initializer
   26143                 :   110387805 :         = cp_parser_constant_expression (parser,
   26144                 :             :                                         /*allow_non_constant_p=*/2,
   26145                 :             :                                         non_constant_p);
   26146                 :             :     }
   26147                 :             :   else
   26148                 :     2818865 :     initializer = cp_parser_braced_list (parser, non_constant_p);
   26149                 :             : 
   26150                 :   113206664 :   return initializer;
   26151                 :             : }
   26152                 :             : 
   26153                 :             : /* Parse a brace-enclosed initializer list.
   26154                 :             : 
   26155                 :             :    braced-init-list:
   26156                 :             :      { initializer-list , [opt] }
   26157                 :             :      { designated-initializer-list , [opt] }
   26158                 :             :      { }
   26159                 :             : 
   26160                 :             :    Returns a CONSTRUCTOR.  The CONSTRUCTOR_ELTS will be
   26161                 :             :    the elements of the initializer-list (or NULL, if the last
   26162                 :             :    production is used).  The TREE_TYPE for the CONSTRUCTOR will be
   26163                 :             :    NULL_TREE.  There is no way to detect whether or not the optional
   26164                 :             :    trailing `,' was provided.  NON_CONSTANT_P is as for
   26165                 :             :    cp_parser_initializer.  */
   26166                 :             : 
   26167                 :             : static cp_expr
   26168                 :     8842725 : cp_parser_braced_list (cp_parser *parser, bool *non_constant_p /*=nullptr*/)
   26169                 :             : {
   26170                 :     8842725 :   tree initializer;
   26171                 :     8842725 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   26172                 :     8842725 :   auto oas = make_temp_override (parser->omp_array_section_p, false);
   26173                 :             : 
   26174                 :             :   /* Consume the `{' token.  */
   26175                 :     8842725 :   matching_braces braces;
   26176                 :     8842725 :   braces.require_open (parser);
   26177                 :             :   /* Create a CONSTRUCTOR to represent the braced-initializer.  */
   26178                 :     8842725 :   initializer = make_node (CONSTRUCTOR);
   26179                 :             :   /* If it's not a `}', then there is a non-trivial initializer.  */
   26180                 :     8842725 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
   26181                 :             :     {
   26182                 :     4948345 :       bool designated;
   26183                 :             :       /* Parse the initializer list.  */
   26184                 :     9896690 :       CONSTRUCTOR_ELTS (initializer)
   26185                 :     4948345 :         = cp_parser_initializer_list (parser, non_constant_p, &designated);
   26186                 :     4948345 :       CONSTRUCTOR_IS_DESIGNATED_INIT (initializer) = designated;
   26187                 :             :       /* A trailing `,' token is allowed.  */
   26188                 :     4948345 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   26189                 :       62037 :         cp_lexer_consume_token (parser->lexer);
   26190                 :             :     }
   26191                 :     3894380 :   else if (non_constant_p)
   26192                 :      621036 :     *non_constant_p = false;
   26193                 :             :   /* Now, there should be a trailing `}'.  */
   26194                 :     8842725 :   location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
   26195                 :     8842725 :   braces.require_close (parser);
   26196                 :     8842725 :   TREE_TYPE (initializer) = init_list_type_node;
   26197                 :     8842725 :   recompute_constructor_flags (initializer);
   26198                 :             : 
   26199                 :     8842725 :   cp_expr result (initializer);
   26200                 :             :   /* Build a location of the form:
   26201                 :             :        { ... }
   26202                 :             :        ^~~~~~~
   26203                 :             :      with caret==start at the open brace, finish at the close brace.  */
   26204                 :     8842725 :   location_t combined_loc = make_location (start_loc, start_loc, finish_loc);
   26205                 :     8842725 :   result.set_location (combined_loc);
   26206                 :     8842725 :   return result;
   26207                 :     8842725 : }
   26208                 :             : 
   26209                 :             : /* Consume tokens up to, but not including, the next non-nested closing `]'.
   26210                 :             :    Returns true iff we found a closing `]'.  */
   26211                 :             : 
   26212                 :             : static bool
   26213                 :         259 : cp_parser_skip_up_to_closing_square_bracket (cp_parser *parser)
   26214                 :             : {
   26215                 :         259 :   unsigned square_depth = 0;
   26216                 :             : 
   26217                 :         789 :   while (true)
   26218                 :             :     {
   26219                 :         524 :       cp_token * token = cp_lexer_peek_token (parser->lexer);
   26220                 :             : 
   26221                 :         524 :       switch (token->type)
   26222                 :             :         {
   26223                 :           0 :         case CPP_PRAGMA_EOL:
   26224                 :           0 :           if (!parser->lexer->in_pragma)
   26225                 :             :             break;
   26226                 :             :           /* FALLTHRU */
   26227                 :             : 
   26228                 :             :         case CPP_EOF:
   26229                 :             :           /* If we've run out of tokens, then there is no closing `]'.  */
   26230                 :             :           return false;
   26231                 :             : 
   26232                 :           0 :         case CPP_OPEN_SQUARE:
   26233                 :           0 :           ++square_depth;
   26234                 :           0 :           break;
   26235                 :             : 
   26236                 :         259 :         case CPP_CLOSE_SQUARE:
   26237                 :         259 :           if (!square_depth--)
   26238                 :             :             return true;
   26239                 :             :           break;
   26240                 :             : 
   26241                 :             :         default:
   26242                 :             :           break;
   26243                 :             :         }
   26244                 :             : 
   26245                 :             :       /* Consume the current token, skipping it.  */
   26246                 :         265 :       cp_lexer_consume_token (parser->lexer);
   26247                 :         265 :     }
   26248                 :             : }
   26249                 :             : 
   26250                 :             : /* Consume tokens up to, and including, the next non-nested closing `]'.
   26251                 :             :    Returns true iff we found a closing `]'.  */
   26252                 :             : 
   26253                 :             : static bool
   26254                 :         248 : cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
   26255                 :             : {
   26256                 :         248 :   bool found = cp_parser_skip_up_to_closing_square_bracket (parser);
   26257                 :         248 :   if (found)
   26258                 :         248 :     cp_lexer_consume_token (parser->lexer);
   26259                 :         248 :   return found;
   26260                 :             : }
   26261                 :             : 
   26262                 :             : /* Return true if we are looking at an array-designator, false otherwise.  */
   26263                 :             : 
   26264                 :             : static bool
   26265                 :         242 : cp_parser_array_designator_p (cp_parser *parser)
   26266                 :             : {
   26267                 :             :   /* Consume the `['.  */
   26268                 :         242 :   cp_lexer_consume_token (parser->lexer);
   26269                 :             : 
   26270                 :         242 :   cp_lexer_save_tokens (parser->lexer);
   26271                 :             : 
   26272                 :             :   /* Skip tokens until the next token is a closing square bracket.
   26273                 :             :      If we find the closing `]', and the next token is a `=', then
   26274                 :             :      we are looking at an array designator.  */
   26275                 :         242 :   bool array_designator_p
   26276                 :         242 :     = (cp_parser_skip_to_closing_square_bracket (parser)
   26277                 :         242 :        && cp_lexer_next_token_is (parser->lexer, CPP_EQ));
   26278                 :             : 
   26279                 :             :   /* Roll back the tokens we skipped.  */
   26280                 :         242 :   cp_lexer_rollback_tokens (parser->lexer);
   26281                 :             : 
   26282                 :         242 :   return array_designator_p;
   26283                 :             : }
   26284                 :             : 
   26285                 :             : /* Parse an initializer-list.
   26286                 :             : 
   26287                 :             :    initializer-list:
   26288                 :             :      initializer-clause ... [opt]
   26289                 :             :      initializer-list , initializer-clause ... [opt]
   26290                 :             : 
   26291                 :             :    C++20 Extension:
   26292                 :             : 
   26293                 :             :    designated-initializer-list:
   26294                 :             :      designated-initializer-clause
   26295                 :             :      designated-initializer-list , designated-initializer-clause
   26296                 :             : 
   26297                 :             :    designated-initializer-clause:
   26298                 :             :      designator brace-or-equal-initializer
   26299                 :             : 
   26300                 :             :    designator:
   26301                 :             :      . identifier
   26302                 :             : 
   26303                 :             :    GNU Extension:
   26304                 :             : 
   26305                 :             :    initializer-list:
   26306                 :             :      designation initializer-clause ...[opt]
   26307                 :             :      initializer-list , designation initializer-clause ...[opt]
   26308                 :             : 
   26309                 :             :    designation:
   26310                 :             :      . identifier =
   26311                 :             :      identifier :
   26312                 :             :      [ constant-expression ] =
   26313                 :             : 
   26314                 :             :    Returns a vec of constructor_elt.  The VALUE of each elt is an expression
   26315                 :             :    for the initializer.  If the INDEX of the elt is non-NULL, it is the
   26316                 :             :    IDENTIFIER_NODE naming the field to initialize.  NON_CONSTANT_P is
   26317                 :             :    as for cp_parser_initializer.  Set *DESIGNATED to a boolean whether there
   26318                 :             :    are any designators.  */
   26319                 :             : 
   26320                 :             : static vec<constructor_elt, va_gc> *
   26321                 :     4948345 : cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
   26322                 :             :                             bool *designated)
   26323                 :             : {
   26324                 :     4948345 :   vec<constructor_elt, va_gc> *v = NULL;
   26325                 :     4948345 :   bool first_p = true;
   26326                 :     4948345 :   tree first_designator = NULL_TREE;
   26327                 :             : 
   26328                 :             :   /* Assume all of the expressions are constant.  */
   26329                 :     4948345 :   if (non_constant_p)
   26330                 :      953287 :     *non_constant_p = false;
   26331                 :             : 
   26332                 :     4948345 :   unsigned nelts = 0;
   26333                 :     4948345 :   int suppress = suppress_location_wrappers;
   26334                 :             : 
   26335                 :             :   /* Parse the rest of the list.  */
   26336                 :    30870613 :   while (true)
   26337                 :             :     {
   26338                 :    17909479 :       cp_token *token;
   26339                 :    17909479 :       tree designator;
   26340                 :    17909479 :       tree initializer;
   26341                 :    17909479 :       bool clause_non_constant_p;
   26342                 :    17909479 :       bool direct_p = false;
   26343                 :    17909479 :       location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   26344                 :             : 
   26345                 :             :       /* Handle the C++20 syntax, '. id ='.  */
   26346                 :    17909479 :       if ((cxx_dialect >= cxx20
   26347                 :     6922432 :            || cp_parser_allow_gnu_extensions_p (parser))
   26348                 :    17909479 :           && cp_lexer_next_token_is (parser->lexer, CPP_DOT)
   26349                 :        3875 :           && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
   26350                 :    17913354 :           && (cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ
   26351                 :          13 :               || (cp_lexer_peek_nth_token (parser->lexer, 3)->type
   26352                 :             :                   == CPP_OPEN_BRACE)))
   26353                 :             :         {
   26354                 :        3875 :           if (pedantic && cxx_dialect < cxx20)
   26355                 :          71 :             pedwarn (loc, OPT_Wc__20_extensions,
   26356                 :             :                      "C++ designated initializers only available with "
   26357                 :             :                      "%<-std=c++20%> or %<-std=gnu++20%>");
   26358                 :             :           /* Consume the `.'.  */
   26359                 :        3875 :           cp_lexer_consume_token (parser->lexer);
   26360                 :             :           /* Consume the identifier.  */
   26361                 :        3875 :           designator = cp_lexer_consume_token (parser->lexer)->u.value;
   26362                 :        3875 :           if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   26363                 :             :             /* Consume the `='.  */
   26364                 :        3862 :             cp_lexer_consume_token (parser->lexer);
   26365                 :             :           else
   26366                 :             :             direct_p = true;
   26367                 :             :         }
   26368                 :             :       /* Also, if the next token is an identifier and the following one is a
   26369                 :             :          colon, we are looking at the GNU designated-initializer
   26370                 :             :          syntax.  */
   26371                 :    17905604 :       else if (cp_parser_allow_gnu_extensions_p (parser)
   26372                 :    17905604 :                && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   26373                 :     4600664 :                && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
   26374                 :             :                    == CPP_COLON))
   26375                 :             :         {
   26376                 :             :           /* Warn the user that they are using an extension.  */
   26377                 :         109 :           pedwarn (loc, OPT_Wpedantic,
   26378                 :             :                    "ISO C++ does not allow GNU designated initializers");
   26379                 :             :           /* Consume the identifier.  */
   26380                 :         109 :           designator = cp_lexer_consume_token (parser->lexer)->u.value;
   26381                 :             :           /* Consume the `:'.  */
   26382                 :         109 :           cp_lexer_consume_token (parser->lexer);
   26383                 :             :         }
   26384                 :             :       /* Also handle C99 array designators, '[ const ] ='.  */
   26385                 :    17905495 :       else if (cp_parser_allow_gnu_extensions_p (parser)
   26386                 :    17905495 :                && !c_dialect_objc ()
   26387                 :    35810990 :                && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
   26388                 :             :         {
   26389                 :             :           /* In C++11, [ could start a lambda-introducer.  */
   26390                 :         242 :           bool non_const = false;
   26391                 :             : 
   26392                 :         242 :           cp_parser_parse_tentatively (parser);
   26393                 :             : 
   26394                 :         242 :           if (!cp_parser_array_designator_p (parser))
   26395                 :             :             {
   26396                 :         381 :               cp_parser_simulate_error (parser);
   26397                 :             :               designator = NULL_TREE;
   26398                 :             :             }
   26399                 :             :           else
   26400                 :             :             {
   26401                 :         103 :               designator = cp_parser_constant_expression (parser, true,
   26402                 :             :                                                           &non_const);
   26403                 :         103 :               cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
   26404                 :         103 :               cp_parser_require (parser, CPP_EQ, RT_EQ);
   26405                 :             :             }
   26406                 :             : 
   26407                 :         242 :           if (!cp_parser_parse_definitely (parser))
   26408                 :             :             designator = NULL_TREE;
   26409                 :         103 :           else if (non_const
   26410                 :         109 :                    && (!require_potential_rvalue_constant_expression
   26411                 :           6 :                        (designator)))
   26412                 :             :             designator = NULL_TREE;
   26413                 :          97 :           if (designator)
   26414                 :             :             /* Warn the user that they are using an extension.  */
   26415                 :          97 :             pedwarn (loc, OPT_Wpedantic,
   26416                 :             :                      "ISO C++ does not allow C99 designated initializers");
   26417                 :             :         }
   26418                 :             :       else
   26419                 :             :         designator = NULL_TREE;
   26420                 :             : 
   26421                 :    17909479 :       if (first_p)
   26422                 :             :         {
   26423                 :             :           first_designator = designator;
   26424                 :             :           first_p = false;
   26425                 :             :         }
   26426                 :    12961134 :       else if (cxx_dialect >= cxx20
   26427                 :     8460524 :                && first_designator != error_mark_node
   26428                 :     8460519 :                && (!first_designator != !designator))
   26429                 :             :         {
   26430                 :           9 :           error_at (loc, "either all initializer clauses should be designated "
   26431                 :             :                          "or none of them should be");
   26432                 :           9 :           first_designator = error_mark_node;
   26433                 :             :         }
   26434                 :    12961125 :       else if (cxx_dialect < cxx20 && !first_designator)
   26435                 :     9448710 :         first_designator = designator;
   26436                 :             : 
   26437                 :             :       /* Parse the initializer.  */
   26438                 :    26537048 :       initializer = cp_parser_initializer_clause (parser,
   26439                 :             :                                                   (non_constant_p != nullptr
   26440                 :             :                                                    ? &clause_non_constant_p
   26441                 :             :                                                    : nullptr));
   26442                 :             :       /* If any clause is non-constant, so is the entire initializer.  */
   26443                 :    17909479 :       if (non_constant_p && clause_non_constant_p)
   26444                 :      107766 :         *non_constant_p = true;
   26445                 :             : 
   26446                 :    17909479 :       if (TREE_CODE (initializer) == CONSTRUCTOR)
   26447                 :             :         /* This uses |= rather than = because C_I_D_I could have been set in
   26448                 :             :            cp_parser_functional_cast so we must be careful not to clear the
   26449                 :             :            flag.  */
   26450                 :     1717853 :         CONSTRUCTOR_IS_DIRECT_INIT (initializer) |= direct_p;
   26451                 :             : 
   26452                 :             :       /* If we have an ellipsis, this is an initializer pack
   26453                 :             :          expansion.  */
   26454                 :    17909479 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   26455                 :             :         {
   26456                 :      130556 :           location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   26457                 :             : 
   26458                 :             :           /* Consume the `...'.  */
   26459                 :      130556 :           cp_lexer_consume_token (parser->lexer);
   26460                 :             : 
   26461                 :      130556 :           if (designator && cxx_dialect >= cxx20)
   26462                 :           1 :             error_at (loc,
   26463                 :             :                       "%<...%> not allowed in designated initializer list");
   26464                 :             : 
   26465                 :             :           /* Turn the initializer into an initializer expansion.  */
   26466                 :      130556 :           initializer = make_pack_expansion (initializer);
   26467                 :             :         }
   26468                 :             : 
   26469                 :             :       /* Add it to the vector.  */
   26470                 :    17909479 :       CONSTRUCTOR_APPEND_ELT (v, designator, initializer);
   26471                 :             : 
   26472                 :             :       /* If the next token is not a comma, we have reached the end of
   26473                 :             :          the list.  */
   26474                 :    17909479 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   26475                 :             :         break;
   26476                 :             : 
   26477                 :             :       /* Peek at the next token.  */
   26478                 :    13023171 :       token = cp_lexer_peek_nth_token (parser->lexer, 2);
   26479                 :             :       /* If the next token is a `}', then we're still done.  An
   26480                 :             :          initializer-clause can have a trailing `,' after the
   26481                 :             :          initializer-list and before the closing `}'.  */
   26482                 :    13023171 :       if (token->type == CPP_CLOSE_BRACE)
   26483                 :             :         break;
   26484                 :             : 
   26485                 :             :       /* Suppress location wrappers in a long initializer to save memory
   26486                 :             :          (14179).  The cutoff is chosen arbitrarily.  */
   26487                 :    12961134 :       const unsigned loc_max = 256;
   26488                 :    12961134 :       unsigned incr = 1;
   26489                 :    12961134 :       if (TREE_CODE (initializer) == CONSTRUCTOR)
   26490                 :             :         /* Look one level down because it's easy.  Looking deeper would require
   26491                 :             :            passing down a nelts pointer, and I don't think multi-level massive
   26492                 :             :            initializers are common enough to justify this.  */
   26493                 :     1468032 :         incr = CONSTRUCTOR_NELTS (initializer);
   26494                 :    12961134 :       nelts += incr;
   26495                 :    12961134 :       if (nelts >= loc_max && (nelts - incr) < loc_max)
   26496                 :        5112 :         ++suppress_location_wrappers;
   26497                 :             : 
   26498                 :             :       /* Consume the `,' token.  */
   26499                 :    12961134 :       cp_lexer_consume_token (parser->lexer);
   26500                 :    12961134 :     }
   26501                 :             : 
   26502                 :             :   /* The same identifier shall not appear in multiple designators
   26503                 :             :      of a designated-initializer-list.  */
   26504                 :     4948345 :   if (first_designator)
   26505                 :             :     {
   26506                 :             :       unsigned int i;
   26507                 :             :       tree designator, val;
   26508                 :        6827 :       FOR_EACH_CONSTRUCTOR_ELT (v, i, designator, val)
   26509                 :        4127 :         if (designator && TREE_CODE (designator) == IDENTIFIER_NODE)
   26510                 :             :           {
   26511                 :        3984 :             if (IDENTIFIER_MARKED (designator))
   26512                 :             :               {
   26513                 :           7 :                 error_at (cp_expr_loc_or_input_loc (val),
   26514                 :             :                           "%<.%s%> designator used multiple times in "
   26515                 :             :                           "the same initializer list",
   26516                 :           7 :                           IDENTIFIER_POINTER (designator));
   26517                 :           7 :                 (*v)[i].index = error_mark_node;
   26518                 :             :               }
   26519                 :             :             else
   26520                 :        3977 :               IDENTIFIER_MARKED (designator) = 1;
   26521                 :             :           }
   26522                 :        6827 :       FOR_EACH_CONSTRUCTOR_ELT (v, i, designator, val)
   26523                 :        4127 :         if (designator && TREE_CODE (designator) == IDENTIFIER_NODE)
   26524                 :        3977 :           IDENTIFIER_MARKED (designator) = 0;
   26525                 :             :     }
   26526                 :             : 
   26527                 :     4948345 :   suppress_location_wrappers = suppress;
   26528                 :             : 
   26529                 :     4948345 :   *designated = first_designator != NULL_TREE;
   26530                 :     4948345 :   return v;
   26531                 :             : }
   26532                 :             : 
   26533                 :             : /* Classes [gram.class] */
   26534                 :             : 
   26535                 :             : /* Parse a class-name.
   26536                 :             : 
   26537                 :             :    class-name:
   26538                 :             :      identifier
   26539                 :             :      template-id
   26540                 :             : 
   26541                 :             :    TYPENAME_KEYWORD_P is true iff the `typename' keyword has been used
   26542                 :             :    to indicate that names looked up in dependent types should be
   26543                 :             :    assumed to be types.  TEMPLATE_KEYWORD_P is true iff the `template'
   26544                 :             :    keyword has been used to indicate that the name that appears next
   26545                 :             :    is a template.  TAG_TYPE indicates the explicit tag given before
   26546                 :             :    the type name, if any.  If CHECK_DEPENDENCY_P is FALSE, names are
   26547                 :             :    looked up in dependent scopes.  If CLASS_HEAD_P is TRUE, this class
   26548                 :             :    is the class being defined in a class-head.  If ENUM_OK is TRUE,
   26549                 :             :    enum-names are also accepted.
   26550                 :             : 
   26551                 :             :    Returns the TYPE_DECL representing the class.  */
   26552                 :             : 
   26553                 :             : static tree
   26554                 :  2424765864 : cp_parser_class_name (cp_parser *parser,
   26555                 :             :                       bool typename_keyword_p,
   26556                 :             :                       bool template_keyword_p,
   26557                 :             :                       enum tag_types tag_type,
   26558                 :             :                       bool check_dependency_p,
   26559                 :             :                       bool class_head_p,
   26560                 :             :                       bool is_declaration,
   26561                 :             :                       bool enum_ok)
   26562                 :             : {
   26563                 :  2424765864 :   tree decl;
   26564                 :  2424765864 :   tree identifier = NULL_TREE;
   26565                 :             : 
   26566                 :             :   /* All class-names start with an identifier.  */
   26567                 :  2424765864 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   26568                 :  2424765864 :   if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
   26569                 :             :     {
   26570                 :   563234542 :       cp_parser_error (parser, "expected class-name");
   26571                 :   563234542 :       return error_mark_node;
   26572                 :             :     }
   26573                 :             : 
   26574                 :             :   /* PARSER->SCOPE can be cleared when parsing the template-arguments
   26575                 :             :      to a template-id, so we save it here.  Consider object scope too,
   26576                 :             :      so that make_typename_type below can use it (cp_parser_template_name
   26577                 :             :      considers object scope also).  This may happen with code like
   26578                 :             : 
   26579                 :             :        p->template A<T>::a()
   26580                 :             : 
   26581                 :             :       where we first want to look up A<T>::a in the class of the object
   26582                 :             :       expression, as per [basic.lookup.classref].  */
   26583                 :  1861531322 :   tree scope = parser->scope ? parser->scope : parser->context->object_type;
   26584                 :             :   /* This only checks parser->scope to avoid duplicate errors; if
   26585                 :             :      ->object_type is erroneous, go on to give a parse error.  */
   26586                 :  1861531322 :   if (parser->scope == error_mark_node)
   26587                 :             :     return error_mark_node;
   26588                 :             : 
   26589                 :             :   /* Any name names a type if we're following the `typename' keyword
   26590                 :             :      in a qualified name where the enclosing scope is type-dependent.  */
   26591                 :  1861531257 :   const bool typename_p = (typename_keyword_p
   26592                 :    62816610 :                            && parser->scope
   26593                 :     6800872 :                            && TYPE_P (parser->scope)
   26594                 :  1863646639 :                            && dependent_scope_p (parser->scope));
   26595                 :             :   /* Handle the common case (an identifier, but not a template-id)
   26596                 :             :      efficiently.  */
   26597                 :  1861531257 :   if (token->type == CPP_NAME
   26598                 :  1861531257 :       && !cp_parser_nth_token_starts_template_argument_list_p (parser, 2))
   26599                 :             :     {
   26600                 :  1447883780 :       cp_token *identifier_token;
   26601                 :  1447883780 :       bool ambiguous_p;
   26602                 :             : 
   26603                 :             :       /* Look for the identifier.  */
   26604                 :  1447883780 :       identifier_token = cp_lexer_peek_token (parser->lexer);
   26605                 :  1447883780 :       ambiguous_p = identifier_token->error_reported;
   26606                 :  1447883780 :       identifier = cp_parser_identifier (parser);
   26607                 :             :       /* If the next token isn't an identifier, we are certainly not
   26608                 :             :          looking at a class-name.  */
   26609                 :  1447883780 :       if (identifier == error_mark_node)
   26610                 :             :         decl = error_mark_node;
   26611                 :             :       /* If we know this is a type-name, there's no need to look it
   26612                 :             :          up.  */
   26613                 :  1447883780 :       else if (typename_p)
   26614                 :             :         decl = identifier;
   26615                 :             :       else
   26616                 :             :         {
   26617                 :  1446890204 :           tree ambiguous_decls;
   26618                 :             :           /* If we already know that this lookup is ambiguous, then
   26619                 :             :              we've already issued an error message; there's no reason
   26620                 :             :              to check again.  */
   26621                 :  1446890204 :           if (ambiguous_p)
   26622                 :             :             {
   26623                 :           0 :               cp_parser_simulate_error (parser);
   26624                 :         206 :               return error_mark_node;
   26625                 :             :             }
   26626                 :             :           /* If the next token is a `::', then the name must be a type
   26627                 :             :              name.
   26628                 :             : 
   26629                 :             :              [basic.lookup.qual]
   26630                 :             : 
   26631                 :             :              During the lookup for a name preceding the :: scope
   26632                 :             :              resolution operator, object, function, and enumerator
   26633                 :             :              names are ignored.  */
   26634                 :  1446890204 :           if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
   26635                 :   130082272 :             tag_type = scope_type;
   26636                 :             :           /* Look up the name.  */
   26637                 :  1446890204 :           decl = cp_parser_lookup_name (parser, identifier,
   26638                 :             :                                         tag_type,
   26639                 :             :                                         /*is_template=*/false,
   26640                 :             :                                         /*is_namespace=*/false,
   26641                 :             :                                         check_dependency_p,
   26642                 :             :                                         &ambiguous_decls,
   26643                 :             :                                         identifier_token->location);
   26644                 :  1446890204 :           if (ambiguous_decls)
   26645                 :             :             {
   26646                 :         206 :               if (cp_parser_parsing_tentatively (parser))
   26647                 :         412 :                 cp_parser_simulate_error (parser);
   26648                 :         206 :               return error_mark_node;
   26649                 :             :             }
   26650                 :             :         }
   26651                 :             :     }
   26652                 :             :   else
   26653                 :             :     {
   26654                 :             :       /* Try a template-id.  */
   26655                 :   413647477 :       decl = cp_parser_template_id (parser, template_keyword_p,
   26656                 :             :                                     check_dependency_p,
   26657                 :             :                                     tag_type,
   26658                 :             :                                     is_declaration);
   26659                 :   413647474 :       if (decl == error_mark_node)
   26660                 :             :         return error_mark_node;
   26661                 :             :     }
   26662                 :             : 
   26663                 :  1832756978 :   decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
   26664                 :             : 
   26665                 :             :   /* If this is a typename, create a TYPENAME_TYPE.  */
   26666                 :  1832756978 :   if (typename_p && decl != error_mark_node)
   26667                 :             :     {
   26668                 :     1286676 :       decl = make_typename_type (scope, decl, typename_type,
   26669                 :             :                                  /*complain=*/tf_error);
   26670                 :     1286676 :       if (decl != error_mark_node)
   26671                 :     1286676 :         decl = TYPE_NAME (decl);
   26672                 :             :     }
   26673                 :             : 
   26674                 :  1832756978 :   decl = strip_using_decl (decl);
   26675                 :             : 
   26676                 :             :   /* Check to see that it is really the name of a class.  */
   26677                 :  1832756978 :   if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
   26678                 :    87758567 :       && identifier_p (TREE_OPERAND (decl, 0))
   26679                 :  1833485132 :       && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
   26680                 :             :     /* Situations like this:
   26681                 :             : 
   26682                 :             :          template <typename T> struct A {
   26683                 :             :            typename T::template X<int>::I i;
   26684                 :             :          };
   26685                 :             : 
   26686                 :             :        are problematic.  Is `T::template X<int>' a class-name?  The
   26687                 :             :        standard does not seem to be definitive, but there is no other
   26688                 :             :        valid interpretation of the following `::'.  Therefore, those
   26689                 :             :        names are considered class-names.  */
   26690                 :             :     {
   26691                 :         124 :       decl = make_typename_type (scope, decl, tag_type, tf_error);
   26692                 :         124 :       if (decl != error_mark_node)
   26693                 :         124 :         decl = TYPE_NAME (decl);
   26694                 :             :     }
   26695                 :  1832756854 :   else if (TREE_CODE (decl) != TYPE_DECL
   26696                 :   953248067 :            || TREE_TYPE (decl) == error_mark_node
   26697                 :   953247990 :            || !(MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))
   26698                 :     2263858 :                 || (enum_ok && TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE))
   26699                 :             :            /* In Objective-C 2.0, a classname followed by '.' starts a
   26700                 :             :               dot-syntax expression, and it's not a type-name.  */
   26701                 :  2686999981 :            || (c_dialect_objc ()
   26702                 :           0 :                && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
   26703                 :           0 :                && objc_is_class_name (decl)))
   26704                 :   978513727 :     decl = error_mark_node;
   26705                 :             : 
   26706                 :  1832756978 :   if (decl == error_mark_node)
   26707                 :   978513727 :     cp_parser_error (parser, "expected class-name");
   26708                 :   854243251 :   else if (identifier && !parser->scope)
   26709                 :   545771825 :     maybe_note_name_used_in_class (identifier, decl);
   26710                 :             : 
   26711                 :             :   return decl;
   26712                 :             : }
   26713                 :             : 
   26714                 :             : /* Make sure that any member-function parameters are in scope.
   26715                 :             :    For instance, a function's noexcept-specifier can use the function's
   26716                 :             :    parameters:
   26717                 :             : 
   26718                 :             :    struct S {
   26719                 :             :      void fn (int p) noexcept(noexcept(p));
   26720                 :             :    };
   26721                 :             : 
   26722                 :             :    so we need to make sure name lookup can find them.  This is used
   26723                 :             :    when we delay parsing of the noexcept-specifier.  */
   26724                 :             : 
   26725                 :             : static void
   26726                 :     2329793 : inject_parm_decls (tree decl)
   26727                 :             : {
   26728                 :     2329793 :   begin_scope (sk_function_parms, decl);
   26729                 :     2329793 :   tree args = DECL_ARGUMENTS (decl);
   26730                 :             : 
   26731                 :     2329793 :   do_push_parm_decls (decl, args, /*nonparms=*/NULL);
   26732                 :             : 
   26733                 :     2329793 :   if (args && is_this_parameter (args))
   26734                 :             :     {
   26735                 :     2140183 :       gcc_checking_assert (current_class_ptr == NULL_TREE);
   26736                 :     2140183 :       current_class_ref = cp_build_fold_indirect_ref (args);
   26737                 :     2140183 :       current_class_ptr = args;
   26738                 :             :     }
   26739                 :     2329793 : }
   26740                 :             : 
   26741                 :             : /* Undo the effects of inject_parm_decls.  */
   26742                 :             : 
   26743                 :             : static void
   26744                 :     2329793 : pop_injected_parms (void)
   26745                 :             : {
   26746                 :     2329793 :   pop_bindings_and_leave_scope ();
   26747                 :     2329793 :   current_class_ptr = current_class_ref = NULL_TREE;
   26748                 :     2329793 : }
   26749                 :             : 
   26750                 :             : /* Parse a class-specifier.
   26751                 :             : 
   26752                 :             :    class-specifier:
   26753                 :             :      class-head { member-specification [opt] }
   26754                 :             : 
   26755                 :             :    Returns the TREE_TYPE representing the class.  */
   26756                 :             : 
   26757                 :             : tree
   26758                 :    35116346 : cp_parser_class_specifier (cp_parser* parser)
   26759                 :             : {
   26760                 :    35116346 :   auto_timevar tv (TV_PARSE_STRUCT);
   26761                 :             : 
   26762                 :    35116346 :   tree type;
   26763                 :    35116346 :   tree attributes = NULL_TREE;
   26764                 :    35116346 :   bool nested_name_specifier_p;
   26765                 :    35116346 :   unsigned saved_num_template_parameter_lists;
   26766                 :    35116346 :   bool saved_in_function_body;
   26767                 :    35116346 :   unsigned char in_statement;
   26768                 :    35116346 :   bool in_switch_statement_p;
   26769                 :    35116346 :   bool saved_in_unbraced_linkage_specification_p;
   26770                 :    35116346 :   tree old_scope = NULL_TREE;
   26771                 :    35116346 :   tree scope = NULL_TREE;
   26772                 :    35116346 :   cp_token *closing_brace;
   26773                 :             : 
   26774                 :    35116346 :   push_deferring_access_checks (dk_no_deferred);
   26775                 :             : 
   26776                 :             :   /* Parse the class-head.  */
   26777                 :    35116346 :   type = cp_parser_class_head (parser,
   26778                 :             :                                &nested_name_specifier_p);
   26779                 :             :   /* If the class-head was a semantic disaster, skip the entire body
   26780                 :             :      of the class.  */
   26781                 :    35116346 :   if (!type)
   26782                 :             :     {
   26783                 :         472 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   26784                 :         472 :       pop_deferring_access_checks ();
   26785                 :         472 :       return error_mark_node;
   26786                 :             :     }
   26787                 :             : 
   26788                 :             :   /* Look for the `{'.  */
   26789                 :    35115874 :   matching_braces braces;
   26790                 :    35115874 :   if (!braces.require_open (parser))
   26791                 :             :     {
   26792                 :    11648245 :       pop_deferring_access_checks ();
   26793                 :    11648245 :       return error_mark_node;
   26794                 :             :     }
   26795                 :             : 
   26796                 :    23467629 :   cp_ensure_no_omp_declare_simd (parser);
   26797                 :    23467629 :   cp_ensure_no_oacc_routine (parser);
   26798                 :             : 
   26799                 :             :   /* Issue an error message if type-definitions are forbidden here.  */
   26800                 :    23467629 :   bool type_definition_ok_p = cp_parser_check_type_definition (parser);
   26801                 :             :   /* Remember that we are defining one more class.  */
   26802                 :    23467629 :   ++parser->num_classes_being_defined;
   26803                 :             :   /* Inside the class, surrounding template-parameter-lists do not
   26804                 :             :      apply.  */
   26805                 :    23467629 :   saved_num_template_parameter_lists
   26806                 :    23467629 :     = parser->num_template_parameter_lists;
   26807                 :    23467629 :   parser->num_template_parameter_lists = 0;
   26808                 :             :   /* We are not in a function body.  */
   26809                 :    23467629 :   saved_in_function_body = parser->in_function_body;
   26810                 :    23467629 :   parser->in_function_body = false;
   26811                 :             :   /* Or in a loop.  */
   26812                 :    23467629 :   in_statement = parser->in_statement;
   26813                 :    23467629 :   parser->in_statement = 0;
   26814                 :             :   /* Or in a switch.  */
   26815                 :    23467629 :   in_switch_statement_p = parser->in_switch_statement_p;
   26816                 :    23467629 :   parser->in_switch_statement_p = false;
   26817                 :             :   /* We are not immediately inside an extern "lang" block.  */
   26818                 :    23467629 :   saved_in_unbraced_linkage_specification_p
   26819                 :    23467629 :     = parser->in_unbraced_linkage_specification_p;
   26820                 :    23467629 :   parser->in_unbraced_linkage_specification_p = false;
   26821                 :             :   /* 'this' from an enclosing non-static member function is unavailable.  */
   26822                 :    23467629 :   tree saved_ccp = current_class_ptr;
   26823                 :    23467629 :   tree saved_ccr = current_class_ref;
   26824                 :    23467629 :   current_class_ptr = NULL_TREE;
   26825                 :    23467629 :   current_class_ref = NULL_TREE;
   26826                 :             : 
   26827                 :             :   /* Start the class.  */
   26828                 :    23467629 :   if (nested_name_specifier_p)
   26829                 :             :     {
   26830                 :      237062 :       scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
   26831                 :             :       /* SCOPE must be a scope nested inside current scope.  */
   26832                 :      237062 :       if (is_nested_namespace (current_namespace,
   26833                 :             :                                decl_namespace_context (scope)))
   26834                 :      237059 :         old_scope = push_inner_scope (scope);
   26835                 :             :       else
   26836                 :           3 :         nested_name_specifier_p = false;
   26837                 :             :     }
   26838                 :    23467629 :   type = begin_class_definition (type);
   26839                 :             : 
   26840                 :    23467629 :   if (type == error_mark_node)
   26841                 :             :     /* If the type is erroneous, skip the entire body of the class.  */
   26842                 :          58 :     cp_parser_skip_to_closing_brace (parser);
   26843                 :             :   else
   26844                 :             :     /* Parse the member-specification.  */
   26845                 :    23467571 :     cp_parser_member_specification_opt (parser);
   26846                 :             : 
   26847                 :             :   /* Look for the trailing `}'.  */
   26848                 :    23467617 :   closing_brace = braces.require_close (parser);
   26849                 :             :   /* Look for trailing attributes to apply to this class.  */
   26850                 :    23467617 :   if (cp_parser_allow_gnu_extensions_p (parser))
   26851                 :    23467617 :     attributes = cp_parser_gnu_attributes_opt (parser);
   26852                 :    23467617 :   if (type != error_mark_node)
   26853                 :    23467559 :     type = finish_struct (type, attributes);
   26854                 :    23467608 :   if (nested_name_specifier_p)
   26855                 :      237059 :     pop_inner_scope (old_scope, scope);
   26856                 :             : 
   26857                 :             :   /* We've finished a type definition.  Check for the common syntax
   26858                 :             :      error of forgetting a semicolon after the definition.  We need to
   26859                 :             :      be careful, as we can't just check for not-a-semicolon and be done
   26860                 :             :      with it; the user might have typed:
   26861                 :             : 
   26862                 :             :      class X { } c = ...;
   26863                 :             :      class X { } *p = ...;
   26864                 :             : 
   26865                 :             :      and so forth.  Instead, enumerate all the possible tokens that
   26866                 :             :      might follow this production; if we don't see one of them, then
   26867                 :             :      complain and silently insert the semicolon.  */
   26868                 :    23467605 :   {
   26869                 :    23467605 :     cp_token *token = cp_lexer_peek_token (parser->lexer);
   26870                 :    23467605 :     bool want_semicolon = true;
   26871                 :             : 
   26872                 :    23467605 :     if (cp_next_tokens_can_be_std_attribute_p (parser))
   26873                 :             :       /* Don't try to parse c++11 attributes here.  As per the
   26874                 :             :          grammar, that should be a task for
   26875                 :             :          cp_parser_decl_specifier_seq.  */
   26876                 :          12 :       want_semicolon = false;
   26877                 :             : 
   26878                 :    23467605 :     switch (token->type)
   26879                 :             :       {
   26880                 :             :       case CPP_NAME:
   26881                 :             :       case CPP_SEMICOLON:
   26882                 :             :       case CPP_MULT:
   26883                 :             :       case CPP_AND:
   26884                 :             :       case CPP_OPEN_PAREN:
   26885                 :             :       case CPP_CLOSE_PAREN:
   26886                 :             :       case CPP_COMMA:
   26887                 :             :       case CPP_SCOPE:
   26888                 :    23467415 :         want_semicolon = false;
   26889                 :             :         break;
   26890                 :             : 
   26891                 :             :         /* While it's legal for type qualifiers and storage class
   26892                 :             :            specifiers to follow type definitions in the grammar, only
   26893                 :             :            compiler testsuites contain code like that.  Assume that if
   26894                 :             :            we see such code, then what we're really seeing is a case
   26895                 :             :            like:
   26896                 :             : 
   26897                 :             :            class X { }
   26898                 :             :            const <type> var = ...;
   26899                 :             : 
   26900                 :             :            or
   26901                 :             : 
   26902                 :             :            class Y { }
   26903                 :             :            static <type> func (...) ...
   26904                 :             : 
   26905                 :             :            i.e. the qualifier or specifier applies to the next
   26906                 :             :            declaration.  To do so, however, we need to look ahead one
   26907                 :             :            more token to see if *that* token is a type specifier.
   26908                 :             : 
   26909                 :             :            This code could be improved to handle:
   26910                 :             : 
   26911                 :             :            class Z { }
   26912                 :             :            static const <type> var = ...;  */
   26913                 :       13667 :       case CPP_KEYWORD:
   26914                 :       13667 :         if (keyword_is_decl_specifier (token->keyword))
   26915                 :             :           {
   26916                 :       13630 :             cp_token *lookahead = cp_lexer_peek_nth_token (parser->lexer, 2);
   26917                 :             : 
   26918                 :             :             /* Handling user-defined types here would be nice, but very
   26919                 :             :                tricky.  */
   26920                 :       13630 :             want_semicolon
   26921                 :       13630 :               = (lookahead->type == CPP_KEYWORD
   26922                 :       13630 :                  && keyword_begins_type_specifier (lookahead->keyword));
   26923                 :             :           }
   26924                 :             :         break;
   26925                 :             :       default:
   26926                 :             :         break;
   26927                 :             :       }
   26928                 :             : 
   26929                 :             :     /* If we don't have a type, then something is very wrong and we
   26930                 :             :        shouldn't try to do anything clever.  Likewise for not seeing the
   26931                 :             :        closing brace.  */
   26932                 :    23467605 :     if (closing_brace && TYPE_P (type) && want_semicolon)
   26933                 :             :       {
   26934                 :             :         /* Locate the closing brace.  */
   26935                 :         103 :         cp_token_position prev
   26936                 :         103 :           = cp_lexer_previous_token_position (parser->lexer);
   26937                 :         103 :         cp_token *prev_token = cp_lexer_token_at (parser->lexer, prev);
   26938                 :         103 :         location_t loc = prev_token->location;
   26939                 :             : 
   26940                 :             :         /* We want to suggest insertion of a ';' immediately *after* the
   26941                 :             :            closing brace, so, if we can, offset the location by 1 column.  */
   26942                 :         103 :         location_t next_loc = loc;
   26943                 :         103 :         if (!linemap_location_from_macro_expansion_p (line_table, loc))
   26944                 :         103 :           next_loc = linemap_position_for_loc_and_offset (line_table, loc, 1);
   26945                 :             : 
   26946                 :         103 :         rich_location richloc (line_table, next_loc);
   26947                 :             : 
   26948                 :             :         /* If we successfully offset the location, suggest the fix-it.  */
   26949                 :         103 :         if (next_loc != loc)
   26950                 :          99 :           richloc.add_fixit_insert_before (next_loc, ";");
   26951                 :             : 
   26952                 :         103 :         if (CLASSTYPE_DECLARED_CLASS (type))
   26953                 :          44 :           error_at (&richloc,
   26954                 :             :                     "expected %<;%> after class definition");
   26955                 :          59 :         else if (TREE_CODE (type) == RECORD_TYPE)
   26956                 :          56 :           error_at (&richloc,
   26957                 :             :                     "expected %<;%> after struct definition");
   26958                 :           3 :         else if (TREE_CODE (type) == UNION_TYPE)
   26959                 :           3 :           error_at (&richloc,
   26960                 :             :                     "expected %<;%> after union definition");
   26961                 :             :         else
   26962                 :           0 :           gcc_unreachable ();
   26963                 :             : 
   26964                 :             :         /* Unget one token and smash it to look as though we encountered
   26965                 :             :            a semicolon in the input stream.  */
   26966                 :         103 :         cp_lexer_set_token_position (parser->lexer, prev);
   26967                 :         103 :         token = cp_lexer_peek_token (parser->lexer);
   26968                 :         103 :         token->type = CPP_SEMICOLON;
   26969                 :         103 :         token->keyword = RID_MAX;
   26970                 :         103 :       }
   26971                 :             :   }
   26972                 :             : 
   26973                 :             :   /* If this class is not itself within the scope of another class,
   26974                 :             :      then we need to parse the bodies of all of the queued function
   26975                 :             :      definitions.  Note that the queued functions defined in a class
   26976                 :             :      are not always processed immediately following the
   26977                 :             :      class-specifier for that class.  Consider:
   26978                 :             : 
   26979                 :             :        struct A {
   26980                 :             :          struct B { void f() { sizeof (A); } };
   26981                 :             :        };
   26982                 :             : 
   26983                 :             :      If `f' were processed before the processing of `A' were
   26984                 :             :      completed, there would be no way to compute the size of `A'.
   26985                 :             :      Note that the nesting we are interested in here is lexical --
   26986                 :             :      not the semantic nesting given by TYPE_CONTEXT.  In particular,
   26987                 :             :      for:
   26988                 :             : 
   26989                 :             :        struct A { struct B; };
   26990                 :             :        struct A::B { void f() { } };
   26991                 :             : 
   26992                 :             :      there is no need to delay the parsing of `A::B::f'.  */
   26993                 :    23467605 :   if (--parser->num_classes_being_defined == 0)
   26994                 :             :     {
   26995                 :    21381660 :       tree decl;
   26996                 :    21381660 :       tree class_type = NULL_TREE;
   26997                 :    21381660 :       tree pushed_scope = NULL_TREE;
   26998                 :    21381660 :       unsigned ix;
   26999                 :    21381660 :       cp_default_arg_entry *e;
   27000                 :             : 
   27001                 :    21381660 :       if (!type_definition_ok_p || any_erroneous_template_args_p (type))
   27002                 :             :         {
   27003                 :             :           /* Skip default arguments, NSDMIs, etc, in order to improve
   27004                 :             :              error recovery (c++/71169, c++/71832).  */
   27005                 :         299 :           vec_safe_truncate (unparsed_funs_with_default_args, 0);
   27006                 :         299 :           vec_safe_truncate (unparsed_nsdmis, 0);
   27007                 :         299 :           vec_safe_truncate (unparsed_funs_with_definitions, 0);
   27008                 :             :         }
   27009                 :             : 
   27010                 :             :       /* In a first pass, parse default arguments to the functions.
   27011                 :             :          Then, in a second pass, parse the bodies of the functions.
   27012                 :             :          This two-phased approach handles cases like:
   27013                 :             : 
   27014                 :             :             struct S {
   27015                 :             :               void f() { g(); }
   27016                 :             :               void g(int i = 3);
   27017                 :             :             };
   27018                 :             : 
   27019                 :             :          */
   27020                 :    26007553 :       FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_default_args, ix, e)
   27021                 :             :         {
   27022                 :     4625893 :           decl = e->decl;
   27023                 :             :           /* If there are default arguments that have not yet been processed,
   27024                 :             :              take care of them now.  */
   27025                 :     4625893 :           if (class_type != e->class_type)
   27026                 :             :             {
   27027                 :     1686935 :               if (pushed_scope)
   27028                 :      139052 :                 pop_scope (pushed_scope);
   27029                 :     1686935 :               class_type = e->class_type;
   27030                 :     1686935 :               pushed_scope = push_scope (class_type);
   27031                 :             :             }
   27032                 :             :           /* Make sure that any template parameters are in scope.  */
   27033                 :     4625893 :           maybe_begin_member_template_processing (decl);
   27034                 :             :           /* Parse the default argument expressions.  */
   27035                 :     4625893 :           cp_parser_late_parsing_default_args (parser, decl);
   27036                 :             :           /* Remove any template parameters from the symbol table.  */
   27037                 :     4625893 :           maybe_end_member_template_processing ();
   27038                 :             :         }
   27039                 :    21381660 :       vec_safe_truncate (unparsed_funs_with_default_args, 0);
   27040                 :             : 
   27041                 :             :       /* If there are noexcept-specifiers that have not yet been processed,
   27042                 :             :          take care of them now.  Do this before processing NSDMIs as they
   27043                 :             :          may depend on noexcept-specifiers already having been processed.  */
   27044                 :    23711295 :       FOR_EACH_VEC_SAFE_ELT (unparsed_noexcepts, ix, decl)
   27045                 :             :         {
   27046                 :     2329635 :           tree ctx = DECL_CONTEXT (decl);
   27047                 :     2329635 :           if (class_type != ctx)
   27048                 :             :             {
   27049                 :      807674 :               if (pushed_scope)
   27050                 :       18415 :                 pop_scope (pushed_scope);
   27051                 :      807674 :               class_type = ctx;
   27052                 :      807674 :               pushed_scope = push_scope (class_type);
   27053                 :             :             }
   27054                 :             : 
   27055                 :     2329635 :           tree def_parse = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
   27056                 :     2329635 :           def_parse = TREE_PURPOSE (def_parse);
   27057                 :             : 
   27058                 :             :           /* Make sure that any template parameters are in scope.  */
   27059                 :     2329635 :           maybe_begin_member_template_processing (decl);
   27060                 :             : 
   27061                 :             :           /* Make sure that any member-function parameters are in scope.
   27062                 :             :              This function doesn't expect ccp to be set.  */
   27063                 :     2329635 :           current_class_ptr = current_class_ref = NULL_TREE;
   27064                 :     2329635 :           inject_parm_decls (decl);
   27065                 :             : 
   27066                 :             :           /* 'this' is not allowed in static member functions.  */
   27067                 :     2329635 :           unsigned char local_variables_forbidden_p
   27068                 :             :             = parser->local_variables_forbidden_p;
   27069                 :     2329635 :           if (DECL_THIS_STATIC (decl))
   27070                 :      187469 :             parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
   27071                 :             : 
   27072                 :             :           /* Now we can parse the noexcept-specifier.  */
   27073                 :     2329635 :           tree spec = cp_parser_late_noexcept_specifier (parser, def_parse);
   27074                 :             : 
   27075                 :     2329635 :           if (spec == error_mark_node)
   27076                 :           3 :             spec = NULL_TREE;
   27077                 :             : 
   27078                 :             :           /* Update the fn's type directly -- it might have escaped
   27079                 :             :              beyond this decl :(  */
   27080                 :     2329635 :           fixup_deferred_exception_variants (TREE_TYPE (decl), spec);
   27081                 :             :           /* Update any instantiations we've already created.  We must
   27082                 :             :              keep the new noexcept-specifier wrapped in a DEFERRED_NOEXCEPT
   27083                 :             :              so that maybe_instantiate_noexcept can tsubst the NOEXCEPT_EXPR
   27084                 :             :              in the pattern.  */
   27085                 :     2329662 :           for (tree i : DEFPARSE_INSTANTIATIONS (def_parse))
   27086                 :           9 :             DEFERRED_NOEXCEPT_PATTERN (TREE_PURPOSE (i))
   27087                 :          27 :               = spec ? TREE_PURPOSE (spec) : error_mark_node;
   27088                 :             : 
   27089                 :             :           /* Restore the state of local_variables_forbidden_p.  */
   27090                 :     2329635 :           parser->local_variables_forbidden_p = local_variables_forbidden_p;
   27091                 :             : 
   27092                 :             :           /* The finish_struct call above performed various override checking,
   27093                 :             :              but it skipped unparsed noexcept-specifier operands.  Now that we
   27094                 :             :              have resolved them, check again.  */
   27095                 :     2329635 :           noexcept_override_late_checks (decl);
   27096                 :             : 
   27097                 :             :           /* Remove any member-function parameters from the symbol table.  */
   27098                 :     2329635 :           pop_injected_parms ();
   27099                 :             : 
   27100                 :             :           /* Remove any template parameters from the symbol table.  */
   27101                 :     2329635 :           maybe_end_member_template_processing ();
   27102                 :             :         }
   27103                 :    21381660 :       vec_safe_truncate (unparsed_noexcepts, 0);
   27104                 :             : 
   27105                 :             :       /* Now parse any NSDMIs.  */
   27106                 :    22238138 :       FOR_EACH_VEC_SAFE_ELT (unparsed_nsdmis, ix, decl)
   27107                 :             :         {
   27108                 :      856478 :           tree ctx = type_context_for_name_lookup (decl);
   27109                 :      856478 :           if (class_type != ctx)
   27110                 :             :             {
   27111                 :      356991 :               if (pushed_scope)
   27112                 :       72586 :                 pop_scope (pushed_scope);
   27113                 :      356991 :               class_type = ctx;
   27114                 :      356991 :               pushed_scope = push_scope (class_type);
   27115                 :             :             }
   27116                 :      856478 :           inject_this_parameter (class_type, TYPE_UNQUALIFIED);
   27117                 :      856478 :           cp_parser_late_parsing_nsdmi (parser, decl);
   27118                 :             :         }
   27119                 :    21381660 :       vec_safe_truncate (unparsed_nsdmis, 0);
   27120                 :             : 
   27121                 :             :       /* Now contract attributes.  */
   27122                 :    21381818 :       FOR_EACH_VEC_SAFE_ELT (unparsed_contracts, ix, decl)
   27123                 :             :         {
   27124                 :         158 :           tree ctx = DECL_CONTEXT (decl);
   27125                 :         158 :           if (class_type != ctx)
   27126                 :             :             {
   27127                 :          61 :               if (pushed_scope)
   27128                 :          11 :                 pop_scope (pushed_scope);
   27129                 :          61 :               class_type = ctx;
   27130                 :          61 :               pushed_scope = push_scope (class_type);
   27131                 :             :             }
   27132                 :             : 
   27133                 :         158 :           temp_override<tree> cfd(current_function_decl, decl);
   27134                 :             : 
   27135                 :             :           /* Make sure that any template parameters are in scope.  */
   27136                 :         158 :           maybe_begin_member_template_processing (decl);
   27137                 :             : 
   27138                 :             :           /* Make sure that any member-function parameters are in scope.
   27139                 :             :              This function doesn't expect ccp to be set.  */
   27140                 :         158 :           current_class_ptr = current_class_ref = NULL_TREE;
   27141                 :         158 :           inject_parm_decls (decl);
   27142                 :             : 
   27143                 :             :           /* 'this' is not allowed in static member functions.  */
   27144                 :         158 :           unsigned char local_variables_forbidden_p
   27145                 :             :             = parser->local_variables_forbidden_p;
   27146                 :         158 :           if (DECL_THIS_STATIC (decl))
   27147                 :           4 :             parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
   27148                 :             : 
   27149                 :             :           /* Now we can parse contract conditions.  */
   27150                 :         394 :           for (tree a = DECL_ATTRIBUTES (decl); a; a = TREE_CHAIN (a))
   27151                 :             :             {
   27152                 :         236 :               if (cxx_contract_attribute_p (a))
   27153                 :         236 :                 cp_parser_late_contract_condition (parser, decl, a);
   27154                 :             :             }
   27155                 :             : 
   27156                 :             :           /* Restore the state of local_variables_forbidden_p.  */
   27157                 :         158 :           parser->local_variables_forbidden_p = local_variables_forbidden_p;
   27158                 :             : 
   27159                 :             :           /* Remove any member-function parameters from the symbol table.  */
   27160                 :         158 :           pop_injected_parms ();
   27161                 :             : 
   27162                 :             :           /* Remove any template parameters from the symbol table.  */
   27163                 :         158 :           maybe_end_member_template_processing ();
   27164                 :             : 
   27165                 :             :           /* Perform any deferred contract matching.  */
   27166                 :         158 :           match_deferred_contracts (decl);
   27167                 :         158 :         }
   27168                 :    21381660 :       vec_safe_truncate (unparsed_contracts, 0);
   27169                 :             : 
   27170                 :    21381660 :       current_class_ptr = NULL_TREE;
   27171                 :    21381660 :       current_class_ref = NULL_TREE;
   27172                 :    21381660 :       if (pushed_scope)
   27173                 :     2621597 :         pop_scope (pushed_scope);
   27174                 :             : 
   27175                 :             :       /* Now parse the body of the functions.  */
   27176                 :    21381660 :       if (flag_openmp)
   27177                 :             :         {
   27178                 :             :           /* OpenMP UDRs need to be parsed before all other functions.  */
   27179                 :       54784 :           FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
   27180                 :       30796 :             if (DECL_OMP_DECLARE_REDUCTION_P (decl))
   27181                 :         234 :               cp_parser_late_parsing_for_member (parser, decl);
   27182                 :       54784 :           FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
   27183                 :       30796 :             if (!DECL_OMP_DECLARE_REDUCTION_P (decl))
   27184                 :       30562 :               cp_parser_late_parsing_for_member (parser, decl);
   27185                 :             :         }
   27186                 :             :       else
   27187                 :    99540811 :         FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
   27188                 :    78183139 :           cp_parser_late_parsing_for_member (parser, decl);
   27189                 :    21381660 :       vec_safe_truncate (unparsed_funs_with_definitions, 0);
   27190                 :             :     }
   27191                 :             : 
   27192                 :             :   /* Put back any saved access checks.  */
   27193                 :    23467605 :   pop_deferring_access_checks ();
   27194                 :             : 
   27195                 :             :   /* Restore saved state.  */
   27196                 :    23467605 :   parser->in_switch_statement_p = in_switch_statement_p;
   27197                 :    23467605 :   parser->in_statement = in_statement;
   27198                 :    23467605 :   parser->in_function_body = saved_in_function_body;
   27199                 :    23467605 :   parser->num_template_parameter_lists
   27200                 :    23467605 :     = saved_num_template_parameter_lists;
   27201                 :    23467605 :   parser->in_unbraced_linkage_specification_p
   27202                 :    23467605 :     = saved_in_unbraced_linkage_specification_p;
   27203                 :    23467605 :   current_class_ptr = saved_ccp;
   27204                 :    23467605 :   current_class_ref = saved_ccr;
   27205                 :             : 
   27206                 :    23467605 :   return type;
   27207                 :    35116322 : }
   27208                 :             : 
   27209                 :             : /* Parse a class-head.
   27210                 :             : 
   27211                 :             :    class-head:
   27212                 :             :      class-key identifier [opt] base-clause [opt]
   27213                 :             :      class-key nested-name-specifier identifier class-virt-specifier [opt] base-clause [opt]
   27214                 :             :      class-key nested-name-specifier [opt] template-id
   27215                 :             :        base-clause [opt]
   27216                 :             : 
   27217                 :             :    class-virt-specifier:
   27218                 :             :      final
   27219                 :             : 
   27220                 :             :    GNU Extensions:
   27221                 :             :      class-key attributes identifier [opt] base-clause [opt]
   27222                 :             :      class-key attributes nested-name-specifier identifier base-clause [opt]
   27223                 :             :      class-key attributes nested-name-specifier [opt] template-id
   27224                 :             :        base-clause [opt]
   27225                 :             : 
   27226                 :             :    Upon return BASES is initialized to the list of base classes (or
   27227                 :             :    NULL, if there are none) in the same form returned by
   27228                 :             :    cp_parser_base_clause.
   27229                 :             : 
   27230                 :             :    Returns the TYPE of the indicated class.  Sets
   27231                 :             :    *NESTED_NAME_SPECIFIER_P to TRUE iff one of the productions
   27232                 :             :    involving a nested-name-specifier was used, and FALSE otherwise.
   27233                 :             : 
   27234                 :             :    Returns error_mark_node if this is not a class-head.
   27235                 :             : 
   27236                 :             :    Returns NULL_TREE if the class-head is syntactically valid, but
   27237                 :             :    semantically invalid in a way that means we should skip the entire
   27238                 :             :    body of the class.  */
   27239                 :             : 
   27240                 :             : static tree
   27241                 :    35116346 : cp_parser_class_head (cp_parser* parser,
   27242                 :             :                       bool* nested_name_specifier_p)
   27243                 :             : {
   27244                 :    35116346 :   tree nested_name_specifier;
   27245                 :    35116346 :   enum tag_types class_key;
   27246                 :    35116346 :   tree id = NULL_TREE;
   27247                 :    35116346 :   tree type = NULL_TREE;
   27248                 :    35116346 :   tree attributes;
   27249                 :    35116346 :   tree bases;
   27250                 :    35116346 :   cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
   27251                 :    35116346 :   bool template_id_p = false;
   27252                 :    35116346 :   bool qualified_p = false;
   27253                 :    35116346 :   bool invalid_nested_name_p = false;
   27254                 :    35116346 :   bool invalid_explicit_specialization_p = false;
   27255                 :    35116346 :   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   27256                 :    35116346 :   tree pushed_scope = NULL_TREE;
   27257                 :    35116346 :   unsigned num_templates;
   27258                 :    35116346 :   cp_token *type_start_token = NULL, *nested_name_specifier_token_start = NULL;
   27259                 :             :   /* Assume no nested-name-specifier will be present.  */
   27260                 :    35116346 :   *nested_name_specifier_p = false;
   27261                 :             :   /* Assume no template parameter lists will be used in defining the
   27262                 :             :      type.  */
   27263                 :    35116346 :   num_templates = 0;
   27264                 :    35116346 :   parser->colon_corrects_to_scope_p = false;
   27265                 :             : 
   27266                 :             :   /* Look for the class-key.  */
   27267                 :    35116346 :   class_key = cp_parser_class_key (parser);
   27268                 :    35116346 :   if (class_key == none_type)
   27269                 :           0 :     return error_mark_node;
   27270                 :             : 
   27271                 :    35116346 :   location_t class_head_start_location = input_location;
   27272                 :             : 
   27273                 :             :   /* Parse the attributes.  */
   27274                 :    35116346 :   attributes = cp_parser_attributes_opt (parser);
   27275                 :    35116346 :   if (find_contract (attributes))
   27276                 :           1 :     diagnose_misapplied_contracts (attributes);
   27277                 :             : 
   27278                 :             :   /* If the next token is `::', that is invalid -- but sometimes
   27279                 :             :      people do try to write:
   27280                 :             : 
   27281                 :             :        struct ::S {};
   27282                 :             : 
   27283                 :             :      Handle this gracefully by accepting the extra qualifier, and then
   27284                 :             :      issuing an error about it later if this really is a
   27285                 :             :      class-head.  If it turns out just to be an elaborated type
   27286                 :             :      specifier, remain silent.  */
   27287                 :    35116346 :   if (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false))
   27288                 :        9734 :     qualified_p = true;
   27289                 :             : 
   27290                 :             :   /* It is OK to define an inaccessible class; for example:
   27291                 :             : 
   27292                 :             :        class A { class B; };
   27293                 :             :        class A::B {};
   27294                 :             : 
   27295                 :             :      So we want to ignore access when parsing the class name.
   27296                 :             :      However, we might be tentatively parsing what is really an
   27297                 :             :      elaborated-type-specifier naming a template-id, e.g.
   27298                 :             : 
   27299                 :             :        struct C<&D::m> c;
   27300                 :             : 
   27301                 :             :      In this case the tentative parse as a class-head will fail, but not
   27302                 :             :      before cp_parser_template_id splices in a CPP_TEMPLATE_ID token.
   27303                 :             :      Since dk_no_check is sticky, we must instead use dk_deferred so that
   27304                 :             :      any such CPP_TEMPLATE_ID token created during this tentative parse
   27305                 :             :      will correctly capture the access checks imposed by the template-id . */
   27306                 :    35116346 :   push_deferring_access_checks (dk_deferred);
   27307                 :             : 
   27308                 :             :   /* Determine the name of the class.  Begin by looking for an
   27309                 :             :      optional nested-name-specifier.  */
   27310                 :    35116346 :   nested_name_specifier_token_start = cp_lexer_peek_token (parser->lexer);
   27311                 :    35116346 :   nested_name_specifier
   27312                 :    35116346 :     = cp_parser_nested_name_specifier_opt (parser,
   27313                 :             :                                            /*typename_keyword_p=*/false,
   27314                 :             :                                            /*check_dependency_p=*/false,
   27315                 :             :                                            /*type_p=*/true,
   27316                 :             :                                            /*is_declaration=*/false);
   27317                 :             :   /* If there was a nested-name-specifier, then there *must* be an
   27318                 :             :      identifier.  */
   27319                 :             : 
   27320                 :    35116346 :   cp_token *bad_template_keyword = NULL;
   27321                 :             : 
   27322                 :    35116346 :   if (nested_name_specifier)
   27323                 :             :     {
   27324                 :     4740281 :       type_start_token = cp_lexer_peek_token (parser->lexer);
   27325                 :             :       /* Although the grammar says `identifier', it really means
   27326                 :             :          `class-name' or `template-name'.  You are only allowed to
   27327                 :             :          define a class that has already been declared with this
   27328                 :             :          syntax.
   27329                 :             : 
   27330                 :             :          The proposed resolution for Core Issue 180 says that wherever
   27331                 :             :          you see `class T::X' you should treat `X' as a type-name.
   27332                 :             : 
   27333                 :             :          We do not know if we will see a class-name, or a
   27334                 :             :          template-name.  We look for a class-name first, in case the
   27335                 :             :          class-name is a template-id; if we looked for the
   27336                 :             :          template-name first we would stop after the template-name.  */
   27337                 :     4740281 :       cp_parser_parse_tentatively (parser);
   27338                 :     4740281 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
   27339                 :           7 :         bad_template_keyword = cp_lexer_consume_token (parser->lexer);
   27340                 :     4740281 :       type = cp_parser_class_name (parser,
   27341                 :             :                                    /*typename_keyword_p=*/false,
   27342                 :             :                                    /*template_keyword_p=*/false,
   27343                 :             :                                    class_type,
   27344                 :             :                                    /*check_dependency_p=*/false,
   27345                 :             :                                    /*class_head_p=*/true,
   27346                 :             :                                    /*is_declaration=*/false);
   27347                 :             :       /* If that didn't work, ignore the nested-name-specifier.  */
   27348                 :     4740281 :       if (!cp_parser_parse_definitely (parser))
   27349                 :             :         {
   27350                 :          67 :           invalid_nested_name_p = true;
   27351                 :          67 :           type_start_token = cp_lexer_peek_token (parser->lexer);
   27352                 :          67 :           id = cp_parser_identifier (parser);
   27353                 :          67 :           if (id == error_mark_node)
   27354                 :           0 :             id = NULL_TREE;
   27355                 :             :         }
   27356                 :             :       /* If we could not find a corresponding TYPE, treat this
   27357                 :             :          declaration like an unqualified declaration.  */
   27358                 :     4740281 :       if (type == error_mark_node)
   27359                 :             :         nested_name_specifier = NULL_TREE;
   27360                 :             :       /* Otherwise, count the number of templates used in TYPE and its
   27361                 :             :          containing scopes.  */
   27362                 :             :       else
   27363                 :     4740210 :         num_templates = num_template_headers_for_class (TREE_TYPE (type));
   27364                 :             :     }
   27365                 :             :   /* Otherwise, the identifier is optional.  */
   27366                 :             :   else
   27367                 :             :     {
   27368                 :             :       /* We don't know whether what comes next is a template-id,
   27369                 :             :          an identifier, or nothing at all.  */
   27370                 :    30376065 :       cp_parser_parse_tentatively (parser);
   27371                 :             :       /* Check for a template-id.  */
   27372                 :    30376065 :       type_start_token = cp_lexer_peek_token (parser->lexer);
   27373                 :    30376065 :       id = cp_parser_template_id (parser,
   27374                 :             :                                   /*template_keyword_p=*/false,
   27375                 :             :                                   /*check_dependency_p=*/true,
   27376                 :             :                                   class_key,
   27377                 :             :                                   /*is_declaration=*/true);
   27378                 :             :       /* If that didn't work, it could still be an identifier.  */
   27379                 :    30376065 :       if (!cp_parser_parse_definitely (parser))
   27380                 :             :         {
   27381                 :    19023932 :           if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   27382                 :             :             {
   27383                 :    18377869 :               type_start_token = cp_lexer_peek_token (parser->lexer);
   27384                 :    18377869 :               id = cp_parser_identifier (parser);
   27385                 :             :             }
   27386                 :             :           else
   27387                 :             :             id = NULL_TREE;
   27388                 :             :         }
   27389                 :             :       else
   27390                 :             :         {
   27391                 :             :           template_id_p = true;
   27392                 :             :           ++num_templates;
   27393                 :             :         }
   27394                 :             :     }
   27395                 :             : 
   27396                 :    35116346 :   pop_deferring_access_checks ();
   27397                 :             : 
   27398                 :    35116346 :   if (id)
   27399                 :             :     {
   27400                 :    29730069 :       cp_parser_check_for_invalid_template_id (parser, id,
   27401                 :             :                                                class_key,
   27402                 :             :                                                type_start_token->location);
   27403                 :             :     }
   27404                 :    35116346 :   virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
   27405                 :             : 
   27406                 :             :   /* If it's not a `:' or a `{' then we can't really be looking at a
   27407                 :             :      class-head, since a class-head only appears as part of a
   27408                 :             :      class-specifier.  We have to detect this situation before calling
   27409                 :             :      xref_tag, since that has irreversible side-effects.  */
   27410                 :    70232692 :   if (!cp_parser_next_token_starts_class_definition_p (parser))
   27411                 :             :     {
   27412                 :    11648198 :       cp_parser_error (parser, "expected %<{%> or %<:%>");
   27413                 :    11648198 :       type = error_mark_node;
   27414                 :    11648198 :       goto out;
   27415                 :             :     }
   27416                 :             : 
   27417                 :             :   /* At this point, we're going ahead with the class-specifier, even
   27418                 :             :      if some other problem occurs.  */
   27419                 :    23468148 :   cp_parser_commit_to_tentative_parse (parser);
   27420                 :    23468148 :   if (virt_specifiers & VIRT_SPEC_OVERRIDE)
   27421                 :             :     {
   27422                 :           6 :       cp_parser_error (parser,
   27423                 :             :                        "cannot specify %<override%> for a class");
   27424                 :           6 :       type = error_mark_node;
   27425                 :           6 :       goto out;
   27426                 :             :     }
   27427                 :             :   /* Issue the error about the overly-qualified name now.  */
   27428                 :    23468142 :   if (qualified_p)
   27429                 :             :     {
   27430                 :          16 :       cp_parser_error (parser,
   27431                 :             :                        "global qualification of class name is invalid");
   27432                 :          16 :       type = error_mark_node;
   27433                 :          16 :       goto out;
   27434                 :             :     }
   27435                 :    23468126 :   else if (invalid_nested_name_p)
   27436                 :             :     {
   27437                 :          24 :       cp_parser_error (parser,
   27438                 :             :                        "qualified name does not name a class");
   27439                 :          24 :       type = error_mark_node;
   27440                 :          24 :       goto out;
   27441                 :             :     }
   27442                 :    23468102 :   else if (nested_name_specifier)
   27443                 :             :     {
   27444                 :      237157 :       tree scope;
   27445                 :             : 
   27446                 :      237157 :       if (bad_template_keyword)
   27447                 :             :         /* [temp.names]: in a qualified-id formed by a class-head-name, the
   27448                 :             :            keyword template shall not appear at the top level.  */
   27449                 :           4 :         pedwarn (bad_template_keyword->location, OPT_Wpedantic,
   27450                 :             :                  "keyword %<template%> not allowed in class-head-name");
   27451                 :             : 
   27452                 :             :       /* Reject typedef-names in class heads.  */
   27453                 :      237157 :       if (!DECL_IMPLICIT_TYPEDEF_P (type))
   27454                 :             :         {
   27455                 :          20 :           error_at (type_start_token->location,
   27456                 :             :                     "invalid class name in declaration of %qD",
   27457                 :             :                     type);
   27458                 :          20 :           type = NULL_TREE;
   27459                 :          20 :           goto done;
   27460                 :             :         }
   27461                 :             : 
   27462                 :             :       /* Figure out in what scope the declaration is being placed.  */
   27463                 :      237137 :       scope = current_scope ();
   27464                 :             :       /* If that scope does not contain the scope in which the
   27465                 :             :          class was originally declared, the program is invalid.  */
   27466                 :      237137 :       if (scope && !is_ancestor (scope, nested_name_specifier))
   27467                 :             :         {
   27468                 :          24 :           if (at_namespace_scope_p ())
   27469                 :          12 :             error_at (type_start_token->location,
   27470                 :             :                       "declaration of %qD in namespace %qD which does not "
   27471                 :             :                       "enclose %qD",
   27472                 :             :                       type, scope, nested_name_specifier);
   27473                 :             :           else
   27474                 :          12 :             error_at (type_start_token->location,
   27475                 :             :                       "declaration of %qD in %qD which does not enclose %qD",
   27476                 :             :                       type, scope, nested_name_specifier);
   27477                 :          24 :           type = NULL_TREE;
   27478                 :          24 :           goto done;
   27479                 :             :         }
   27480                 :             :       /* [dcl.meaning]
   27481                 :             : 
   27482                 :             :          A declarator-id shall not be qualified except for the
   27483                 :             :          definition of a ... nested class outside of its class
   27484                 :             :          ... [or] the definition or explicit instantiation of a
   27485                 :             :          class member of a namespace outside of its namespace.  */
   27486                 :      237113 :       if (scope == nested_name_specifier)
   27487                 :           8 :         permerror (nested_name_specifier_token_start->location,
   27488                 :             :                    "extra qualification not allowed");
   27489                 :             :     }
   27490                 :             :   /* An explicit-specialization must be preceded by "template <>".  If
   27491                 :             :      it is not, try to recover gracefully.  */
   27492                 :    23468058 :   if (at_namespace_scope_p ()
   27493                 :    21197830 :       && parser->num_template_parameter_lists == 0
   27494                 :     3943371 :       && !processing_template_parmlist
   27495                 :    27411401 :       && template_id_p)
   27496                 :             :     {
   27497                 :             :       /* Build a location of this form:
   27498                 :             :            struct typename <ARGS>
   27499                 :             :            ^~~~~~~~~~~~~~~~~~~~~~
   27500                 :             :          with caret==start at the start token, and
   27501                 :             :          finishing at the end of the type.  */
   27502                 :           8 :       location_t reported_loc
   27503                 :           8 :         = make_location (class_head_start_location,
   27504                 :             :                          class_head_start_location,
   27505                 :             :                          get_finish (type_start_token->location));
   27506                 :           8 :       rich_location richloc (line_table, reported_loc);
   27507                 :           8 :       richloc.add_fixit_insert_before (class_head_start_location,
   27508                 :             :                                        "template <> ");
   27509                 :           8 :       error_at (&richloc,
   27510                 :             :                 "an explicit specialization must be preceded by"
   27511                 :             :                 " %<template <>%>");
   27512                 :           8 :       invalid_explicit_specialization_p = true;
   27513                 :             :       /* Take the same action that would have been taken by
   27514                 :             :          cp_parser_explicit_specialization.  */
   27515                 :           8 :       ++parser->num_template_parameter_lists;
   27516                 :           8 :       begin_specialization ();
   27517                 :           8 :     }
   27518                 :             :   /* There must be no "return" statements between this point and the
   27519                 :             :      end of this function; set "type "to the correct return value and
   27520                 :             :      use "goto done;" to return.  */
   27521                 :             :   /* Make sure that the right number of template parameters were
   27522                 :             :      present.  */
   27523                 :    23468058 :   if (!cp_parser_check_template_parameters (parser, num_templates,
   27524                 :             :                                             template_id_p,
   27525                 :             :                                             type_start_token->location,
   27526                 :             :                                             /*declarator=*/NULL))
   27527                 :             :     {
   27528                 :             :       /* If something went wrong, there is no point in even trying to
   27529                 :             :          process the class-definition.  */
   27530                 :          51 :       type = NULL_TREE;
   27531                 :          51 :       goto done;
   27532                 :             :     }
   27533                 :             : 
   27534                 :             :   /* Look up the type.  */
   27535                 :    23468007 :   if (template_id_p)
   27536                 :             :     {
   27537                 :     9941831 :       if (TREE_CODE (id) == TEMPLATE_ID_EXPR
   27538                 :     9941831 :           && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
   27539                 :           0 :               || TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
   27540                 :             :         {
   27541                 :           0 :           error_at (type_start_token->location,
   27542                 :             :                     "function template %qD redeclared as a class template", id);
   27543                 :           0 :           type = error_mark_node;
   27544                 :             :         }
   27545                 :             :       else
   27546                 :             :         {
   27547                 :     9941831 :           type = TREE_TYPE (id);
   27548                 :     9941831 :           type = maybe_process_partial_specialization (type);
   27549                 :             : 
   27550                 :             :           /* Check the scope while we still know whether or not we had a
   27551                 :             :              nested-name-specifier.  */
   27552                 :     9941831 :           if (type != error_mark_node)
   27553                 :     9941678 :             check_unqualified_spec_or_inst (type, type_start_token->location);
   27554                 :             :         }
   27555                 :     9941831 :       if (nested_name_specifier)
   27556                 :           0 :         pushed_scope = push_scope (nested_name_specifier);
   27557                 :             :     }
   27558                 :    13526176 :   else if (nested_name_specifier)
   27559                 :             :     {
   27560                 :      237097 :       type = TREE_TYPE (type);
   27561                 :             : 
   27562                 :             :       /* Given:
   27563                 :             : 
   27564                 :             :             template <typename T> struct S { struct T };
   27565                 :             :             template <typename T> struct S<T>::T { };
   27566                 :             : 
   27567                 :             :          we will get a TYPENAME_TYPE when processing the definition of
   27568                 :             :          `S::T'.  We need to resolve it to the actual type before we
   27569                 :             :          try to define it.  */
   27570                 :      237097 :       if (TREE_CODE (type) == TYPENAME_TYPE)
   27571                 :             :         {
   27572                 :           0 :           type = resolve_typename_type (type, /*only_current_p=*/false);
   27573                 :           0 :           if (TREE_CODE (type) == TYPENAME_TYPE)
   27574                 :             :             {
   27575                 :           0 :               cp_parser_error (parser, "could not resolve typename type");
   27576                 :           0 :               type = error_mark_node;
   27577                 :             :             }
   27578                 :             :         }
   27579                 :             : 
   27580                 :      237097 :       type = maybe_process_partial_specialization (type);
   27581                 :      237097 :       if (type == error_mark_node)
   27582                 :             :         {
   27583                 :           7 :           type = NULL_TREE;
   27584                 :           7 :           goto done;
   27585                 :             :         }
   27586                 :             : 
   27587                 :             :       /* Enter the scope indicated by the nested-name-specifier.  */
   27588                 :      237090 :       pushed_scope = push_scope (nested_name_specifier);
   27589                 :             :       /* Get the canonical version of this type.  */
   27590                 :      237090 :       type = TYPE_MAIN_DECL (type);
   27591                 :             :       /* Call push_template_decl if it seems like we should be defining a
   27592                 :             :          template either from the template headers or the type we're
   27593                 :             :          defining, so that we diagnose both extra and missing headers.  */
   27594                 :      237086 :       if ((PROCESSING_REAL_TEMPLATE_DECL_P ()
   27595                 :      120113 :            || CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type)))
   27596                 :      403898 :           && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
   27597                 :             :         {
   27598                 :      109536 :           type = push_template_decl (type);
   27599                 :      109536 :           if (type == error_mark_node)
   27600                 :             :             {
   27601                 :          20 :               type = NULL_TREE;
   27602                 :          20 :               goto done;
   27603                 :             :             }
   27604                 :             :         }
   27605                 :             : 
   27606                 :      237070 :       type = TREE_TYPE (type);
   27607                 :      237070 :       *nested_name_specifier_p = true;
   27608                 :             :     }
   27609                 :             :   else      /* The name is not a nested name.  */
   27610                 :             :     {
   27611                 :             :       /* If the class was unnamed, create a dummy name.  */
   27612                 :    13289079 :       if (!id)
   27613                 :      646003 :         id = make_anon_name ();
   27614                 :    26578158 :       TAG_how how = (parser->in_type_id_in_expr_p
   27615                 :    13289079 :                      ? TAG_how::INNERMOST_NON_CLASS
   27616                 :             :                      : TAG_how::CURRENT_ONLY);
   27617                 :    13289079 :       type = xref_tag (class_key, id, how,
   27618                 :    13289079 :                        parser->num_template_parameter_lists);
   27619                 :             :     }
   27620                 :             : 
   27621                 :             :   /* Diagnose class/struct/union mismatches.  */
   27622                 :    23467980 :   cp_parser_check_class_key (parser, UNKNOWN_LOCATION, class_key, type,
   27623                 :             :                              true, true);
   27624                 :             : 
   27625                 :             :   /* Indicate whether this class was declared as a `class' or as a
   27626                 :             :      `struct'.  */
   27627                 :    23467980 :   if (TREE_CODE (type) == RECORD_TYPE)
   27628                 :    23047511 :     CLASSTYPE_DECLARED_CLASS (type) = class_key == class_type;
   27629                 :             : 
   27630                 :             :   /* If this type was already complete, and we see another definition,
   27631                 :             :      that's an error.  Likewise if the type is already being defined:
   27632                 :             :      this can happen, eg, when it's defined from within an expression 
   27633                 :             :      (c++/84605).  */
   27634                 :    23467980 :   if (type != error_mark_node
   27635                 :    23467980 :       && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type)))
   27636                 :             :     {
   27637                 :          84 :       error_at (type_start_token->location, "redefinition of %q#T",
   27638                 :             :                 type);
   27639                 :          84 :       inform (location_of (type), "previous definition of %q#T",
   27640                 :             :               type);
   27641                 :          84 :       type = NULL_TREE;
   27642                 :          84 :       goto done;
   27643                 :             :     }
   27644                 :    23467896 :   else if (type == error_mark_node)
   27645                 :         266 :     type = NULL_TREE;
   27646                 :             : 
   27647                 :    23467896 :   if (type)
   27648                 :             :     {
   27649                 :    23467630 :       if (current_lambda_expr ()
   27650                 :    23467630 :           && uses_parameter_packs (attributes))
   27651                 :             :         {
   27652                 :             :           /* In a lambda this should work, but doesn't currently.  */
   27653                 :           3 :           sorry ("unexpanded parameter pack in local class in lambda");
   27654                 :           3 :           attributes = NULL_TREE;
   27655                 :             :         }
   27656                 :             : 
   27657                 :             :       /* Apply attributes now, before any use of the class as a template
   27658                 :             :          argument in its base list.  */
   27659                 :    23467630 :       cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
   27660                 :    23467630 :       fixup_attribute_variants (type);
   27661                 :             :     }
   27662                 :             : 
   27663                 :             :   /* Associate constraints with the type.  */
   27664                 :    23467896 :   if (flag_concepts)
   27665                 :     6035147 :     type = associate_classtype_constraints (type);
   27666                 :             : 
   27667                 :             :   /* We will have entered the scope containing the class; the names of
   27668                 :             :      base classes should be looked up in that context.  For example:
   27669                 :             : 
   27670                 :             :        struct A { struct B {}; struct C; };
   27671                 :             :        struct A::C : B {};
   27672                 :             : 
   27673                 :             :      is valid.  */
   27674                 :             : 
   27675                 :             :   /* Get the list of base-classes, if there is one.  Defer access checking
   27676                 :             :      until the entire list has been seen, as per [class.access.general].  */
   27677                 :    23467896 :   push_deferring_access_checks (dk_deferred);
   27678                 :    23467896 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   27679                 :             :     {
   27680                 :     9880956 :       if (type)
   27681                 :             :         {
   27682                 :     9880941 :           pushclass (type);
   27683                 :     9880941 :           start_lambda_scope (TYPE_NAME (type));
   27684                 :             :         }
   27685                 :     9880956 :       bases = cp_parser_base_clause (parser);
   27686                 :     9880956 :       if (type)
   27687                 :             :         {
   27688                 :     9880941 :           finish_lambda_scope ();
   27689                 :     9880941 :           popclass ();
   27690                 :             :         }
   27691                 :             :     }
   27692                 :             :   else
   27693                 :             :     bases = NULL_TREE;
   27694                 :             : 
   27695                 :             :   /* If we're really defining a class, process the base classes.
   27696                 :             :      If they're invalid, fail.  */
   27697                 :    23467896 :   if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   27698                 :    23467583 :     xref_basetypes (type, bases);
   27699                 :             : 
   27700                 :             :   /* Now that all bases have been seen and attached to the class, check
   27701                 :             :      accessibility of the types named in the base-clause.  This must be
   27702                 :             :      done relative to the class scope, so that we accept e.g.
   27703                 :             : 
   27704                 :             :        struct A { protected: struct B {}; };
   27705                 :             :        struct C : A::B, A {}; // OK: A::B is accessible via base A
   27706                 :             : 
   27707                 :             :      as per [class.access.general].  */
   27708                 :    23467896 :   if (type)
   27709                 :    23467630 :     pushclass (type);
   27710                 :    23467896 :   pop_to_parent_deferring_access_checks ();
   27711                 :    23467896 :   if (type)
   27712                 :    23467630 :     popclass ();
   27713                 :             : 
   27714                 :    23468102 :  done:
   27715                 :             :   /* Leave the scope given by the nested-name-specifier.  We will
   27716                 :             :      enter the class scope itself while processing the members.  */
   27717                 :    23468102 :   if (pushed_scope)
   27718                 :      237086 :     pop_scope (pushed_scope);
   27719                 :             : 
   27720                 :    23468102 :   if (invalid_explicit_specialization_p)
   27721                 :             :     {
   27722                 :           8 :       end_specialization ();
   27723                 :           8 :       --parser->num_template_parameter_lists;
   27724                 :             :     }
   27725                 :             : 
   27726                 :    23468102 :   if (type)
   27727                 :    23467630 :     DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
   27728                 :    23468102 :   if (type && (virt_specifiers & VIRT_SPEC_FINAL))
   27729                 :       99617 :     CLASSTYPE_FINAL (type) = 1;
   27730                 :    23368485 :  out:
   27731                 :    35116346 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   27732                 :    35116346 :   return type;
   27733                 :             : }
   27734                 :             : 
   27735                 :             : /* Parse a class-key.
   27736                 :             : 
   27737                 :             :    class-key:
   27738                 :             :      class
   27739                 :             :      struct
   27740                 :             :      union
   27741                 :             : 
   27742                 :             :    Returns the kind of class-key specified, or none_type to indicate
   27743                 :             :    error.  */
   27744                 :             : 
   27745                 :             : static enum tag_types
   27746                 :    46764553 : cp_parser_class_key (cp_parser* parser)
   27747                 :             : {
   27748                 :    46764553 :   cp_token *token;
   27749                 :    46764553 :   enum tag_types tag_type;
   27750                 :             : 
   27751                 :             :   /* Look for the class-key.  */
   27752                 :    46764553 :   token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_KEY);
   27753                 :    46764553 :   if (!token)
   27754                 :             :     return none_type;
   27755                 :             : 
   27756                 :             :   /* Check to see if the TOKEN is a class-key.  */
   27757                 :   129473949 :   tag_type = cp_parser_token_is_class_key (token);
   27758                 :    35944843 :   if (!tag_type)
   27759                 :           0 :     cp_parser_error (parser, "expected class-key");
   27760                 :             :   return tag_type;
   27761                 :             : }
   27762                 :             : 
   27763                 :             : /* Parse a type-parameter-key.
   27764                 :             : 
   27765                 :             :    type-parameter-key:
   27766                 :             :      class
   27767                 :             :      typename
   27768                 :             :  */
   27769                 :             : 
   27770                 :             : static void
   27771                 :      296580 : cp_parser_type_parameter_key (cp_parser* parser)
   27772                 :             : {
   27773                 :             :   /* Look for the type-parameter-key.  */
   27774                 :      296580 :   enum tag_types tag_type = none_type;
   27775                 :      296580 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   27776                 :      289988 :   if ((tag_type = cp_parser_token_is_type_parameter_key (token)) != none_type)
   27777                 :             :     {
   27778                 :      296572 :       cp_lexer_consume_token (parser->lexer);
   27779                 :      296572 :       if (pedantic && tag_type == typename_type
   27780                 :          79 :           && cxx_dialect < cxx17)
   27781                 :             :         /* typename is not allowed in a template template parameter
   27782                 :             :            by the standard until C++17.  */
   27783                 :           2 :         pedwarn (token->location, OPT_Wc__17_extensions,
   27784                 :             :                  "ISO C++ forbids typename key in template template parameter;"
   27785                 :             :                  " use %<-std=c++17%> or %<-std=gnu++17%>");
   27786                 :             :     }
   27787                 :             :   else
   27788                 :           8 :     cp_parser_error (parser, "expected %<class%> or %<typename%>");
   27789                 :             : 
   27790                 :      296580 :   return;
   27791                 :             : }
   27792                 :             : 
   27793                 :             : /* Parse an (optional) member-specification.
   27794                 :             : 
   27795                 :             :    member-specification:
   27796                 :             :      member-declaration member-specification [opt]
   27797                 :             :      access-specifier : member-specification [opt]  */
   27798                 :             : 
   27799                 :             : static void
   27800                 :    23467571 : cp_parser_member_specification_opt (cp_parser* parser)
   27801                 :             : {
   27802                 :   172641421 :   while (true)
   27803                 :             :     {
   27804                 :   172641421 :       cp_token *token;
   27805                 :   172641421 :       enum rid keyword;
   27806                 :             : 
   27807                 :             :       /* Peek at the next token.  */
   27808                 :   172641421 :       token = cp_lexer_peek_token (parser->lexer);
   27809                 :             :       /* If it's a `}', or EOF then we've seen all the members.  */
   27810                 :   172641421 :       if (token->type == CPP_CLOSE_BRACE
   27811                 :             :           || token->type == CPP_EOF
   27812                 :             :           || token->type == CPP_PRAGMA_EOL)
   27813                 :             :         break;
   27814                 :             : 
   27815                 :             :       /* See if this token is a keyword.  */
   27816                 :   149173862 :       keyword = token->keyword;
   27817                 :   149173862 :       switch (keyword)
   27818                 :             :         {
   27819                 :    10670906 :         case RID_PUBLIC:
   27820                 :    10670906 :         case RID_PROTECTED:
   27821                 :    10670906 :         case RID_PRIVATE:
   27822                 :             :           /* Consume the access-specifier.  */
   27823                 :    10670906 :           cp_lexer_consume_token (parser->lexer);
   27824                 :             :           /* Remember which access-specifier is active.  */
   27825                 :    10670906 :           current_access_specifier = token->u.value;
   27826                 :             :           /* Look for the `:'.  */
   27827                 :    10670906 :           cp_parser_require (parser, CPP_COLON, RT_COLON);
   27828                 :    10670906 :           break;
   27829                 :             : 
   27830                 :   138502956 :         default:
   27831                 :             :           /* Accept #pragmas at class scope.  */
   27832                 :   138502956 :           if (token->type == CPP_PRAGMA)
   27833                 :             :             {
   27834                 :      378226 :               cp_parser_pragma (parser, pragma_member, NULL);
   27835                 :      378226 :               break;
   27836                 :             :             }
   27837                 :             : 
   27838                 :             :           /* Otherwise, the next construction must be a
   27839                 :             :              member-declaration.  */
   27840                 :   138124730 :           cp_parser_member_declaration (parser);
   27841                 :             :         }
   27842                 :             :     }
   27843                 :    23467559 : }
   27844                 :             : 
   27845                 :             : /* Parse a member-declaration.
   27846                 :             : 
   27847                 :             :    member-declaration:
   27848                 :             :      decl-specifier-seq [opt] member-declarator-list [opt] ;
   27849                 :             :      function-definition ; [opt]
   27850                 :             :      :: [opt] nested-name-specifier template [opt] unqualified-id ;
   27851                 :             :      using-declaration
   27852                 :             :      template-declaration
   27853                 :             :      alias-declaration
   27854                 :             : 
   27855                 :             :    member-declarator-list:
   27856                 :             :      member-declarator
   27857                 :             :      member-declarator-list , member-declarator
   27858                 :             : 
   27859                 :             :    member-declarator:
   27860                 :             :      declarator pure-specifier [opt]
   27861                 :             :      declarator constant-initializer [opt]
   27862                 :             :      identifier [opt] : constant-expression
   27863                 :             : 
   27864                 :             :    GNU Extensions:
   27865                 :             : 
   27866                 :             :    member-declaration:
   27867                 :             :      __extension__ member-declaration
   27868                 :             : 
   27869                 :             :    member-declarator:
   27870                 :             :      declarator attributes [opt] pure-specifier [opt]
   27871                 :             :      declarator attributes [opt] constant-initializer [opt]
   27872                 :             :      identifier [opt] attributes [opt] : constant-expression
   27873                 :             : 
   27874                 :             :    C++0x Extensions:
   27875                 :             : 
   27876                 :             :    member-declaration:
   27877                 :             :      static_assert-declaration  */
   27878                 :             : 
   27879                 :             : static void
   27880                 :   138221584 : cp_parser_member_declaration (cp_parser* parser)
   27881                 :             : {
   27882                 :   138221584 :   cp_decl_specifier_seq decl_specifiers;
   27883                 :   138221584 :   tree prefix_attributes;
   27884                 :   138221584 :   tree decl;
   27885                 :   138221584 :   int declares_class_or_enum;
   27886                 :   138221584 :   bool friend_p;
   27887                 :   138221584 :   cp_token *token = NULL;
   27888                 :   138221584 :   cp_token *decl_spec_token_start = NULL;
   27889                 :   138221584 :   cp_token *initializer_token_start = NULL;
   27890                 :   138221584 :   int saved_pedantic;
   27891                 :   138221584 :   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   27892                 :             : 
   27893                 :             :   /* Check for the `__extension__' keyword.  */
   27894                 :   138221584 :   if (cp_parser_extension_opt (parser, &saved_pedantic))
   27895                 :             :     {
   27896                 :             :       /* Recurse.  */
   27897                 :       96556 :       cp_parser_member_declaration (parser);
   27898                 :             :       /* Restore the old value of the PEDANTIC flag.  */
   27899                 :       96556 :       pedantic = saved_pedantic;
   27900                 :             : 
   27901                 :    30055996 :       return;
   27902                 :             :     }
   27903                 :             : 
   27904                 :             :   /* Check for a template-declaration.  */
   27905                 :   138125028 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
   27906                 :             :     {
   27907                 :             :       /* An explicit specialization here is an error condition, and we
   27908                 :             :          expect the specialization handler to detect and report this.  */
   27909                 :    19600265 :       if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS
   27910                 :    19600265 :           && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER)
   27911                 :          32 :         cp_parser_explicit_specialization (parser);
   27912                 :             :       else
   27913                 :    19600233 :         cp_parser_template_declaration (parser, /*member_p=*/true);
   27914                 :             : 
   27915                 :    19600265 :       return;
   27916                 :             :     }
   27917                 :             :   /* Check for a template introduction.  */
   27918                 :   118524763 :   else if (cp_parser_template_declaration_after_export (parser, true))
   27919                 :             :     return;
   27920                 :             : 
   27921                 :             :   /* Check for a using-declaration.  */
   27922                 :   118524760 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
   27923                 :             :     {
   27924                 :     8335321 :       if (cxx_dialect < cxx11)
   27925                 :             :         /* Parse the using-declaration.  */
   27926                 :        2093 :         cp_parser_using_declaration (parser, /*access_declaration_p=*/false);
   27927                 :     8333228 :       else if (cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_ENUM))
   27928                 :        1029 :         cp_parser_using_enum (parser);
   27929                 :             :       else
   27930                 :             :         {
   27931                 :     8332199 :           tree decl;
   27932                 :     8332199 :           bool alias_decl_expected;
   27933                 :     8332199 :           cp_parser_parse_tentatively (parser);
   27934                 :     8332199 :           decl = cp_parser_alias_declaration (parser);
   27935                 :             :           /* Note that if we actually see the '=' token after the
   27936                 :             :              identifier, cp_parser_alias_declaration commits the
   27937                 :             :              tentative parse.  In that case, we really expect an
   27938                 :             :              alias-declaration.  Otherwise, we expect a using
   27939                 :             :              declaration.  */
   27940                 :    16664398 :           alias_decl_expected =
   27941                 :     8332199 :             !cp_parser_uncommitted_to_tentative_parse_p (parser);
   27942                 :     8332199 :           cp_parser_parse_definitely (parser);
   27943                 :             : 
   27944                 :     8332199 :           if (alias_decl_expected)
   27945                 :     7480976 :             finish_member_declaration (decl);
   27946                 :             :           else
   27947                 :      851223 :             cp_parser_using_declaration (parser,
   27948                 :             :                                          /*access_declaration_p=*/false);
   27949                 :             :         }
   27950                 :     8335321 :       return;
   27951                 :             :     }
   27952                 :             : 
   27953                 :             :   /* Check for @defs.  */
   27954                 :   110189439 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_DEFS))
   27955                 :             :     {
   27956                 :           0 :       tree ivar, member;
   27957                 :           0 :       tree ivar_chains = cp_parser_objc_defs_expression (parser);
   27958                 :           0 :       ivar = ivar_chains;
   27959                 :           0 :       while (ivar)
   27960                 :             :         {
   27961                 :           0 :           member = ivar;
   27962                 :           0 :           ivar = TREE_CHAIN (member);
   27963                 :           0 :           TREE_CHAIN (member) = NULL_TREE;
   27964                 :           0 :           finish_member_declaration (member);
   27965                 :             :         }
   27966                 :             :       return;
   27967                 :             :     }
   27968                 :             : 
   27969                 :             :   /* If the next token is `static_assert' we have a static assertion.  */
   27970                 :   110189439 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC_ASSERT))
   27971                 :             :     {
   27972                 :     2023851 :       cp_parser_static_assert (parser, /*member_p=*/true);
   27973                 :     2023851 :       return;
   27974                 :             :     }
   27975                 :             : 
   27976                 :   108165588 :   parser->colon_corrects_to_scope_p = false;
   27977                 :             : 
   27978                 :   108165588 :   cp_omp_declare_simd_data odsd;
   27979                 :   108165588 :   if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
   27980                 :         152 :     goto out;
   27981                 :             : 
   27982                 :             :   /* Parse the decl-specifier-seq.  */
   27983                 :   108165436 :   decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
   27984                 :   108165436 :   cp_parser_decl_specifier_seq (parser,
   27985                 :             :                                 (CP_PARSER_FLAGS_OPTIONAL
   27986                 :             :                                  | CP_PARSER_FLAGS_TYPENAME_OPTIONAL),
   27987                 :             :                                 &decl_specifiers,
   27988                 :             :                                 &declares_class_or_enum);
   27989                 :             : 
   27990                 :   108165436 :   if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
   27991                 :        3010 :     cp_parser_handle_directive_omp_attributes (parser,
   27992                 :             :                                                &decl_specifiers.attributes,
   27993                 :             :                                                &odsd, true);
   27994                 :             : 
   27995                 :             :   /* Check for an invalid type-name.  */
   27996                 :   108165436 :   if (!decl_specifiers.any_type_specifiers_p
   27997                 :   108165436 :       && cp_parser_parse_and_diagnose_invalid_type_name (parser))
   27998                 :         237 :     goto out;
   27999                 :             :   /* If there is no declarator, then the decl-specifier-seq should
   28000                 :             :      specify a type.  */
   28001                 :   108165199 :   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   28002                 :             :     {
   28003                 :             :       /* If there was no decl-specifier-seq, and the next token is a
   28004                 :             :          `;', then we have something like:
   28005                 :             : 
   28006                 :             :            struct S { ; };
   28007                 :             : 
   28008                 :             :          [class.mem]
   28009                 :             : 
   28010                 :             :          Each member-declaration shall declare at least one member
   28011                 :             :          name of the class.  */
   28012                 :     2800476 :       if (!decl_specifiers.any_specifiers_p)
   28013                 :             :         {
   28014                 :          50 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   28015                 :          50 :           if (cxx_dialect < cxx11 && !in_system_header_at (token->location))
   28016                 :             :             {
   28017                 :          11 :               gcc_rich_location richloc (token->location);
   28018                 :          11 :               richloc.add_fixit_remove ();
   28019                 :          11 :               pedwarn (&richloc, OPT_Wpedantic, "extra %<;%>");
   28020                 :          11 :             }
   28021                 :             :         }
   28022                 :             :       else
   28023                 :             :         {
   28024                 :             :           /* See if this declaration is a friend.  */
   28025                 :     5600852 :           friend_p = cp_parser_friend_p (&decl_specifiers);
   28026                 :             :           /* If there were decl-specifiers, check to see if there was
   28027                 :             :              a class-declaration.  */
   28028                 :     2800426 :           tree type = check_tag_decl (&decl_specifiers,
   28029                 :             :                                       /*explicit_type_instantiation_p=*/false);
   28030                 :             :           /* Nested classes have already been added to the class, but
   28031                 :             :              a `friend' needs to be explicitly registered.  */
   28032                 :     2800426 :           if (friend_p)
   28033                 :             :             {
   28034                 :             :               /* If the `friend' keyword was present, the friend must
   28035                 :             :                  be introduced with a class-key.  */
   28036                 :      871042 :                if (!declares_class_or_enum && cxx_dialect < cxx11)
   28037                 :           6 :                  pedwarn (decl_spec_token_start->location, OPT_Wpedantic,
   28038                 :             :                           "in C++03 a class-key must be used "
   28039                 :             :                           "when declaring a friend");
   28040                 :             :                /* In this case:
   28041                 :             : 
   28042                 :             :                     template <typename T> struct A {
   28043                 :             :                       friend struct A<T>::B;
   28044                 :             :                     };
   28045                 :             : 
   28046                 :             :                   A<T>::B will be represented by a TYPENAME_TYPE, and
   28047                 :             :                   therefore not recognized by check_tag_decl.  */
   28048                 :      871042 :                if (!type)
   28049                 :             :                  {
   28050                 :      129225 :                    type = decl_specifiers.type;
   28051                 :      129225 :                    if (type && TREE_CODE (type) == TYPE_DECL)
   28052                 :      128085 :                      type = TREE_TYPE (type);
   28053                 :             :                  }
   28054                 :             :                /* Warn if an attribute cannot appear here, as per
   28055                 :             :                   [dcl.attr.grammar]/5.  But not when declares_class_or_enum:
   28056                 :             :                   we ignore attributes in elaborated-type-specifiers.  */
   28057                 :      871042 :                if (!declares_class_or_enum
   28058                 :      871042 :                    && cxx11_attribute_p (decl_specifiers.attributes))
   28059                 :             :                  {
   28060                 :           9 :                    decl_specifiers.attributes = NULL_TREE;
   28061                 :           9 :                    if (warning_at (decl_spec_token_start->location,
   28062                 :             :                                    OPT_Wattributes, "attribute ignored"))
   28063                 :           9 :                      inform (decl_spec_token_start->location, "an attribute "
   28064                 :             :                              "that appertains to a friend declaration that "
   28065                 :             :                              "is not a definition is ignored");
   28066                 :             :                  }
   28067                 :      871042 :                if (!type || !TYPE_P (type))
   28068                 :          35 :                  error_at (decl_spec_token_start->location,
   28069                 :             :                            "friend declaration does not name a class or "
   28070                 :             :                            "function");
   28071                 :             :                else
   28072                 :      871007 :                  make_friend_class (current_class_type, type,
   28073                 :             :                                     /*complain=*/true);
   28074                 :             :             }
   28075                 :             :           /* If there is no TYPE, an error message will already have
   28076                 :             :              been issued.  */
   28077                 :     1929384 :           else if (!type || type == error_mark_node)
   28078                 :             :             ;
   28079                 :             :           /* An anonymous aggregate has to be handled specially; such
   28080                 :             :              a declaration really declares a data member (with a
   28081                 :             :              particular type), as opposed to a nested class.  */
   28082                 :     1929254 :           else if (ANON_AGGR_TYPE_P (type))
   28083                 :             :             {
   28084                 :             :               /* C++11 9.5/6.  */
   28085                 :       88188 :               if (decl_specifiers.storage_class != sc_none)
   28086                 :          17 :                 error_at (decl_spec_token_start->location,
   28087                 :             :                           "a storage class on an anonymous aggregate "
   28088                 :             :                           "in class scope is not allowed");
   28089                 :             : 
   28090                 :             :               /* Remove constructors and such from TYPE, now that we
   28091                 :             :                  know it is an anonymous aggregate.  */
   28092                 :       88188 :               fixup_anonymous_aggr (type);
   28093                 :             :               /* And make the corresponding data member.  */
   28094                 :       88188 :               decl = build_decl (decl_spec_token_start->location,
   28095                 :             :                                  FIELD_DECL, NULL_TREE, type);
   28096                 :             :               /* Add it to the class.  */
   28097                 :       88188 :               finish_member_declaration (decl);
   28098                 :             :             }
   28099                 :             :           else
   28100                 :     1841066 :             cp_parser_check_access_in_redeclaration
   28101                 :     1841066 :                                               (TYPE_NAME (type),
   28102                 :             :                                                decl_spec_token_start->location);
   28103                 :             :         }
   28104                 :             :     }
   28105                 :             :   else
   28106                 :             :     {
   28107                 :   105364723 :       bool assume_semicolon = false;
   28108                 :             : 
   28109                 :             :       /* Clear attributes from the decl_specifiers but keep them
   28110                 :             :          around as prefix attributes that apply them to the entity
   28111                 :             :          being declared.  */
   28112                 :   105364723 :       prefix_attributes = decl_specifiers.attributes;
   28113                 :   105364723 :       decl_specifiers.attributes = NULL_TREE;
   28114                 :   105364723 :       if (parser->omp_declare_simd
   28115                 :         256 :           && (parser->omp_declare_simd->attribs[0]
   28116                 :             :               == &decl_specifiers.attributes))
   28117                 :           6 :         parser->omp_declare_simd->attribs[0] = &prefix_attributes;
   28118                 :             : 
   28119                 :             :       /* See if these declarations will be friends.  */
   28120                 :   105364723 :       friend_p = cp_parser_friend_p (&decl_specifiers);
   28121                 :             : 
   28122                 :             :       /* Keep going until we hit the `;' at the end of the
   28123                 :             :          declaration.  */
   28124                 :   162288074 :       while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   28125                 :             :         {
   28126                 :   105560589 :           tree attributes = NULL_TREE;
   28127                 :   105560589 :           tree first_attribute;
   28128                 :   105560589 :           tree initializer;
   28129                 :   105560589 :           bool named_bitfld = false;
   28130                 :             : 
   28131                 :             :           /* Peek at the next token.  */
   28132                 :   105560589 :           token = cp_lexer_peek_token (parser->lexer);
   28133                 :             : 
   28134                 :             :           /* The following code wants to know early if it is a bit-field
   28135                 :             :              or some other declaration.  Attributes can appear before
   28136                 :             :              the `:' token.  Skip over them without consuming any tokens
   28137                 :             :              to peek if they are followed by `:'.  */
   28138                 :   105560589 :           if (cp_next_tokens_can_be_attribute_p (parser)
   28139                 :   105560589 :               || (token->type == CPP_NAME
   28140                 :    80079272 :                   && cp_nth_tokens_can_be_attribute_p (parser, 2)
   28141                 :             :                   && (named_bitfld = true)))
   28142                 :             :             {
   28143                 :       51774 :               size_t n
   28144                 :       51774 :                 = cp_parser_skip_attributes_opt (parser, 1 + named_bitfld);
   28145                 :       51774 :               token = cp_lexer_peek_nth_token (parser->lexer, n);
   28146                 :             :             }
   28147                 :             : 
   28148                 :             :           /* Check for a bitfield declaration.  */
   28149                 :   105560589 :           if (token->type == CPP_COLON
   28150                 :   105560589 :               || (token->type == CPP_NAME
   28151                 :    80027506 :                   && token == cp_lexer_peek_token (parser->lexer)
   28152                 :    80027502 :                   && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON)
   28153                 :             :                   && (named_bitfld = true)))
   28154                 :             :             {
   28155                 :      341614 :               tree identifier;
   28156                 :      341614 :               tree width;
   28157                 :      341614 :               tree late_attributes = NULL_TREE;
   28158                 :      341614 :               location_t id_location
   28159                 :      341614 :                 = cp_lexer_peek_token (parser->lexer)->location;
   28160                 :             : 
   28161                 :      341614 :               if (named_bitfld)
   28162                 :      212752 :                 identifier = cp_parser_identifier (parser);
   28163                 :             :               else
   28164                 :             :                 identifier = NULL_TREE;
   28165                 :             : 
   28166                 :             :               /* Look for attributes that apply to the bitfield.  */
   28167                 :      341614 :               attributes = cp_parser_attributes_opt (parser);
   28168                 :             : 
   28169                 :             :               /* Consume the `:' token.  */
   28170                 :      341614 :               cp_lexer_consume_token (parser->lexer);
   28171                 :             : 
   28172                 :             :               /* Get the width of the bitfield.  */
   28173                 :      341614 :               width = cp_parser_constant_expression (parser, false, NULL,
   28174                 :      341614 :                                                      cxx_dialect >= cxx11);
   28175                 :             : 
   28176                 :             :               /* In C++20 and as extension for C++11 and above we allow
   28177                 :             :                  default member initializers for bit-fields.  */
   28178                 :      341614 :               initializer = NULL_TREE;
   28179                 :      341614 :               if (cxx_dialect >= cxx11
   28180                 :      341614 :                   && (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
   28181                 :      335342 :                       || cp_lexer_next_token_is (parser->lexer,
   28182                 :             :                                                  CPP_OPEN_BRACE)))
   28183                 :             :                 {
   28184                 :        6413 :                   location_t loc
   28185                 :        6413 :                     = cp_lexer_peek_token (parser->lexer)->location;
   28186                 :        6413 :                   if (cxx_dialect < cxx20
   28187                 :          58 :                       && identifier != NULL_TREE)
   28188                 :          46 :                     pedwarn (loc, OPT_Wc__20_extensions,
   28189                 :             :                              "default member initializers for bit-fields "
   28190                 :             :                              "only available with %<-std=c++20%> or "
   28191                 :             :                              "%<-std=gnu++20%>");
   28192                 :             : 
   28193                 :       12826 :                   initializer = cp_parser_save_nsdmi (parser);
   28194                 :        6413 :                   if (identifier == NULL_TREE)
   28195                 :             :                     {
   28196                 :          18 :                       error_at (loc, "default member initializer for "
   28197                 :             :                                      "unnamed bit-field");
   28198                 :          18 :                       initializer = NULL_TREE;
   28199                 :             :                     }
   28200                 :             :                 }
   28201                 :             :               else
   28202                 :             :                 {
   28203                 :             :                   /* Look for attributes that apply to the bitfield after
   28204                 :             :                      the `:' token and width.  This is where GCC used to
   28205                 :             :                      parse attributes in the past, pedwarn if there is
   28206                 :             :                      a std attribute.  */
   28207                 :      335201 :                   if (cp_next_tokens_can_be_std_attribute_p (parser))
   28208                 :           6 :                     pedwarn (input_location, OPT_Wpedantic,
   28209                 :             :                              "ISO C++ allows bit-field attributes only "
   28210                 :             :                              "before the %<:%> token");
   28211                 :             : 
   28212                 :      335201 :                   late_attributes = cp_parser_attributes_opt (parser);
   28213                 :             :                 }
   28214                 :             : 
   28215                 :      341614 :               attributes = attr_chainon (attributes, late_attributes);
   28216                 :             : 
   28217                 :             :               /* Remember which attributes are prefix attributes and
   28218                 :             :                  which are not.  */
   28219                 :      341614 :               first_attribute = attributes;
   28220                 :             :               /* Combine the attributes.  */
   28221                 :      341614 :               attributes = attr_chainon (prefix_attributes, attributes);
   28222                 :             : 
   28223                 :             :               /* Create the bitfield declaration.  */
   28224                 :      554366 :               decl = grokbitfield (identifier
   28225                 :      212752 :                                    ? make_id_declarator (NULL_TREE,
   28226                 :             :                                                          identifier,
   28227                 :             :                                                          sfk_none,
   28228                 :             :                                                          id_location)
   28229                 :             :                                    : NULL,
   28230                 :             :                                    &decl_specifiers,
   28231                 :             :                                    width, initializer,
   28232                 :             :                                    attributes);
   28233                 :             :             }
   28234                 :             :           else
   28235                 :             :             {
   28236                 :   105218975 :               cp_declarator *declarator;
   28237                 :   105218975 :               tree asm_specification;
   28238                 :   105218975 :               int ctor_dtor_or_conv_p;
   28239                 :   105218975 :               bool static_p = (decl_specifiers.storage_class == sc_static);
   28240                 :   105218975 :               cp_parser_flags flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
   28241                 :             :               /* We can't delay parsing for friends,
   28242                 :             :                  alias-declarations, and typedefs, even though the
   28243                 :             :                  standard seems to require it.  */
   28244                 :   105218975 :               if (!friend_p
   28245                 :   105218975 :                   && !decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
   28246                 :             :                 flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT;
   28247                 :             : 
   28248                 :             :               /* Parse the declarator.  */
   28249                 :   105218975 :               declarator
   28250                 :   105218975 :                 = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
   28251                 :             :                                         flags,
   28252                 :             :                                         &ctor_dtor_or_conv_p,
   28253                 :             :                                         /*parenthesized_p=*/NULL,
   28254                 :             :                                         /*member_p=*/true,
   28255                 :             :                                         friend_p, static_p);
   28256                 :             : 
   28257                 :             :               /* If something went wrong parsing the declarator, make sure
   28258                 :             :                  that we at least consume some tokens.  */
   28259                 :   105218975 :               if (declarator == cp_error_declarator)
   28260                 :             :                 {
   28261                 :             :                   /* Skip to the end of the statement.  */
   28262                 :         239 :                   cp_parser_skip_to_end_of_statement (parser);
   28263                 :             :                   /* If the next token is not a semicolon, that is
   28264                 :             :                      probably because we just skipped over the body of
   28265                 :             :                      a function.  So, we consume a semicolon if
   28266                 :             :                      present, but do not issue an error message if it
   28267                 :             :                      is not present.  */
   28268                 :         239 :                   if (cp_lexer_next_token_is (parser->lexer,
   28269                 :             :                                               CPP_SEMICOLON))
   28270                 :         160 :                     cp_lexer_consume_token (parser->lexer);
   28271                 :    48637102 :                   goto out;
   28272                 :             :                 }
   28273                 :             : 
   28274                 :             :               /* Handle class-scope non-template C++17 deduction guides.  */
   28275                 :   105218736 :               cp_parser_maybe_adjust_declarator_for_dguide (parser,
   28276                 :             :                                                             &decl_specifiers,
   28277                 :             :                                                             declarator,
   28278                 :             :                                                             &ctor_dtor_or_conv_p);
   28279                 :             : 
   28280                 :   105218736 :               if (declares_class_or_enum & 2)
   28281                 :      222241 :                 cp_parser_check_for_definition_in_return_type
   28282                 :      222241 :                                             (declarator, decl_specifiers.type,
   28283                 :             :                                              decl_specifiers.locations[ds_type_spec]);
   28284                 :             : 
   28285                 :             :               /* Look for an asm-specification.  */
   28286                 :   105218736 :               asm_specification = cp_parser_asm_specification_opt (parser);
   28287                 :             :               /* Look for attributes that apply to the declaration.  */
   28288                 :   105218736 :               attributes = cp_parser_attributes_opt (parser);
   28289                 :             :               /* Remember which attributes are prefix attributes and
   28290                 :             :                  which are not.  */
   28291                 :   105218736 :               first_attribute = attributes;
   28292                 :             :               /* Combine the attributes.  */
   28293                 :   105218736 :               attributes = attr_chainon (prefix_attributes, attributes);
   28294                 :             : 
   28295                 :             :               /* If it's an `=', then we have a constant-initializer or a
   28296                 :             :                  pure-specifier.  It is not correct to parse the
   28297                 :             :                  initializer before registering the member declaration
   28298                 :             :                  since the member declaration should be in scope while
   28299                 :             :                  its initializer is processed.  However, the rest of the
   28300                 :             :                  front end does not yet provide an interface that allows
   28301                 :             :                  us to handle this correctly.  */
   28302                 :   105218736 :               if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   28303                 :             :                 {
   28304                 :             :                   /* In [class.mem]:
   28305                 :             : 
   28306                 :             :                      A pure-specifier shall be used only in the declaration of
   28307                 :             :                      a virtual function.
   28308                 :             : 
   28309                 :             :                      A member-declarator can contain a constant-initializer
   28310                 :             :                      only if it declares a static member of integral or
   28311                 :             :                      enumeration type.
   28312                 :             : 
   28313                 :             :                      Therefore, if the DECLARATOR is for a function, we look
   28314                 :             :                      for a pure-specifier; otherwise, we look for a
   28315                 :             :                      constant-initializer.  When we call `grokfield', it will
   28316                 :             :                      perform more stringent semantics checks.  */
   28317                 :    17430158 :                   initializer_token_start = cp_lexer_peek_token (parser->lexer);
   28318                 :    17430158 :                   declarator->init_loc = initializer_token_start->location;
   28319                 :    17430158 :                   if (function_declarator_p (declarator)
   28320                 :    17430158 :                       || (decl_specifiers.type
   28321                 :     9227252 :                           && TREE_CODE (decl_specifiers.type) == TYPE_DECL
   28322                 :     3021697 :                           && declarator->kind == cdk_id
   28323                 :     2895474 :                           && (TREE_CODE (TREE_TYPE (decl_specifiers.type))
   28324                 :             :                               == FUNCTION_TYPE)))
   28325                 :     8199439 :                     initializer = cp_parser_pure_specifier (parser);
   28326                 :     9230719 :                   else if (decl_specifiers.storage_class != sc_static)
   28327                 :      736310 :                     initializer = cp_parser_save_nsdmi (parser);
   28328                 :     8494409 :                   else if (cxx_dialect >= cxx11)
   28329                 :             :                     {
   28330                 :             :                       /* Don't require a constant rvalue in C++11, since we
   28331                 :             :                          might want a reference constant.  We'll enforce
   28332                 :             :                          constancy later.  */
   28333                 :     8472784 :                       cp_lexer_consume_token (parser->lexer);
   28334                 :             :                       /* Parse the initializer.  */
   28335                 :     8472784 :                       initializer = cp_parser_initializer_clause (parser);
   28336                 :             :                     }
   28337                 :             :                   else
   28338                 :             :                     /* Parse the initializer.  */
   28339                 :       21625 :                     initializer = cp_parser_constant_initializer (parser);
   28340                 :             :                 }
   28341                 :    87788578 :               else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
   28342                 :    87788578 :                        && !function_declarator_p (declarator))
   28343                 :             :                 {
   28344                 :      127771 :                   declarator->init_loc
   28345                 :      127771 :                     = cp_lexer_peek_token (parser->lexer)->location;
   28346                 :      127771 :                   if (decl_specifiers.storage_class != sc_static)
   28347                 :      113827 :                     initializer = cp_parser_save_nsdmi (parser);
   28348                 :             :                   else
   28349                 :       13944 :                     initializer = cp_parser_initializer (parser);
   28350                 :             :                 }
   28351                 :             :               /* Detect invalid bit-field cases such as
   28352                 :             : 
   28353                 :             :                    int *p : 4;
   28354                 :             :                    int &&r : 3;
   28355                 :             : 
   28356                 :             :                  and similar.  */
   28357                 :    87660807 :               else if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
   28358                 :             :                        /* If there were no type specifiers, it was a
   28359                 :             :                           constructor.  */
   28360                 :    87660807 :                        && decl_specifiers.any_type_specifiers_p)
   28361                 :             :                 {
   28362                 :             :                   /* This is called for a decent diagnostic only.  */
   28363                 :          27 :                   tree d = grokdeclarator (declarator, &decl_specifiers,
   28364                 :             :                                            BITFIELD, /*initialized=*/false,
   28365                 :             :                                            &attributes);
   28366                 :          27 :                   if (!error_operand_p (d))
   28367                 :          27 :                     error_at (DECL_SOURCE_LOCATION (d),
   28368                 :             :                               "bit-field %qD has non-integral type %qT",
   28369                 :          27 :                               d, TREE_TYPE (d));
   28370                 :          27 :                   cp_parser_skip_to_end_of_statement (parser);
   28371                 :             :                   /* Avoid "extra ;" pedwarns.  */
   28372                 :          27 :                   if (cp_lexer_next_token_is (parser->lexer,
   28373                 :             :                                               CPP_SEMICOLON))
   28374                 :          27 :                     cp_lexer_consume_token (parser->lexer);
   28375                 :          27 :                   goto out;
   28376                 :             :                 }
   28377                 :             :               /* Otherwise, there is no initializer.  */
   28378                 :             :               else
   28379                 :             :                 initializer = NULL_TREE;
   28380                 :             : 
   28381                 :             :               /* See if we are probably looking at a function
   28382                 :             :                  definition.  We are certainly not looking at a
   28383                 :             :                  member-declarator.  Calling `grokfield' has
   28384                 :             :                  side-effects, so we must not do it unless we are sure
   28385                 :             :                  that we are looking at a member-declarator.  */
   28386                 :   105218705 :               if (cp_parser_token_starts_function_definition_p
   28387                 :   105218705 :                   (cp_lexer_peek_token (parser->lexer)))
   28388                 :             :                 {
   28389                 :             :                   /* The grammar does not allow a pure-specifier to be
   28390                 :             :                      used when a member function is defined.  (It is
   28391                 :             :                      possible that this fact is an oversight in the
   28392                 :             :                      standard, since a pure function may be defined
   28393                 :             :                      outside of the class-specifier.  */
   28394                 :    48636836 :                   if (initializer && initializer_token_start)
   28395                 :           4 :                     error_at (initializer_token_start->location,
   28396                 :             :                               "pure-specifier on function-definition");
   28397                 :    48636836 :                   decl = cp_parser_save_member_function_body (parser,
   28398                 :             :                                                               &decl_specifiers,
   28399                 :             :                                                               declarator,
   28400                 :             :                                                               attributes);
   28401                 :             : 
   28402                 :    48636836 :                   if (parser->fully_implicit_function_template_p)
   28403                 :        5264 :                     decl = finish_fully_implicit_template (parser, decl);
   28404                 :             :                   /* If the member was not a friend, declare it here.  */
   28405                 :    48636836 :                   if (!friend_p)
   28406                 :    46780475 :                     finish_member_declaration (decl);
   28407                 :             :                   /* Peek at the next token.  */
   28408                 :    48636836 :                   token = cp_lexer_peek_token (parser->lexer);
   28409                 :             :                   /* If the next token is a semicolon, consume it.  */
   28410                 :    48636836 :                   if (token->type == CPP_SEMICOLON)
   28411                 :             :                     {
   28412                 :       24226 :                       location_t semicolon_loc
   28413                 :       24226 :                         = cp_lexer_consume_token (parser->lexer)->location;
   28414                 :       24226 :                       gcc_rich_location richloc (semicolon_loc);
   28415                 :       24226 :                       richloc.add_fixit_remove ();
   28416                 :       24226 :                       warning_at (&richloc, OPT_Wextra_semi,
   28417                 :             :                                   "extra %<;%> after in-class "
   28418                 :             :                                   "function definition");
   28419                 :       24226 :                     }
   28420                 :    48636836 :                   goto out;
   28421                 :             :                 }
   28422                 :             :               else
   28423                 :    56581869 :                 if (declarator->kind == cdk_function)
   28424                 :    15039384 :                   declarator->id_loc = token->location;
   28425                 :             : 
   28426                 :             :               /* Create the declaration.  */
   28427                 :    56581869 :               decl = grokfield (declarator, &decl_specifiers,
   28428                 :             :                                 initializer, /*init_const_expr_p=*/true,
   28429                 :             :                                 asm_specification, attributes);
   28430                 :             : 
   28431                 :    56581861 :               if (parser->fully_implicit_function_template_p)
   28432                 :             :                 {
   28433                 :         104 :                   if (friend_p)
   28434                 :           7 :                     finish_fully_implicit_template (parser, 0);
   28435                 :             :                   else
   28436                 :          97 :                     decl = finish_fully_implicit_template (parser, decl);
   28437                 :             :                 }
   28438                 :             :             }
   28439                 :             : 
   28440                 :    56923475 :           cp_finalize_omp_declare_simd (parser, decl);
   28441                 :    56923475 :           cp_finalize_oacc_routine (parser, decl, false);
   28442                 :             : 
   28443                 :             :           /* Reset PREFIX_ATTRIBUTES.  */
   28444                 :    56923475 :           if (attributes != error_mark_node)
   28445                 :             :             {
   28446                 :    57012890 :               while (attributes && TREE_CHAIN (attributes) != first_attribute)
   28447                 :       89421 :                 attributes = TREE_CHAIN (attributes);
   28448                 :    56923469 :               if (attributes)
   28449                 :      563360 :                 TREE_CHAIN (attributes) = NULL_TREE;
   28450                 :             :             }
   28451                 :             : 
   28452                 :             :           /* If there is any qualification still in effect, clear it
   28453                 :             :              now; we will be starting fresh with the next declarator.  */
   28454                 :    56923475 :           parser->scope = NULL_TREE;
   28455                 :    56923475 :           parser->qualifying_scope = NULL_TREE;
   28456                 :    56923475 :           parser->object_scope = NULL_TREE;
   28457                 :             :           /* If it's a `,', then there are more declarators.  */
   28458                 :    56923475 :           if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   28459                 :             :             {
   28460                 :      195874 :               cp_lexer_consume_token (parser->lexer);
   28461                 :      195874 :               if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   28462                 :             :                 {
   28463                 :           8 :                   cp_token *token = cp_lexer_previous_token (parser->lexer);
   28464                 :           8 :                   gcc_rich_location richloc (token->location);
   28465                 :           8 :                   richloc.add_fixit_remove ();
   28466                 :           8 :                   error_at (&richloc, "stray %<,%> at end of "
   28467                 :             :                             "member declaration");
   28468                 :           8 :                 }
   28469                 :             :             }
   28470                 :             :           /* If the next token isn't a `;', then we have a parse error.  */
   28471                 :    56727601 :           else if (cp_lexer_next_token_is_not (parser->lexer,
   28472                 :             :                                                CPP_SEMICOLON))
   28473                 :             :             {
   28474                 :             :               /* The next token might be a ways away from where the
   28475                 :             :                  actual semicolon is missing.  Find the previous token
   28476                 :             :                  and use that for our error position.  */
   28477                 :         124 :               cp_token *token = cp_lexer_previous_token (parser->lexer);
   28478                 :         124 :               gcc_rich_location richloc (token->location);
   28479                 :         124 :               richloc.add_fixit_insert_after (";");
   28480                 :         124 :               error_at (&richloc, "expected %<;%> at end of "
   28481                 :             :                         "member declaration");
   28482                 :             : 
   28483                 :             :               /* Assume that the user meant to provide a semicolon.  If
   28484                 :             :                  we were to cp_parser_skip_to_end_of_statement, we might
   28485                 :             :                  skip to a semicolon inside a member function definition
   28486                 :             :                  and issue nonsensical error messages.  */
   28487                 :         124 :               assume_semicolon = true;
   28488                 :         124 :             }
   28489                 :             : 
   28490                 :    56923475 :           if (decl)
   28491                 :             :             {
   28492                 :             :               /* Add DECL to the list of members.  */
   28493                 :    56923435 :               if (!friend_p
   28494                 :             :                   /* Explicitly include, eg, NSDMIs, for better error
   28495                 :             :                      recovery (c++/58650).  */
   28496                 :    56923435 :                   || !DECL_DECLARES_FUNCTION_P (decl))
   28497                 :    56686408 :                 finish_member_declaration (decl);
   28498                 :             : 
   28499                 :    56923435 :               if (DECL_DECLARES_FUNCTION_P (decl))
   28500                 :    19503346 :                 cp_parser_save_default_args (parser, STRIP_TEMPLATE (decl));
   28501                 :    37420089 :               else if (TREE_CODE (decl) == FIELD_DECL
   28502                 :    37420089 :                        && DECL_INITIAL (decl))
   28503                 :             :                 /* Add DECL to the queue of NSDMI to be parsed later.  */
   28504                 :      856482 :                 vec_safe_push (unparsed_nsdmis, decl);
   28505                 :             :             }
   28506                 :             : 
   28507                 :    56923475 :           if (assume_semicolon)
   28508                 :         124 :             goto out;
   28509                 :             :         }
   28510                 :             :     }
   28511                 :             : 
   28512                 :    59527961 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   28513                 :   108165576 :  out:
   28514                 :   108165576 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   28515                 :   108165576 :   cp_finalize_omp_declare_simd (parser, &odsd);
   28516                 :             : }
   28517                 :             : 
   28518                 :             : /* Parse a pure-specifier.
   28519                 :             : 
   28520                 :             :    pure-specifier:
   28521                 :             :      = 0
   28522                 :             : 
   28523                 :             :    Returns INTEGER_ZERO_NODE if a pure specifier is found.
   28524                 :             :    Otherwise, ERROR_MARK_NODE is returned.  */
   28525                 :             : 
   28526                 :             : static tree
   28527                 :     8746946 : cp_parser_pure_specifier (cp_parser* parser)
   28528                 :             : {
   28529                 :     8746946 :   cp_token *token;
   28530                 :             : 
   28531                 :             :   /* Look for the `=' token.  */
   28532                 :     8746946 :   if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   28533                 :           0 :     return error_mark_node;
   28534                 :             :   /* Look for the `0' token.  */
   28535                 :     8746946 :   token = cp_lexer_peek_token (parser->lexer);
   28536                 :             : 
   28537                 :     8746946 :   if (token->type == CPP_EOF
   28538                 :     8746942 :       || token->type == CPP_PRAGMA_EOL)
   28539                 :           4 :     return error_mark_node;
   28540                 :             : 
   28541                 :     8746942 :   cp_lexer_consume_token (parser->lexer);
   28542                 :             : 
   28543                 :             :   /* Accept = default or = delete in c++0x mode.  */
   28544                 :     8746942 :   if (token->keyword == RID_DEFAULT
   28545                 :     3563747 :       || token->keyword == RID_DELETE)
   28546                 :             :     {
   28547                 :     8402033 :       maybe_warn_cpp0x (CPP0X_DEFAULTED_DELETED);
   28548                 :     8402033 :       return token->u.value;
   28549                 :             :     }
   28550                 :             : 
   28551                 :             :   /* c_lex_with_flags marks a single digit '0' with PURE_ZERO.  */
   28552                 :      344909 :   if (token->type != CPP_NUMBER || !(token->flags & PURE_ZERO))
   28553                 :             :     {
   28554                 :          48 :       cp_parser_error (parser,
   28555                 :             :                        "invalid pure specifier (only %<= 0%> is allowed)");
   28556                 :          48 :       cp_parser_skip_to_end_of_statement (parser);
   28557                 :          48 :       return error_mark_node;
   28558                 :             :     }
   28559                 :      344861 :   if (PROCESSING_REAL_TEMPLATE_DECL_P ())
   28560                 :             :     {
   28561                 :           4 :       error_at (token->location, "templates may not be %<virtual%>");
   28562                 :           4 :       return error_mark_node;
   28563                 :             :     }
   28564                 :             : 
   28565                 :      344857 :   return integer_zero_node;
   28566                 :             : }
   28567                 :             : 
   28568                 :             : /* Parse a constant-initializer.
   28569                 :             : 
   28570                 :             :    constant-initializer:
   28571                 :             :      = constant-expression
   28572                 :             : 
   28573                 :             :    Returns a representation of the constant-expression.  */
   28574                 :             : 
   28575                 :             : static tree
   28576                 :       21625 : cp_parser_constant_initializer (cp_parser* parser)
   28577                 :             : {
   28578                 :             :   /* Look for the `=' token.  */
   28579                 :       21625 :   if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   28580                 :           0 :     return error_mark_node;
   28581                 :             : 
   28582                 :             :   /* It is invalid to write:
   28583                 :             : 
   28584                 :             :        struct S { static const int i = { 7 }; };
   28585                 :             : 
   28586                 :             :      */
   28587                 :       21625 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   28588                 :             :     {
   28589                 :           1 :       cp_parser_error (parser,
   28590                 :             :                        "a brace-enclosed initializer is not allowed here");
   28591                 :             :       /* Consume the opening brace.  */
   28592                 :           1 :       matching_braces braces;
   28593                 :           1 :       braces.consume_open (parser);
   28594                 :             :       /* Skip the initializer.  */
   28595                 :           1 :       cp_parser_skip_to_closing_brace (parser);
   28596                 :             :       /* Look for the trailing `}'.  */
   28597                 :           1 :       braces.require_close (parser);
   28598                 :             : 
   28599                 :           1 :       return error_mark_node;
   28600                 :             :     }
   28601                 :             : 
   28602                 :       21624 :   return cp_parser_constant_expression (parser);
   28603                 :             : }
   28604                 :             : 
   28605                 :             : /* Derived classes [gram.class.derived] */
   28606                 :             : 
   28607                 :             : /* Parse a base-clause.
   28608                 :             : 
   28609                 :             :    base-clause:
   28610                 :             :      : base-specifier-list
   28611                 :             : 
   28612                 :             :    base-specifier-list:
   28613                 :             :      base-specifier ... [opt]
   28614                 :             :      base-specifier-list , base-specifier ... [opt]
   28615                 :             : 
   28616                 :             :    Returns a TREE_LIST representing the base-classes, in the order in
   28617                 :             :    which they were declared.  The representation of each node is as
   28618                 :             :    described by cp_parser_base_specifier.
   28619                 :             : 
   28620                 :             :    In the case that no bases are specified, this function will return
   28621                 :             :    NULL_TREE, not ERROR_MARK_NODE.  */
   28622                 :             : 
   28623                 :             : static tree
   28624                 :     9880956 : cp_parser_base_clause (cp_parser* parser)
   28625                 :             : {
   28626                 :     9880956 :   tree bases = NULL_TREE;
   28627                 :             : 
   28628                 :             :   /* Look for the `:' that begins the list.  */
   28629                 :     9880956 :   cp_parser_require (parser, CPP_COLON, RT_COLON);
   28630                 :             : 
   28631                 :             :   /* Scan the base-specifier-list.  */
   28632                 :    10665490 :   while (true)
   28633                 :             :     {
   28634                 :    10273223 :       cp_token *token;
   28635                 :    10273223 :       tree base;
   28636                 :    10273223 :       bool pack_expansion_p = false;
   28637                 :             : 
   28638                 :             :       /* Look for the base-specifier.  */
   28639                 :    10273223 :       base = cp_parser_base_specifier (parser);
   28640                 :             :       /* Look for the (optional) ellipsis. */
   28641                 :    10273223 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   28642                 :             :         {
   28643                 :             :           /* Consume the `...'. */
   28644                 :       18507 :           cp_lexer_consume_token (parser->lexer);
   28645                 :             : 
   28646                 :       18507 :           pack_expansion_p = true;
   28647                 :             :         }
   28648                 :             : 
   28649                 :             :       /* Add BASE to the front of the list.  */
   28650                 :    10273223 :       if (base && base != error_mark_node)
   28651                 :             :         {
   28652                 :    10273128 :           if (pack_expansion_p)
   28653                 :             :             /* Make this a pack expansion type. */
   28654                 :       18507 :             TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
   28655                 :             : 
   28656                 :    10273128 :           if (!check_for_bare_parameter_packs (TREE_VALUE (base)))
   28657                 :             :             {
   28658                 :    10273110 :               TREE_CHAIN (base) = bases;
   28659                 :    10273110 :               bases = base;
   28660                 :             :             }
   28661                 :             :         }
   28662                 :             :       /* Peek at the next token.  */
   28663                 :    10273223 :       token = cp_lexer_peek_token (parser->lexer);
   28664                 :             :       /* If it's not a comma, then the list is complete.  */
   28665                 :    10273223 :       if (token->type != CPP_COMMA)
   28666                 :             :         break;
   28667                 :             :       /* Consume the `,'.  */
   28668                 :      392267 :       cp_lexer_consume_token (parser->lexer);
   28669                 :      392267 :     }
   28670                 :             : 
   28671                 :             :   /* PARSER->SCOPE may still be non-NULL at this point, if the last
   28672                 :             :      base class had a qualified name.  However, the next name that
   28673                 :             :      appears is certainly not qualified.  */
   28674                 :     9880956 :   parser->scope = NULL_TREE;
   28675                 :     9880956 :   parser->qualifying_scope = NULL_TREE;
   28676                 :     9880956 :   parser->object_scope = NULL_TREE;
   28677                 :             : 
   28678                 :     9880956 :   return nreverse (bases);
   28679                 :             : }
   28680                 :             : 
   28681                 :             : /* Parse a base-specifier.
   28682                 :             : 
   28683                 :             :    base-specifier:
   28684                 :             :      :: [opt] nested-name-specifier [opt] class-name
   28685                 :             :      virtual access-specifier [opt] :: [opt] nested-name-specifier
   28686                 :             :        [opt] class-name
   28687                 :             :      access-specifier virtual [opt] :: [opt] nested-name-specifier
   28688                 :             :        [opt] class-name
   28689                 :             : 
   28690                 :             :    Returns a TREE_LIST.  The TREE_PURPOSE will be one of
   28691                 :             :    ACCESS_{DEFAULT,PUBLIC,PROTECTED,PRIVATE}_[VIRTUAL]_NODE to
   28692                 :             :    indicate the specifiers provided.  The TREE_VALUE will be a TYPE
   28693                 :             :    (or the ERROR_MARK_NODE) indicating the type that was specified.  */
   28694                 :             : 
   28695                 :             : static tree
   28696                 :    10273223 : cp_parser_base_specifier (cp_parser* parser)
   28697                 :             : {
   28698                 :    10273223 :   cp_token *token;
   28699                 :    10273223 :   bool done = false;
   28700                 :    10273223 :   bool virtual_p = false;
   28701                 :    10273223 :   bool duplicate_virtual_error_issued_p = false;
   28702                 :    10273223 :   bool duplicate_access_error_issued_p = false;
   28703                 :    10273223 :   bool class_scope_p, template_p;
   28704                 :    10273223 :   tree access = access_default_node;
   28705                 :    10273223 :   tree type;
   28706                 :             : 
   28707                 :             :   /* Process the optional `virtual' and `access-specifier'.  */
   28708                 :    36953283 :   while (!done)
   28709                 :             :     {
   28710                 :             :       /* Peek at the next token.  */
   28711                 :    16406837 :       token = cp_lexer_peek_token (parser->lexer);
   28712                 :             :       /* Process `virtual'.  */
   28713                 :    16406837 :       switch (token->keyword)
   28714                 :             :         {
   28715                 :       25504 :         case RID_VIRTUAL:
   28716                 :             :           /* If `virtual' appears more than once, issue an error.  */
   28717                 :       25504 :           if (virtual_p && !duplicate_virtual_error_issued_p)
   28718                 :             :             {
   28719                 :           0 :               cp_parser_error (parser,
   28720                 :             :                                "%<virtual%> specified more than once in base-specifier");
   28721                 :           0 :               duplicate_virtual_error_issued_p = true;
   28722                 :             :             }
   28723                 :             : 
   28724                 :       25504 :           virtual_p = true;
   28725                 :             : 
   28726                 :             :           /* Consume the `virtual' token.  */
   28727                 :       25504 :           cp_lexer_consume_token (parser->lexer);
   28728                 :             : 
   28729                 :       25504 :           break;
   28730                 :             : 
   28731                 :     6108110 :         case RID_PUBLIC:
   28732                 :     6108110 :         case RID_PROTECTED:
   28733                 :     6108110 :         case RID_PRIVATE:
   28734                 :             :           /* If more than one access specifier appears, issue an
   28735                 :             :              error.  */
   28736                 :     6108110 :           if (access != access_default_node
   28737                 :           0 :               && !duplicate_access_error_issued_p)
   28738                 :             :             {
   28739                 :           0 :               cp_parser_error (parser,
   28740                 :             :                                "more than one access specifier in base-specifier");
   28741                 :           0 :               duplicate_access_error_issued_p = true;
   28742                 :             :             }
   28743                 :             : 
   28744                 :     6108110 :           access = ridpointers[(int) token->keyword];
   28745                 :             : 
   28746                 :             :           /* Consume the access-specifier.  */
   28747                 :     6108110 :           cp_lexer_consume_token (parser->lexer);
   28748                 :             : 
   28749                 :     6108110 :           break;
   28750                 :             : 
   28751                 :             :         default:
   28752                 :             :           done = true;
   28753                 :             :           break;
   28754                 :             :         }
   28755                 :             :     }
   28756                 :             :   /* It is not uncommon to see programs mechanically, erroneously, use
   28757                 :             :      the 'typename' keyword to denote (dependent) qualified types
   28758                 :             :      as base classes.  */
   28759                 :    10273223 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
   28760                 :             :     {
   28761                 :          12 :       token = cp_lexer_peek_token (parser->lexer);
   28762                 :          12 :       if (!processing_template_decl)
   28763                 :           4 :         error_at (token->location,
   28764                 :             :                   "keyword %<typename%> not allowed outside of templates");
   28765                 :             :       else
   28766                 :           8 :         error_at (token->location,
   28767                 :             :                   "keyword %<typename%> not allowed in this context "
   28768                 :             :                   "(the base class is implicitly a type)");
   28769                 :          12 :       cp_lexer_consume_token (parser->lexer);
   28770                 :             :     }
   28771                 :             : 
   28772                 :             :   /* Look for the optional `::' operator.  */
   28773                 :    10273223 :   cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
   28774                 :             :   /* Look for the nested-name-specifier.  The simplest way to
   28775                 :             :      implement:
   28776                 :             : 
   28777                 :             :        [temp.res]
   28778                 :             : 
   28779                 :             :        The keyword `typename' is not permitted in a base-specifier or
   28780                 :             :        mem-initializer; in these contexts a qualified name that
   28781                 :             :        depends on a template-parameter is implicitly assumed to be a
   28782                 :             :        type name.
   28783                 :             : 
   28784                 :             :      is to pretend that we have seen the `typename' keyword at this
   28785                 :             :      point.  */
   28786                 :    10273223 :   cp_parser_nested_name_specifier_opt (parser,
   28787                 :             :                                        /*typename_keyword_p=*/true,
   28788                 :             :                                        /*check_dependency_p=*/true,
   28789                 :             :                                        /*type_p=*/true,
   28790                 :             :                                        /*is_declaration=*/true);
   28791                 :             :   /* If the base class is given by a qualified name, assume that names
   28792                 :             :      we see are type names or templates, as appropriate.  */
   28793                 :    10273223 :   class_scope_p = (parser->scope && TYPE_P (parser->scope));
   28794                 :     1015828 :   template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
   28795                 :             : 
   28796                 :    10273223 :   if (!parser->scope
   28797                 :    10273223 :       && cp_lexer_next_token_is_decltype (parser->lexer))
   28798                 :             :     /* DR 950 allows decltype as a base-specifier.  */
   28799                 :       27004 :     type = cp_parser_decltype (parser);
   28800                 :             :   else
   28801                 :             :     {
   28802                 :             :       /* Otherwise, look for the class-name.  */
   28803                 :    10246219 :       type = cp_parser_class_name (parser,
   28804                 :             :                                    class_scope_p,
   28805                 :             :                                    template_p,
   28806                 :             :                                    typename_type,
   28807                 :             :                                    /*check_dependency_p=*/true,
   28808                 :             :                                    /*class_head_p=*/false,
   28809                 :             :                                    /*is_declaration=*/true);
   28810                 :    10246219 :       type = TREE_TYPE (type);
   28811                 :             :     }
   28812                 :             : 
   28813                 :    10273223 :   if (type == error_mark_node)
   28814                 :             :     return error_mark_node;
   28815                 :             : 
   28816                 :    10273131 :   return finish_base_specifier (type, access, virtual_p);
   28817                 :             : }
   28818                 :             : 
   28819                 :             : /* Exception handling [gram.exception] */
   28820                 :             : 
   28821                 :             : /* Save the tokens that make up the noexcept-specifier for a member-function.
   28822                 :             :    Returns a DEFERRED_PARSE.  */
   28823                 :             : 
   28824                 :             : static tree
   28825                 :     2329635 : cp_parser_save_noexcept (cp_parser *parser)
   28826                 :             : {
   28827                 :     2329635 :   cp_token *first = parser->lexer->next_token;
   28828                 :             :   /* We want everything up to, including, the final ')'.  */
   28829                 :     2329635 :   cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0);
   28830                 :     2329635 :   cp_token *last = parser->lexer->next_token;
   28831                 :             : 
   28832                 :             :   /* As with default arguments and NSDMIs, make use of DEFERRED_PARSE
   28833                 :             :      to carry the information we will need.  */
   28834                 :     2329635 :   tree expr = make_node (DEFERRED_PARSE);
   28835                 :             :   /* Save away the noexcept-specifier; we will process it when the
   28836                 :             :      class is complete.  */
   28837                 :     2329635 :   DEFPARSE_TOKENS (expr) = cp_token_cache_new (first, last);
   28838                 :     2329635 :   DEFPARSE_INSTANTIATIONS (expr) = nullptr;
   28839                 :     2329635 :   expr = build_tree_list (expr, NULL_TREE);
   28840                 :     2329635 :   return expr;
   28841                 :             : }
   28842                 :             : 
   28843                 :             : /* Used for late processing of noexcept-specifiers of member-functions.
   28844                 :             :    DEFAULT_ARG is the unparsed operand of a noexcept-specifier which
   28845                 :             :    we saved for later; parse it now.  DECL is the declaration of the
   28846                 :             :    member function.  */
   28847                 :             : 
   28848                 :             : static tree
   28849                 :     2329635 : cp_parser_late_noexcept_specifier (cp_parser *parser, tree default_arg)
   28850                 :             : {
   28851                 :             :   /* Make sure we've gotten something that hasn't been parsed yet.  */
   28852                 :     2329635 :   gcc_assert (TREE_CODE (default_arg) == DEFERRED_PARSE);
   28853                 :             : 
   28854                 :     2329635 :   push_unparsed_function_queues (parser);
   28855                 :             : 
   28856                 :             :   /* Push the saved tokens for the noexcept-specifier onto the parser's
   28857                 :             :      lexer stack.  */
   28858                 :     2329635 :   cp_token_cache *tokens = DEFPARSE_TOKENS (default_arg);
   28859                 :     2329635 :   cp_parser_push_lexer_for_tokens (parser, tokens);
   28860                 :             : 
   28861                 :             :   /* Parse the cached noexcept-specifier.  */
   28862                 :     2329635 :   tree parsed_arg
   28863                 :     2329635 :     = cp_parser_noexcept_specification_opt (parser,
   28864                 :             :                                             CP_PARSER_FLAGS_NONE,
   28865                 :             :                                             /*require_constexpr=*/true,
   28866                 :             :                                             /*consumed_expr=*/NULL,
   28867                 :             :                                             /*return_cond=*/false);
   28868                 :             : 
   28869                 :             :   /* Revert to the main lexer.  */
   28870                 :     2329635 :   cp_parser_pop_lexer (parser);
   28871                 :             : 
   28872                 :             :   /* Restore the queue.  */
   28873                 :     2329635 :   pop_unparsed_function_queues (parser);
   28874                 :             : 
   28875                 :             :   /* And we're done.  */
   28876                 :     2329635 :   return parsed_arg;
   28877                 :             : }
   28878                 :             : 
   28879                 :             : /* Perform late checking of overriding function with respect to their
   28880                 :             :    noexcept-specifiers.  FNDECL is the member function that potentially
   28881                 :             :    overrides some virtual function with the same signature.  */
   28882                 :             : 
   28883                 :             : static void
   28884                 :     2329635 : noexcept_override_late_checks (tree fndecl)
   28885                 :             : {
   28886                 :     2329635 :   tree binfo = TYPE_BINFO (DECL_CONTEXT (fndecl));
   28887                 :     2329635 :   tree base_binfo;
   28888                 :             : 
   28889                 :     2329635 :   if (DECL_STATIC_FUNCTION_P (fndecl))
   28890                 :     2329635 :     return;
   28891                 :             : 
   28892                 :     3884768 :   for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
   28893                 :             :     {
   28894                 :     1742602 :       tree basetype = BINFO_TYPE (base_binfo);
   28895                 :             : 
   28896                 :     1742602 :       if (!TYPE_POLYMORPHIC_P (basetype))
   28897                 :     1742593 :         continue;
   28898                 :             : 
   28899                 :           9 :       tree fn = look_for_overrides_here (basetype, fndecl);
   28900                 :           9 :       if (fn)
   28901                 :           6 :         maybe_check_overriding_exception_spec (fndecl, fn);
   28902                 :             :     }
   28903                 :             : }
   28904                 :             : 
   28905                 :             : /* Parse an (optional) noexcept-specification.
   28906                 :             : 
   28907                 :             :    noexcept-specification:
   28908                 :             :      noexcept ( constant-expression ) [opt]
   28909                 :             : 
   28910                 :             :    If no noexcept-specification is present, returns NULL_TREE.
   28911                 :             :    Otherwise, if REQUIRE_CONSTEXPR is false, then either parse and return any
   28912                 :             :    expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if
   28913                 :             :    there are no parentheses.  CONSUMED_EXPR will be set accordingly.
   28914                 :             :    Otherwise, returns a noexcept specification unless RETURN_COND is true,
   28915                 :             :    in which case a boolean condition is returned instead.  The parser flags
   28916                 :             :    FLAGS is used to control parsing.  QUALS are qualifiers indicating whether
   28917                 :             :    the (member) function is `const'.  */
   28918                 :             : 
   28919                 :             : static tree
   28920                 :   162524942 : cp_parser_noexcept_specification_opt (cp_parser* parser,
   28921                 :             :                                       cp_parser_flags flags,
   28922                 :             :                                       bool require_constexpr,
   28923                 :             :                                       bool* consumed_expr,
   28924                 :             :                                       bool return_cond)
   28925                 :             : {
   28926                 :   162524942 :   cp_token *token;
   28927                 :   162524942 :   const char *saved_message;
   28928                 :             : 
   28929                 :             :   /* Peek at the next token.  */
   28930                 :   162524942 :   token = cp_lexer_peek_token (parser->lexer);
   28931                 :             : 
   28932                 :             :   /* Is it a noexcept-specification?  */
   28933                 :   162524942 :   if (cp_parser_is_keyword (token, RID_NOEXCEPT))
   28934                 :             :     {
   28935                 :    61974638 :       tree expr;
   28936                 :             : 
   28937                 :             :       /* [class.mem]/6 says that a noexcept-specifer (within the
   28938                 :             :          member-specification of the class) is a complete-class context of
   28939                 :             :          a class.  So, if the noexcept-specifier has the optional expression,
   28940                 :             :          just save the tokens, and reparse this after we're done with the
   28941                 :             :          class.  */
   28942                 :             : 
   28943                 :    61974638 :       if ((flags & CP_PARSER_FLAGS_DELAY_NOEXCEPT)
   28944                 :    26071848 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN)
   28945                 :             :           /* No need to delay parsing for a number literal or true/false.  */
   28946                 :     2370086 :           && !((cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER)
   28947                 :     2370077 :                 || cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD))
   28948                 :      737457 :                && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN))
   28949                 :     2329635 :           && at_class_scope_p ()
   28950                 :     2329635 :           && TYPE_BEING_DEFINED (current_class_type)
   28951                 :    66633908 :           && !LAMBDA_TYPE_P (current_class_type))
   28952                 :     2329635 :         return cp_parser_save_noexcept (parser);
   28953                 :             : 
   28954                 :    59645003 :       cp_lexer_consume_token (parser->lexer);
   28955                 :             : 
   28956                 :    59645003 :       if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
   28957                 :             :         {
   28958                 :    27365111 :           matching_parens parens;
   28959                 :    27365111 :           parens.consume_open (parser);
   28960                 :             : 
   28961                 :    27365111 :           if (require_constexpr)
   28962                 :             :             {
   28963                 :             :               /* Types may not be defined in an exception-specification.  */
   28964                 :    27365054 :               saved_message = parser->type_definition_forbidden_message;
   28965                 :    27365054 :               parser->type_definition_forbidden_message
   28966                 :    27365054 :               = G_("types may not be defined in an exception-specification");
   28967                 :             : 
   28968                 :    27365054 :               bool non_constant_p;
   28969                 :    27365054 :               expr
   28970                 :    27365054 :                 = cp_parser_constant_expression (parser,
   28971                 :             :                                                  /*allow_non_constant=*/true,
   28972                 :             :                                                  &non_constant_p);
   28973                 :    27365054 :               if (non_constant_p
   28974                 :    27365054 :                   && !require_potential_rvalue_constant_expression (expr))
   28975                 :             :                 {
   28976                 :             :                   expr = NULL_TREE;
   28977                 :             :                   return_cond = true;
   28978                 :             :                 }
   28979                 :             : 
   28980                 :             :               /* Restore the saved message.  */
   28981                 :    27365054 :               parser->type_definition_forbidden_message = saved_message;
   28982                 :             :             }
   28983                 :             :           else
   28984                 :             :             {
   28985                 :          57 :               expr = cp_parser_expression (parser);
   28986                 :          57 :               *consumed_expr = true;
   28987                 :             :             }
   28988                 :             : 
   28989                 :    27365111 :           parens.require_close (parser);
   28990                 :             :         }
   28991                 :             :       else
   28992                 :             :         {
   28993                 :    32279892 :           expr = boolean_true_node;
   28994                 :    32279892 :           if (!require_constexpr)
   28995                 :           0 :             *consumed_expr = false;
   28996                 :             :         }
   28997                 :             : 
   28998                 :             :       /* We cannot build a noexcept-spec right away because this will check
   28999                 :             :          that expr is a constexpr.  */
   29000                 :    59645003 :       if (!return_cond)
   29001                 :    59644856 :         return build_noexcept_spec (expr, tf_warning_or_error);
   29002                 :             :       else
   29003                 :             :         return expr;
   29004                 :             :     }
   29005                 :             :   else
   29006                 :             :     return NULL_TREE;
   29007                 :             : }
   29008                 :             : 
   29009                 :             : /* Parse an (optional) exception-specification.
   29010                 :             : 
   29011                 :             :    exception-specification:
   29012                 :             :      throw ( type-id-list [opt] )
   29013                 :             : 
   29014                 :             :    Returns a TREE_LIST representing the exception-specification.  The
   29015                 :             :    TREE_VALUE of each node is a type.  The parser flags FLAGS is used to
   29016                 :             :    control parsing.  QUALS are qualifiers indicating whether the (member)
   29017                 :             :    function is `const'.  */
   29018                 :             : 
   29019                 :             : static tree
   29020                 :   160194925 : cp_parser_exception_specification_opt (cp_parser* parser,
   29021                 :             :                                        cp_parser_flags flags)
   29022                 :             : {
   29023                 :   160194925 :   cp_token *token;
   29024                 :   160194925 :   tree type_id_list;
   29025                 :   160194925 :   const char *saved_message;
   29026                 :             : 
   29027                 :             :   /* Peek at the next token.  */
   29028                 :   160194925 :   token = cp_lexer_peek_token (parser->lexer);
   29029                 :             : 
   29030                 :             :   /* Is it a noexcept-specification?  */
   29031                 :   160194925 :   type_id_list
   29032                 :   160194925 :     = cp_parser_noexcept_specification_opt (parser, flags,
   29033                 :             :                                             /*require_constexpr=*/true,
   29034                 :             :                                             /*consumed_expr=*/NULL,
   29035                 :             :                                             /*return_cond=*/false);
   29036                 :   160194925 :   if (type_id_list != NULL_TREE)
   29037                 :             :     return type_id_list;
   29038                 :             : 
   29039                 :             :   /* If it's not `throw', then there's no exception-specification.  */
   29040                 :   100550036 :   if (!cp_parser_is_keyword (token, RID_THROW))
   29041                 :             :     return NULL_TREE;
   29042                 :             : 
   29043                 :     2008015 :   location_t loc = token->location;
   29044                 :             : 
   29045                 :             :   /* Consume the `throw'.  */
   29046                 :     2008015 :   cp_lexer_consume_token (parser->lexer);
   29047                 :             : 
   29048                 :             :   /* Look for the `('.  */
   29049                 :     2008015 :   matching_parens parens;
   29050                 :     2008015 :   parens.require_open (parser);
   29051                 :             : 
   29052                 :             :   /* Peek at the next token.  */
   29053                 :     2008015 :   token = cp_lexer_peek_token (parser->lexer);
   29054                 :             :   /* If it's not a `)', then there is a type-id-list.  */
   29055                 :     2008015 :   if (token->type != CPP_CLOSE_PAREN)
   29056                 :             :     {
   29057                 :             :       /* Types may not be defined in an exception-specification.  */
   29058                 :        1212 :       saved_message = parser->type_definition_forbidden_message;
   29059                 :        1212 :       parser->type_definition_forbidden_message
   29060                 :        1212 :         = G_("types may not be defined in an exception-specification");
   29061                 :             :       /* Parse the type-id-list.  */
   29062                 :        1212 :       type_id_list = cp_parser_type_id_list (parser);
   29063                 :             :       /* Restore the saved message.  */
   29064                 :        1212 :       parser->type_definition_forbidden_message = saved_message;
   29065                 :             : 
   29066                 :        1212 :       if (cxx_dialect >= cxx17)
   29067                 :             :         {
   29068                 :          50 :           error_at (loc, "ISO C++17 does not allow dynamic exception "
   29069                 :             :                          "specifications");
   29070                 :          50 :           type_id_list = NULL_TREE;
   29071                 :             :         }
   29072                 :        1162 :       else if (cxx_dialect >= cxx11)
   29073                 :         202 :         warning_at (loc, OPT_Wdeprecated,
   29074                 :             :                     "dynamic exception specifications are deprecated in "
   29075                 :             :                     "C++11");
   29076                 :             :     }
   29077                 :             :   /* In C++17, throw() is equivalent to noexcept (true).  throw()
   29078                 :             :      is deprecated in C++11 and above as well, but is still widely used,
   29079                 :             :      so don't warn about it yet.  */
   29080                 :     2006803 :   else if (cxx_dialect >= cxx17)
   29081                 :     1694855 :     type_id_list = noexcept_true_spec;
   29082                 :             :   else
   29083                 :      311948 :     type_id_list = empty_except_spec;
   29084                 :             : 
   29085                 :             :   /* Look for the `)'.  */
   29086                 :     2008015 :   parens.require_close (parser);
   29087                 :             : 
   29088                 :     2008015 :   return type_id_list;
   29089                 :             : }
   29090                 :             : 
   29091                 :             : /* Parse an (optional) type-id-list.
   29092                 :             : 
   29093                 :             :    type-id-list:
   29094                 :             :      type-id ... [opt]
   29095                 :             :      type-id-list , type-id ... [opt]
   29096                 :             : 
   29097                 :             :    Returns a TREE_LIST.  The TREE_VALUE of each node is a TYPE,
   29098                 :             :    in the order that the types were presented.  */
   29099                 :             : 
   29100                 :             : static tree
   29101                 :        1212 : cp_parser_type_id_list (cp_parser* parser)
   29102                 :             : {
   29103                 :        1212 :   tree types = NULL_TREE;
   29104                 :             : 
   29105                 :        1320 :   while (true)
   29106                 :             :     {
   29107                 :        1266 :       cp_token *token;
   29108                 :        1266 :       tree type;
   29109                 :             : 
   29110                 :        1266 :       token = cp_lexer_peek_token (parser->lexer);
   29111                 :             : 
   29112                 :             :       /* Get the next type-id.  */
   29113                 :        1266 :       type = cp_parser_type_id (parser);
   29114                 :             :       /* Check for invalid 'auto'.  */
   29115                 :        1266 :       if (flag_concepts && type_uses_auto (type))
   29116                 :             :         {
   29117                 :           2 :           error_at (token->location,
   29118                 :             :                     "invalid use of %<auto%> in exception-specification");
   29119                 :           2 :           type = error_mark_node;
   29120                 :             :         }
   29121                 :             :       /* Parse the optional ellipsis. */
   29122                 :        1266 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   29123                 :             :         {
   29124                 :             :           /* Consume the `...'. */
   29125                 :           4 :           cp_lexer_consume_token (parser->lexer);
   29126                 :             : 
   29127                 :             :           /* Turn the type into a pack expansion expression. */
   29128                 :           4 :           type = make_pack_expansion (type);
   29129                 :             :         }
   29130                 :             :       /* Add it to the list.  */
   29131                 :        1266 :       types = add_exception_specifier (types, type, /*complain=*/1);
   29132                 :             :       /* Peek at the next token.  */
   29133                 :        1266 :       token = cp_lexer_peek_token (parser->lexer);
   29134                 :             :       /* If it is not a `,', we are done.  */
   29135                 :        1266 :       if (token->type != CPP_COMMA)
   29136                 :             :         break;
   29137                 :             :       /* Consume the `,'.  */
   29138                 :          54 :       cp_lexer_consume_token (parser->lexer);
   29139                 :          54 :     }
   29140                 :             : 
   29141                 :        1212 :   return nreverse (types);
   29142                 :             : }
   29143                 :             : 
   29144                 :             : /* Parse a try-block.
   29145                 :             : 
   29146                 :             :    try-block:
   29147                 :             :      try compound-statement handler-seq  */
   29148                 :             : 
   29149                 :             : static tree
   29150                 :     1194399 : cp_parser_try_block (cp_parser* parser)
   29151                 :             : {
   29152                 :     1194399 :   tree try_block;
   29153                 :             : 
   29154                 :     1194399 :   cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
   29155                 :     1194399 :   if (parser->in_function_body
   29156                 :     1194399 :       && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
   29157                 :     1228696 :       && cxx_dialect < cxx20)
   29158                 :          26 :     pedwarn (input_location, OPT_Wc__20_extensions,
   29159                 :             :              "%<try%> in %<constexpr%> function only "
   29160                 :             :              "available with %<-std=c++20%> or %<-std=gnu++20%>");
   29161                 :             : 
   29162                 :     1194399 :   try_block = begin_try_block ();
   29163                 :     1194399 :   cp_parser_compound_statement (parser, NULL, BCS_TRY_BLOCK, false);
   29164                 :     1194399 :   finish_try_block (try_block);
   29165                 :     1194399 :   cp_parser_handler_seq (parser);
   29166                 :     1194399 :   finish_handler_sequence (try_block);
   29167                 :             : 
   29168                 :     1194399 :   return try_block;
   29169                 :             : }
   29170                 :             : 
   29171                 :             : /* Parse a function-try-block.
   29172                 :             : 
   29173                 :             :    function-try-block:
   29174                 :             :      try ctor-initializer [opt] function-body handler-seq  */
   29175                 :             : 
   29176                 :             : static void
   29177                 :         320 : cp_parser_function_try_block (cp_parser* parser)
   29178                 :             : {
   29179                 :         320 :   tree compound_stmt;
   29180                 :         320 :   tree try_block;
   29181                 :             : 
   29182                 :             :   /* Look for the `try' keyword.  */
   29183                 :         320 :   if (!cp_parser_require_keyword (parser, RID_TRY, RT_TRY))
   29184                 :           0 :     return;
   29185                 :             :   /* Let the rest of the front end know where we are.  */
   29186                 :         320 :   try_block = begin_function_try_block (&compound_stmt);
   29187                 :             :   /* Parse the function-body.  */
   29188                 :         320 :   cp_parser_ctor_initializer_opt_and_function_body
   29189                 :         320 :     (parser, /*in_function_try_block=*/true);
   29190                 :             :   /* We're done with the `try' part.  */
   29191                 :         320 :   finish_function_try_block (try_block);
   29192                 :             :   /* Parse the handlers.  */
   29193                 :         320 :   cp_parser_handler_seq (parser);
   29194                 :             :   /* We're done with the handlers.  */
   29195                 :         320 :   finish_function_handler_sequence (try_block, compound_stmt);
   29196                 :             : }
   29197                 :             : 
   29198                 :             : /* Parse a handler-seq.
   29199                 :             : 
   29200                 :             :    handler-seq:
   29201                 :             :      handler handler-seq [opt]  */
   29202                 :             : 
   29203                 :             : static void
   29204                 :     1194719 : cp_parser_handler_seq (cp_parser* parser)
   29205                 :             : {
   29206                 :     1633631 :   while (true)
   29207                 :             :     {
   29208                 :     1633631 :       cp_token *token;
   29209                 :             : 
   29210                 :             :       /* Parse the handler.  */
   29211                 :     1633631 :       cp_parser_handler (parser);
   29212                 :             :       /* Peek at the next token.  */
   29213                 :     1633631 :       token = cp_lexer_peek_token (parser->lexer);
   29214                 :             :       /* If it's not `catch' then there are no more handlers.  */
   29215                 :     1633631 :       if (!cp_parser_is_keyword (token, RID_CATCH))
   29216                 :             :         break;
   29217                 :             :     }
   29218                 :     1194719 : }
   29219                 :             : 
   29220                 :             : /* Parse a handler.
   29221                 :             : 
   29222                 :             :    handler:
   29223                 :             :      catch ( exception-declaration ) compound-statement  */
   29224                 :             : 
   29225                 :             : static void
   29226                 :     1633631 : cp_parser_handler (cp_parser* parser)
   29227                 :             : {
   29228                 :     1633631 :   tree handler;
   29229                 :     1633631 :   tree declaration;
   29230                 :             : 
   29231                 :     1633631 :   cp_parser_require_keyword (parser, RID_CATCH, RT_CATCH);
   29232                 :     1633631 :   handler = begin_handler ();
   29233                 :     1633631 :   matching_parens parens;
   29234                 :     1633631 :   parens.require_open (parser);
   29235                 :     1633631 :   declaration = cp_parser_exception_declaration (parser);
   29236                 :     1633631 :   finish_handler_parms (declaration, handler);
   29237                 :     1633631 :   parens.require_close (parser);
   29238                 :     1633631 :   cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
   29239                 :     1633631 :   finish_handler (handler);
   29240                 :     1633631 : }
   29241                 :             : 
   29242                 :             : /* Parse an exception-declaration.
   29243                 :             : 
   29244                 :             :    exception-declaration:
   29245                 :             :      type-specifier-seq declarator
   29246                 :             :      type-specifier-seq abstract-declarator
   29247                 :             :      type-specifier-seq
   29248                 :             :      ...
   29249                 :             : 
   29250                 :             :    Returns a VAR_DECL for the declaration, or NULL_TREE if the
   29251                 :             :    ellipsis variant is used.  */
   29252                 :             : 
   29253                 :             : static tree
   29254                 :     1633631 : cp_parser_exception_declaration (cp_parser* parser)
   29255                 :             : {
   29256                 :     1633631 :   cp_decl_specifier_seq type_specifiers;
   29257                 :     1633631 :   cp_declarator *declarator;
   29258                 :     1633631 :   const char *saved_message;
   29259                 :             : 
   29260                 :             :   /* If it's an ellipsis, it's easy to handle.  */
   29261                 :     1633631 :   if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   29262                 :             :     {
   29263                 :             :       /* Consume the `...' token.  */
   29264                 :     1171462 :       cp_lexer_consume_token (parser->lexer);
   29265                 :     1171462 :       return NULL_TREE;
   29266                 :             :     }
   29267                 :             : 
   29268                 :             :   /* Types may not be defined in exception-declarations.  */
   29269                 :      462169 :   saved_message = parser->type_definition_forbidden_message;
   29270                 :      462169 :   parser->type_definition_forbidden_message
   29271                 :      462169 :     = G_("types may not be defined in exception-declarations");
   29272                 :             : 
   29273                 :             :   /* Parse the type-specifier-seq.  */
   29274                 :      462169 :   cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
   29275                 :             :                                 /*is_declaration=*/true,
   29276                 :             :                                 /*is_trailing_return=*/false,
   29277                 :             :                                 &type_specifiers);
   29278                 :             :   /* If it's a `)', then there is no declarator.  */
   29279                 :      462169 :   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
   29280                 :             :     declarator = NULL;
   29281                 :             :   else
   29282                 :      461228 :     declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
   29283                 :             :                                        CP_PARSER_FLAGS_NONE,
   29284                 :             :                                        /*ctor_dtor_or_conv_p=*/NULL,
   29285                 :             :                                        /*parenthesized_p=*/NULL,
   29286                 :             :                                        /*member_p=*/false,
   29287                 :             :                                        /*friend_p=*/false,
   29288                 :             :                                        /*static_p=*/false);
   29289                 :             : 
   29290                 :             :   /* Restore the saved message.  */
   29291                 :      462169 :   parser->type_definition_forbidden_message = saved_message;
   29292                 :             : 
   29293                 :      462169 :   if (!type_specifiers.any_specifiers_p)
   29294                 :          36 :     return error_mark_node;
   29295                 :             : 
   29296                 :      462133 :   return grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, NULL);
   29297                 :             : }
   29298                 :             : 
   29299                 :             : /* Parse a throw-expression.
   29300                 :             : 
   29301                 :             :    throw-expression:
   29302                 :             :      throw assignment-expression [opt]
   29303                 :             : 
   29304                 :             :    Returns a THROW_EXPR representing the throw-expression.  */
   29305                 :             : 
   29306                 :             : static tree
   29307                 :     1235410 : cp_parser_throw_expression (cp_parser* parser)
   29308                 :             : {
   29309                 :     1235410 :   tree expression;
   29310                 :     1235410 :   cp_token* token;
   29311                 :     1235410 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   29312                 :             : 
   29313                 :     1235410 :   cp_parser_require_keyword (parser, RID_THROW, RT_THROW);
   29314                 :     1235410 :   token = cp_lexer_peek_token (parser->lexer);
   29315                 :             :   /* Figure out whether or not there is an assignment-expression
   29316                 :             :      following the "throw" keyword.  */
   29317                 :     1235410 :   if (token->type == CPP_COMMA
   29318                 :             :       || token->type == CPP_SEMICOLON
   29319                 :             :       || token->type == CPP_CLOSE_PAREN
   29320                 :             :       || token->type == CPP_CLOSE_SQUARE
   29321                 :             :       || token->type == CPP_CLOSE_BRACE
   29322                 :             :       || token->type == CPP_COLON)
   29323                 :             :     expression = NULL_TREE;
   29324                 :             :   else
   29325                 :      139092 :     expression = cp_parser_assignment_expression (parser);
   29326                 :             : 
   29327                 :             :   /* Construct a location e.g.:
   29328                 :             :        throw x
   29329                 :             :        ^~~~~~~
   29330                 :             :      with caret == start at the start of the "throw" token, and
   29331                 :             :      the end at the end of the final token we consumed.  */
   29332                 :     1235410 :   location_t combined_loc = make_location (start_loc, start_loc,
   29333                 :             :                                            parser->lexer);
   29334                 :     1235410 :   expression = build_throw (combined_loc, expression, tf_warning_or_error);
   29335                 :             : 
   29336                 :     1235410 :   return expression;
   29337                 :             : }
   29338                 :             : 
   29339                 :             : /* Parse a yield-expression.
   29340                 :             : 
   29341                 :             :    yield-expression:
   29342                 :             :      co_yield assignment-expression
   29343                 :             :      co_yield braced-init-list
   29344                 :             : 
   29345                 :             :    Returns a CO_YIELD_EXPR representing the yield-expression.  */
   29346                 :             : 
   29347                 :             : static tree
   29348                 :        1359 : cp_parser_yield_expression (cp_parser* parser)
   29349                 :             : {
   29350                 :        1359 :   tree expr;
   29351                 :             : 
   29352                 :        1359 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   29353                 :        1359 :   location_t kw_loc = token->location; /* Save for later.  */
   29354                 :             : 
   29355                 :        1359 :   cp_parser_require_keyword (parser, RID_CO_YIELD, RT_CO_YIELD);
   29356                 :             : 
   29357                 :        1359 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   29358                 :             :     {
   29359                 :           2 :       cp_lexer_set_source_position (parser->lexer);
   29360                 :             :       /* ??? : probably a moot point?  */
   29361                 :           2 :       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   29362                 :           2 :       expr = cp_parser_braced_list (parser);
   29363                 :             :     }
   29364                 :             :   else
   29365                 :        1357 :     expr = cp_parser_assignment_expression (parser);
   29366                 :             : 
   29367                 :        1359 :   if (expr == error_mark_node)
   29368                 :             :     return expr;
   29369                 :             : 
   29370                 :        1357 :   return finish_co_yield_expr (kw_loc, expr);
   29371                 :             : }
   29372                 :             : 
   29373                 :             : /* GNU Extensions */
   29374                 :             : 
   29375                 :             : /* Parse an (optional) asm-specification.
   29376                 :             : 
   29377                 :             :    asm-specification:
   29378                 :             :      asm ( string-literal )
   29379                 :             : 
   29380                 :             :    If the asm-specification is present, returns a STRING_CST
   29381                 :             :    corresponding to the string-literal.  Otherwise, returns
   29382                 :             :    NULL_TREE.  */
   29383                 :             : 
   29384                 :             : static tree
   29385                 :   255858544 : cp_parser_asm_specification_opt (cp_parser* parser)
   29386                 :             : {
   29387                 :             :   /* Peek at the next token.  */
   29388                 :   255858544 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   29389                 :             :   /* If the next token isn't the `asm' keyword, then there's no
   29390                 :             :      asm-specification.  */
   29391                 :   255858544 :   if (!cp_parser_is_keyword (token, RID_ASM))
   29392                 :             :     return NULL_TREE;
   29393                 :             : 
   29394                 :             :   /* Consume the `asm' token.  */
   29395                 :      929941 :   cp_lexer_consume_token (parser->lexer);
   29396                 :             :   /* Look for the `('.  */
   29397                 :      929941 :   matching_parens parens;
   29398                 :      929941 :   parens.require_open (parser);
   29399                 :             : 
   29400                 :             :   /* Look for the string-literal.  */
   29401                 :      929941 :   tree asm_specification = cp_parser_string_literal (parser,
   29402                 :             :                                                      /*translate=*/false,
   29403                 :             :                                                      /*wide_ok=*/false);
   29404                 :             : 
   29405                 :             :   /* Look for the `)'.  */
   29406                 :      929941 :   parens.require_close (parser);
   29407                 :             : 
   29408                 :      929941 :   return asm_specification;
   29409                 :             : }
   29410                 :             : 
   29411                 :             : /* Parse an asm-operand-list.
   29412                 :             : 
   29413                 :             :    asm-operand-list:
   29414                 :             :      asm-operand
   29415                 :             :      asm-operand-list , asm-operand
   29416                 :             : 
   29417                 :             :    asm-operand:
   29418                 :             :      string-literal ( expression )
   29419                 :             :      [ string-literal ] string-literal ( expression )
   29420                 :             : 
   29421                 :             :    Returns a TREE_LIST representing the operands.  The TREE_VALUE of
   29422                 :             :    each node is the expression.  The TREE_PURPOSE is itself a
   29423                 :             :    TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed
   29424                 :             :    string-literal (or NULL_TREE if not present) and whose TREE_VALUE
   29425                 :             :    is a STRING_CST for the string literal before the parenthesis. Returns
   29426                 :             :    ERROR_MARK_NODE if any of the operands are invalid.  */
   29427                 :             : 
   29428                 :             : static tree
   29429                 :       16681 : cp_parser_asm_operand_list (cp_parser* parser)
   29430                 :             : {
   29431                 :       16681 :   tree asm_operands = NULL_TREE;
   29432                 :       16681 :   bool invalid_operands = false;
   29433                 :             : 
   29434                 :       52263 :   while (true)
   29435                 :             :     {
   29436                 :       34472 :       tree name;
   29437                 :             : 
   29438                 :       34472 :       if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
   29439                 :             :         {
   29440                 :             :           /* Consume the `[' token.  */
   29441                 :          66 :           cp_lexer_consume_token (parser->lexer);
   29442                 :             :           /* Read the operand name.  */
   29443                 :          66 :           name = cp_parser_identifier (parser);
   29444                 :          66 :           if (name != error_mark_node)
   29445                 :          62 :             name = build_string (IDENTIFIER_LENGTH (name),
   29446                 :          62 :                                  IDENTIFIER_POINTER (name));
   29447                 :             :           /* Look for the closing `]'.  */
   29448                 :          66 :           cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
   29449                 :             :         }
   29450                 :             :       else
   29451                 :             :         name = NULL_TREE;
   29452                 :             :       /* Look for the string-literal.  */
   29453                 :       34472 :       tree string_literal = cp_parser_string_literal (parser,
   29454                 :             :                                                       /*translate=*/false,
   29455                 :             :                                                       /*wide_ok=*/false);
   29456                 :             : 
   29457                 :             :       /* Look for the `('.  */
   29458                 :       34472 :       matching_parens parens;
   29459                 :       34472 :       parens.require_open (parser);
   29460                 :             :       /* Parse the expression.  */
   29461                 :       34472 :       tree expression = cp_parser_expression (parser);
   29462                 :             :       /* Look for the `)'.  */
   29463                 :       34472 :       parens.require_close (parser);
   29464                 :             : 
   29465                 :       34472 :       if (name == error_mark_node
   29466                 :       34468 :           || string_literal == error_mark_node
   29467                 :       34460 :           || expression == error_mark_node)
   29468                 :          12 :         invalid_operands = true;
   29469                 :             : 
   29470                 :             :       /* Add this operand to the list.  */
   29471                 :       34472 :       asm_operands = tree_cons (build_tree_list (name, string_literal),
   29472                 :             :                                 expression,
   29473                 :             :                                 asm_operands);
   29474                 :             :       /* If the next token is not a `,', there are no more
   29475                 :             :          operands.  */
   29476                 :       34472 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   29477                 :             :         break;
   29478                 :             :       /* Consume the `,'.  */
   29479                 :       17791 :       cp_lexer_consume_token (parser->lexer);
   29480                 :       17791 :     }
   29481                 :             : 
   29482                 :       16681 :   return invalid_operands ? error_mark_node : nreverse (asm_operands);
   29483                 :             : }
   29484                 :             : 
   29485                 :             : /* Parse an asm-clobber-list.
   29486                 :             : 
   29487                 :             :    asm-clobber-list:
   29488                 :             :      string-literal
   29489                 :             :      asm-clobber-list , string-literal
   29490                 :             : 
   29491                 :             :    Returns a TREE_LIST, indicating the clobbers in the order that they
   29492                 :             :    appeared.  The TREE_VALUE of each node is a STRING_CST.  */
   29493                 :             : 
   29494                 :             : static tree
   29495                 :        9616 : cp_parser_asm_clobber_list (cp_parser* parser)
   29496                 :             : {
   29497                 :        9616 :   tree clobbers = NULL_TREE;
   29498                 :             : 
   29499                 :       22892 :   while (true)
   29500                 :             :     {
   29501                 :             :       /* Look for the string literal.  */
   29502                 :       16254 :       tree string_literal = cp_parser_string_literal (parser,
   29503                 :             :                                                       /*translate=*/false,
   29504                 :             :                                                       /*wide_ok=*/false);
   29505                 :             :       /* Add it to the list.  */
   29506                 :       16254 :       clobbers = tree_cons (NULL_TREE, string_literal, clobbers);
   29507                 :             :       /* If the next token is not a `,', then the list is
   29508                 :             :          complete.  */
   29509                 :       16254 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   29510                 :             :         break;
   29511                 :             :       /* Consume the `,' token.  */
   29512                 :        6638 :       cp_lexer_consume_token (parser->lexer);
   29513                 :        6638 :     }
   29514                 :             : 
   29515                 :        9616 :   return clobbers;
   29516                 :             : }
   29517                 :             : 
   29518                 :             : /* Parse an asm-label-list.
   29519                 :             : 
   29520                 :             :    asm-label-list:
   29521                 :             :      identifier
   29522                 :             :      asm-label-list , identifier
   29523                 :             : 
   29524                 :             :    Returns a TREE_LIST, indicating the labels in the order that they
   29525                 :             :    appeared.  The TREE_VALUE of each node is a label.  */
   29526                 :             : 
   29527                 :             : static tree
   29528                 :          84 : cp_parser_asm_label_list (cp_parser* parser)
   29529                 :             : {
   29530                 :          84 :   tree labels = NULL_TREE;
   29531                 :             : 
   29532                 :         140 :   while (true)
   29533                 :             :     {
   29534                 :         112 :       tree identifier, label, name;
   29535                 :             : 
   29536                 :             :       /* Look for the identifier.  */
   29537                 :         112 :       identifier = cp_parser_identifier (parser);
   29538                 :         112 :       if (!error_operand_p (identifier))
   29539                 :             :         {
   29540                 :         108 :           label = lookup_label (identifier);
   29541                 :         108 :           if (TREE_CODE (label) == LABEL_DECL)
   29542                 :             :             {
   29543                 :         108 :               TREE_USED (label) = 1;
   29544                 :         108 :               check_goto (label);
   29545                 :         108 :               name = build_string (IDENTIFIER_LENGTH (identifier),
   29546                 :         108 :                                    IDENTIFIER_POINTER (identifier));
   29547                 :         108 :               labels = tree_cons (name, label, labels);
   29548                 :             :             }
   29549                 :             :         }
   29550                 :             :       /* If the next token is not a `,', then the list is
   29551                 :             :          complete.  */
   29552                 :         112 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   29553                 :             :         break;
   29554                 :             :       /* Consume the `,' token.  */
   29555                 :          28 :       cp_lexer_consume_token (parser->lexer);
   29556                 :          28 :     }
   29557                 :             : 
   29558                 :          84 :   return nreverse (labels);
   29559                 :             : }
   29560                 :             : 
   29561                 :             : /* Return TRUE iff the next tokens in the stream are possibly the
   29562                 :             :    beginning of a GNU extension attribute. */
   29563                 :             : 
   29564                 :             : static bool
   29565                 :  2948519169 : cp_next_tokens_can_be_gnu_attribute_p (cp_parser *parser)
   29566                 :             : {
   29567                 :  5897038338 :   return cp_nth_tokens_can_be_gnu_attribute_p (parser, 1);
   29568                 :             : }
   29569                 :             : 
   29570                 :             : /* Return TRUE iff the next tokens in the stream are possibly the
   29571                 :             :    beginning of a standard C++-11 attribute specifier.  */
   29572                 :             : 
   29573                 :             : static bool
   29574                 :  2962423187 : cp_next_tokens_can_be_std_attribute_p (cp_parser *parser)
   29575                 :             : {
   29576                 :    48422528 :   return cp_nth_tokens_can_be_std_attribute_p (parser, 1);
   29577                 :             : }
   29578                 :             : 
   29579                 :             : /* Return TRUE iff the next Nth tokens in the stream are possibly the
   29580                 :             :    beginning of a standard C++-11 attribute specifier.  */
   29581                 :             : 
   29582                 :             : static bool
   29583                 :  3043341950 : cp_nth_tokens_can_be_std_attribute_p (cp_parser *parser, size_t n)
   29584                 :             : {
   29585                 :  3043341950 :   cp_token *token = cp_lexer_peek_nth_token (parser->lexer, n);
   29586                 :             : 
   29587                 :  3043341950 :   return (cxx_dialect >= cxx11
   29588                 :  3043341950 :           && ((token->type == CPP_KEYWORD && token->keyword == RID_ALIGNAS)
   29589                 :  3026374323 :               || (token->type == CPP_OPEN_SQUARE
   29590                 :    35077007 :                   && (token = cp_lexer_peek_nth_token (parser->lexer, n + 1))
   29591                 :    35077007 :                   && token->type == CPP_OPEN_SQUARE)));
   29592                 :             : }
   29593                 :             : 
   29594                 :             : /* Return TRUE iff the next Nth tokens in the stream are possibly the
   29595                 :             :    beginning of a GNU extension attribute.  */
   29596                 :             : 
   29597                 :             : static bool
   29598                 :  3029520136 : cp_nth_tokens_can_be_gnu_attribute_p (cp_parser *parser, size_t n)
   29599                 :             : {
   29600                 :  2948519169 :   cp_token *token = cp_lexer_peek_nth_token (parser->lexer, n);
   29601                 :             : 
   29602                 :  3029520136 :   return token->type == CPP_KEYWORD && token->keyword == RID_ATTRIBUTE;
   29603                 :             : }
   29604                 :             : 
   29605                 :             : /* Return true iff the next tokens can be the beginning of either a
   29606                 :             :    GNU attribute list, or a standard C++11 attribute sequence.  */
   29607                 :             : 
   29608                 :             : static bool
   29609                 :  2309925888 : cp_next_tokens_can_be_attribute_p (cp_parser *parser)
   29610                 :             : {
   29611                 :  2309925888 :   return (cp_next_tokens_can_be_gnu_attribute_p (parser)
   29612                 :  2309925888 :           || cp_next_tokens_can_be_std_attribute_p (parser));
   29613                 :             : }
   29614                 :             : 
   29615                 :             : /* Return true iff the next Nth tokens can be the beginning of either
   29616                 :             :    a GNU attribute list, or a standard C++11 attribute sequence.  */
   29617                 :             : 
   29618                 :             : static bool
   29619                 :    80948129 : cp_nth_tokens_can_be_attribute_p (cp_parser *parser, size_t n)
   29620                 :             : {
   29621                 :    80948129 :   return (cp_nth_tokens_can_be_gnu_attribute_p (parser, n)
   29622                 :    80948129 :           || cp_nth_tokens_can_be_std_attribute_p (parser, n));
   29623                 :             : }
   29624                 :             : 
   29625                 :             : /* Parse either a standard C++-11 attribute-specifier-seq, or a series
   29626                 :             :    of GNU attributes, or return NULL.  */
   29627                 :             : 
   29628                 :             : static tree
   29629                 :   597515027 : cp_parser_attributes_opt (cp_parser *parser)
   29630                 :             : {
   29631                 :   597515027 :   tree attrs = NULL_TREE;
   29632                 :   625913357 :   while (true)
   29633                 :             :     {
   29634                 :   625913357 :       if (cp_next_tokens_can_be_gnu_attribute_p (parser))
   29635                 :    17967161 :         attrs = attr_chainon (attrs, cp_parser_gnu_attributes_opt (parser));
   29636                 :   607946196 :       else if (cp_next_tokens_can_be_std_attribute_p (parser))
   29637                 :    10431169 :         attrs = attr_chainon (attrs, cp_parser_std_attribute_spec_seq (parser));
   29638                 :             :       else
   29639                 :             :         break;
   29640                 :             :     }
   29641                 :   597515027 :   return attrs;
   29642                 :             : }
   29643                 :             : 
   29644                 :             : /* Parse an (optional) series of attributes.
   29645                 :             : 
   29646                 :             :    attributes:
   29647                 :             :      attributes attribute
   29648                 :             : 
   29649                 :             :    attribute:
   29650                 :             :      __attribute__ (( attribute-list [opt] ))
   29651                 :             : 
   29652                 :             :    The return value is as for cp_parser_gnu_attribute_list.  */
   29653                 :             : 
   29654                 :             : static tree
   29655                 :  1105814026 : cp_parser_gnu_attributes_opt (cp_parser* parser)
   29656                 :             : {
   29657                 :  1105814026 :   tree attributes = NULL_TREE;
   29658                 :             : 
   29659                 :  1105814026 :   auto cleanup = make_temp_override
   29660                 :  1105814026 :     (parser->auto_is_implicit_function_template_parm_p, false);
   29661                 :             : 
   29662                 :  1145078758 :   while (true)
   29663                 :             :     {
   29664                 :  1125446392 :       cp_token *token;
   29665                 :  1125446392 :       tree attribute_list;
   29666                 :  1125446392 :       bool ok = true;
   29667                 :             : 
   29668                 :             :       /* Peek at the next token.  */
   29669                 :  1125446392 :       token = cp_lexer_peek_token (parser->lexer);
   29670                 :             :       /* If it's not `__attribute__', then we're done.  */
   29671                 :  1125446392 :       if (token->keyword != RID_ATTRIBUTE)
   29672                 :             :         break;
   29673                 :             : 
   29674                 :             :       /* Consume the `__attribute__' keyword.  */
   29675                 :    19632366 :       cp_lexer_consume_token (parser->lexer);
   29676                 :             :       /* Look for the two `(' tokens.  */
   29677                 :    19632366 :       matching_parens outer_parens;
   29678                 :    19632366 :       if (!outer_parens.require_open (parser))
   29679                 :             :         ok = false;
   29680                 :    19632366 :       matching_parens inner_parens;
   29681                 :    19632366 :       if (!inner_parens.require_open (parser))
   29682                 :          40 :         ok = false;
   29683                 :             : 
   29684                 :             :       /* Peek at the next token.  */
   29685                 :    19632366 :       token = cp_lexer_peek_token (parser->lexer);
   29686                 :    19632366 :       if (token->type != CPP_CLOSE_PAREN)
   29687                 :             :         /* Parse the attribute-list.  */
   29688                 :    19632334 :         attribute_list = cp_parser_gnu_attribute_list (parser);
   29689                 :             :       else
   29690                 :             :         /* If the next token is a `)', then there is no attribute
   29691                 :             :            list.  */
   29692                 :             :         attribute_list = NULL;
   29693                 :             : 
   29694                 :             :       /* Look for the two `)' tokens.  */
   29695                 :    19632366 :       if (!inner_parens.require_close (parser))
   29696                 :          50 :         ok = false;
   29697                 :    19632366 :       if (!outer_parens.require_close (parser))
   29698                 :             :         ok = false;
   29699                 :    19632291 :       if (!ok)
   29700                 :          95 :         cp_parser_skip_to_end_of_statement (parser);
   29701                 :             : 
   29702                 :             :       /* Add these new attributes to the list.  */
   29703                 :    19632366 :       attributes = attr_chainon (attributes, attribute_list);
   29704                 :    19632366 :     }
   29705                 :             : 
   29706                 :  1105814026 :   return attributes;
   29707                 :  1105814026 : }
   29708                 :             : 
   29709                 :             : /* Parse a GNU attribute-list.
   29710                 :             : 
   29711                 :             :    attribute-list:
   29712                 :             :      attribute
   29713                 :             :      attribute-list , attribute
   29714                 :             : 
   29715                 :             :    attribute:
   29716                 :             :      identifier
   29717                 :             :      identifier ( identifier )
   29718                 :             :      identifier ( identifier , expression-list )
   29719                 :             :      identifier ( expression-list )
   29720                 :             : 
   29721                 :             :    Returns a TREE_LIST, or NULL_TREE on error.  Each node corresponds
   29722                 :             :    to an attribute.  The TREE_PURPOSE of each node is the identifier
   29723                 :             :    indicating which attribute is in use.  The TREE_VALUE represents
   29724                 :             :    the arguments, if any.  */
   29725                 :             : 
   29726                 :             : static tree
   29727                 :    19635124 : cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
   29728                 :             : {
   29729                 :    19635124 :   tree attribute_list = NULL_TREE;
   29730                 :    19635124 :   bool save_translate_strings_p = parser->translate_strings_p;
   29731                 :             : 
   29732                 :             :   /* Don't create wrapper nodes within attributes: the
   29733                 :             :      handlers don't know how to handle them.  */
   29734                 :    19635124 :   auto_suppress_location_wrappers sentinel;
   29735                 :             : 
   29736                 :    19635124 :   parser->translate_strings_p = false;
   29737                 :    25476582 :   while (true)
   29738                 :             :     {
   29739                 :    22555853 :       cp_token *token;
   29740                 :    22555853 :       tree identifier;
   29741                 :    22555853 :       tree attribute;
   29742                 :             : 
   29743                 :             :       /* Look for the identifier.  We also allow keywords here; for
   29744                 :             :          example `__attribute__ ((const))' is legal.  */
   29745                 :    22555853 :       token = cp_lexer_peek_token (parser->lexer);
   29746                 :    22555853 :       if (token->type == CPP_NAME
   29747                 :     3495564 :           || token->type == CPP_KEYWORD)
   29748                 :             :         {
   29749                 :    22555833 :           tree arguments = NULL_TREE;
   29750                 :             : 
   29751                 :             :           /* Consume the token, but save it since we need it for the
   29752                 :             :              SIMD enabled function parsing.  */
   29753                 :    22555833 :           cp_token *id_token = cp_lexer_consume_token (parser->lexer);
   29754                 :             : 
   29755                 :             :           /* Save away the identifier that indicates which attribute
   29756                 :             :              this is.  */
   29757                 :    45111666 :           identifier = (token->type == CPP_KEYWORD)
   29758                 :             :             /* For keywords, use the canonical spelling, not the
   29759                 :             :                parsed identifier.  */
   29760                 :    22555833 :             ? ridpointers[(int) token->keyword]
   29761                 :             :             : id_token->u.value;
   29762                 :             : 
   29763                 :    22555833 :           identifier = canonicalize_attr_name (identifier);
   29764                 :    22555833 :           attribute = build_tree_list (identifier, NULL_TREE);
   29765                 :             : 
   29766                 :             :           /* Peek at the next token.  */
   29767                 :    22555833 :           token = cp_lexer_peek_token (parser->lexer);
   29768                 :             :           /* If it's an `(', then parse the attribute arguments.  */
   29769                 :    22555833 :           if (token->type == CPP_OPEN_PAREN)
   29770                 :             :             {
   29771                 :    10037822 :               vec<tree, va_gc> *vec;
   29772                 :    10037822 :               int attr_flag = (attribute_takes_identifier_p (identifier)
   29773                 :    10037822 :                                ? id_attr : normal_attr);
   29774                 :    10037822 :               if (is_attribute_p ("assume", identifier))
   29775                 :       20117 :                 attr_flag = assume_attr;
   29776                 :    10037822 :               vec = cp_parser_parenthesized_expression_list
   29777                 :    10037822 :                     (parser, attr_flag, /*cast_p=*/false,
   29778                 :             :                     /*allow_expansion_p=*/false,
   29779                 :             :                     /*non_constant_p=*/NULL);
   29780                 :    10037822 :               if (vec == NULL)
   29781                 :          42 :                 arguments = error_mark_node;
   29782                 :             :               else
   29783                 :             :                 {
   29784                 :    10037780 :                   arguments = build_tree_list_vec (vec);
   29785                 :    10037780 :                   release_tree_vector (vec);
   29786                 :             :                 }
   29787                 :             :               /* Save the arguments away.  */
   29788                 :    10037822 :               TREE_VALUE (attribute) = arguments;
   29789                 :             :             }
   29790                 :             : 
   29791                 :    22555833 :           if (arguments != error_mark_node)
   29792                 :             :             {
   29793                 :             :               /* Add this attribute to the list.  */
   29794                 :    22555791 :               TREE_CHAIN (attribute) = attribute_list;
   29795                 :    22555791 :               attribute_list = attribute;
   29796                 :             :             }
   29797                 :             : 
   29798                 :    22555833 :           token = cp_lexer_peek_token (parser->lexer);
   29799                 :             :         }
   29800                 :             :       /* Unless EXACTLY_ONE is set look for more attributes.
   29801                 :             :          If the next token isn't a `,', we're done.  */
   29802                 :    22555853 :       if (exactly_one || token->type != CPP_COMMA)
   29803                 :             :         break;
   29804                 :             : 
   29805                 :             :       /* Consume the comma and keep going.  */
   29806                 :     2920729 :       cp_lexer_consume_token (parser->lexer);
   29807                 :     2920729 :     }
   29808                 :    19635124 :   parser->translate_strings_p = save_translate_strings_p;
   29809                 :             : 
   29810                 :             :   /* We built up the list in reverse order.  */
   29811                 :    19635124 :   return nreverse (attribute_list);
   29812                 :             : }
   29813                 :             : 
   29814                 :             : /* Parse arguments of omp::directive attribute.
   29815                 :             : 
   29816                 :             :    ( directive-name ,[opt] clause-list[opt] )
   29817                 :             : 
   29818                 :             :    For directive just remember the first/last tokens for subsequent
   29819                 :             :    parsing.  */
   29820                 :             : 
   29821                 :             : static void
   29822                 :        2307 : cp_parser_omp_directive_args (cp_parser *parser, tree attribute, bool decl_p)
   29823                 :             : {
   29824                 :        2307 :   cp_token *first = cp_lexer_peek_nth_token (parser->lexer, 2);
   29825                 :        2307 :   if (first->type == CPP_CLOSE_PAREN)
   29826                 :             :     {
   29827                 :           9 :       cp_lexer_consume_token (parser->lexer);
   29828                 :           9 :       error_at (first->location, "expected OpenMP directive name");
   29829                 :           9 :       cp_lexer_consume_token (parser->lexer);
   29830                 :           9 :       TREE_VALUE (attribute) = NULL_TREE;
   29831                 :           9 :       return;
   29832                 :             :     }
   29833                 :        2298 :   size_t n = cp_parser_skip_balanced_tokens (parser, 1);
   29834                 :        2298 :   if (n == 1)
   29835                 :             :     {
   29836                 :           3 :       cp_lexer_consume_token (parser->lexer);
   29837                 :           3 :       error_at (first->location, "expected attribute argument as balanced "
   29838                 :             :                                  "token sequence");
   29839                 :           3 :       TREE_VALUE (attribute) = NULL_TREE;
   29840                 :           3 :       return;
   29841                 :             :     }
   29842                 :       55170 :   for (n = n - 2; n; --n)
   29843                 :       52875 :     cp_lexer_consume_token (parser->lexer);
   29844                 :        2295 :   cp_token *last = cp_lexer_peek_token (parser->lexer);
   29845                 :        2295 :   cp_lexer_consume_token (parser->lexer);
   29846                 :        2295 :   tree arg = make_node (DEFERRED_PARSE);
   29847                 :        2295 :   DEFPARSE_TOKENS (arg) = cp_token_cache_new (first, last);
   29848                 :        2295 :   DEFPARSE_INSTANTIATIONS (arg) = nullptr;
   29849                 :        2295 :   if (decl_p)
   29850                 :         231 :     TREE_PUBLIC (arg) = 1;
   29851                 :        2295 :   TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
   29852                 :             : }
   29853                 :             : 
   29854                 :             : /* Parse arguments of omp::sequence attribute.
   29855                 :             : 
   29856                 :             :    ( omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... )  */
   29857                 :             : 
   29858                 :             : static void
   29859                 :         300 : cp_parser_omp_sequence_args (cp_parser *parser, tree attribute)
   29860                 :             : {
   29861                 :         300 :   matching_parens parens;
   29862                 :         300 :   parens.consume_open (parser);
   29863                 :         684 :   do
   29864                 :             :     {
   29865                 :         492 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   29866                 :         492 :       if (token->type == CPP_NAME
   29867                 :         489 :           && token->u.value == omp_identifier
   29868                 :         714 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SCOPE))
   29869                 :             :         {
   29870                 :         222 :           cp_lexer_consume_token (parser->lexer);
   29871                 :         222 :           cp_lexer_consume_token (parser->lexer);
   29872                 :         222 :           token = cp_lexer_peek_token (parser->lexer);
   29873                 :             :         }
   29874                 :         492 :       bool directive = false;
   29875                 :         492 :       const char *p;
   29876                 :         492 :       if (token->type != CPP_NAME)
   29877                 :             :         p = "";
   29878                 :             :       else
   29879                 :         489 :         p = IDENTIFIER_POINTER (token->u.value);
   29880                 :         492 :       if (strcmp (p, "directive") == 0)
   29881                 :             :         directive = true;
   29882                 :          42 :       else if (strcmp (p, "sequence") != 0)
   29883                 :             :         {
   29884                 :          27 :           error_at (token->location, "expected %<directive%> or %<sequence%>");
   29885                 :          27 :           cp_parser_skip_to_closing_parenthesis (parser,
   29886                 :             :                                                  /*recovering=*/true,
   29887                 :             :                                                  /*or_comma=*/true,
   29888                 :             :                                                  /*consume_paren=*/false);
   29889                 :          27 :           if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   29890                 :             :             break;
   29891                 :           0 :           cp_lexer_consume_token (parser->lexer);
   29892                 :             :         }
   29893                 :         465 :       cp_lexer_consume_token (parser->lexer);
   29894                 :         465 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
   29895                 :           6 :         cp_parser_required_error (parser, RT_OPEN_PAREN, false,
   29896                 :             :                                   UNKNOWN_LOCATION);
   29897                 :         459 :       else if (directive)
   29898                 :         447 :         cp_parser_omp_directive_args (parser, attribute, false);
   29899                 :             :       else
   29900                 :          12 :         cp_parser_omp_sequence_args (parser, attribute);
   29901                 :         465 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   29902                 :             :         break;
   29903                 :         192 :       cp_lexer_consume_token (parser->lexer);
   29904                 :         192 :     }
   29905                 :             :   while (1);
   29906                 :         300 :   if (!parens.require_close (parser))
   29907                 :           3 :     cp_parser_skip_to_closing_parenthesis (parser, true, false,
   29908                 :             :                                            /*consume_paren=*/true);
   29909                 :         300 : }
   29910                 :             : 
   29911                 :             : /*  Parse a standard C++11 attribute.
   29912                 :             : 
   29913                 :             :     The returned representation is a TREE_LIST which TREE_PURPOSE is
   29914                 :             :     the scoped name of the attribute, and the TREE_VALUE is its
   29915                 :             :     arguments list.
   29916                 :             : 
   29917                 :             :     Note that the scoped name of the attribute is itself a TREE_LIST
   29918                 :             :     which TREE_PURPOSE is the namespace of the attribute, and
   29919                 :             :     TREE_VALUE its name.  This is unlike a GNU attribute -- as parsed
   29920                 :             :     by cp_parser_gnu_attribute_list -- that doesn't have any namespace
   29921                 :             :     and which TREE_PURPOSE is directly the attribute name.
   29922                 :             : 
   29923                 :             :     Clients of the attribute code should use get_attribute_namespace
   29924                 :             :     and get_attribute_name to get the actual namespace and name of
   29925                 :             :     attributes, regardless of their being GNU or C++11 attributes.
   29926                 :             : 
   29927                 :             :     attribute:
   29928                 :             :       attribute-token attribute-argument-clause [opt]
   29929                 :             : 
   29930                 :             :     attribute-token:
   29931                 :             :       identifier
   29932                 :             :       attribute-scoped-token
   29933                 :             : 
   29934                 :             :     attribute-scoped-token:
   29935                 :             :       attribute-namespace :: identifier
   29936                 :             : 
   29937                 :             :     attribute-namespace:
   29938                 :             :       identifier
   29939                 :             : 
   29940                 :             :     attribute-argument-clause:
   29941                 :             :       ( balanced-token-seq )
   29942                 :             : 
   29943                 :             :     balanced-token-seq:
   29944                 :             :       balanced-token [opt]
   29945                 :             :       balanced-token-seq balanced-token
   29946                 :             : 
   29947                 :             :     balanced-token:
   29948                 :             :       ( balanced-token-seq )
   29949                 :             :       [ balanced-token-seq ]
   29950                 :             :       { balanced-token-seq }.  */
   29951                 :             : 
   29952                 :             : static tree
   29953                 :    11516996 : cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
   29954                 :             : {
   29955                 :    11516996 :   tree attribute, attr_id = NULL_TREE, arguments;
   29956                 :    11516996 :   cp_token *token;
   29957                 :             : 
   29958                 :    11516996 :   auto cleanup = make_temp_override
   29959                 :    11516996 :     (parser->auto_is_implicit_function_template_parm_p, false);
   29960                 :             : 
   29961                 :             :   /* First, parse name of the attribute, a.k.a attribute-token.  */
   29962                 :             : 
   29963                 :    11516996 :   token = cp_lexer_peek_token (parser->lexer);
   29964                 :    11516996 :   if (token->type == CPP_NAME)
   29965                 :    11516731 :     attr_id = token->u.value;
   29966                 :         265 :   else if (token->type == CPP_KEYWORD)
   29967                 :          19 :     attr_id = ridpointers[(int) token->keyword];
   29968                 :         246 :   else if (token->flags & NAMED_OP)
   29969                 :          30 :     attr_id = get_identifier (cpp_type2name (token->type, token->flags));
   29970                 :             : 
   29971                 :    11516780 :   if (attr_id == NULL_TREE)
   29972                 :         216 :     return NULL_TREE;
   29973                 :             : 
   29974                 :    11516780 :   cp_lexer_consume_token (parser->lexer);
   29975                 :             : 
   29976                 :    11516780 :   token = cp_lexer_peek_token (parser->lexer);
   29977                 :    11516780 :   if (token->type == CPP_SCOPE)
   29978                 :             :     {
   29979                 :             :       /* We are seeing a scoped attribute token.  */
   29980                 :             : 
   29981                 :     1257489 :       cp_lexer_consume_token (parser->lexer);
   29982                 :     1257489 :       if (attr_ns)
   29983                 :           6 :         error_at (token->location, "attribute using prefix used together "
   29984                 :             :                                    "with scoped attribute token");
   29985                 :     1257489 :       attr_ns = attr_id;
   29986                 :             : 
   29987                 :     1257489 :       token = cp_lexer_peek_token (parser->lexer);
   29988                 :     1257489 :       if (token->type == CPP_NAME)
   29989                 :     1122610 :         attr_id = token->u.value;
   29990                 :      134879 :       else if (token->type == CPP_KEYWORD)
   29991                 :      134867 :         attr_id = ridpointers[(int) token->keyword];
   29992                 :          12 :       else if (token->flags & NAMED_OP)
   29993                 :           9 :         attr_id = get_identifier (cpp_type2name (token->type, token->flags));
   29994                 :             :       else
   29995                 :             :         {
   29996                 :           3 :           error_at (token->location,
   29997                 :             :                     "expected an identifier for the attribute name");
   29998                 :           3 :           return error_mark_node;
   29999                 :             :         }
   30000                 :     1257486 :       cp_lexer_consume_token (parser->lexer);
   30001                 :             : 
   30002                 :     1257486 :       attr_ns = canonicalize_attr_name (attr_ns);
   30003                 :     1257486 :       attr_id = canonicalize_attr_name (attr_id);
   30004                 :     1257486 :       attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
   30005                 :             :                                    NULL_TREE);
   30006                 :     1257486 :       token = cp_lexer_peek_token (parser->lexer);
   30007                 :             :     }
   30008                 :    10259291 :   else if (attr_ns)
   30009                 :             :     {
   30010                 :         137 :       attr_ns = canonicalize_attr_name (attr_ns);
   30011                 :         137 :       attr_id = canonicalize_attr_name (attr_id);
   30012                 :         137 :       attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
   30013                 :             :                                    NULL_TREE);
   30014                 :             :     }
   30015                 :             :   else
   30016                 :             :     {
   30017                 :    10259154 :       attr_id = canonicalize_attr_name (attr_id);
   30018                 :    10259154 :       attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id),
   30019                 :             :                                    NULL_TREE);
   30020                 :             : 
   30021                 :             :       /* We used to treat C++11 noreturn attribute as equivalent to GNU's,
   30022                 :             :          but no longer: we have to be able to tell [[noreturn]] and
   30023                 :             :          __attribute__((noreturn)) apart.  */
   30024                 :             :       /* C++14 deprecated attribute is equivalent to GNU's.  */
   30025                 :    10259154 :       if (is_attribute_p ("deprecated", attr_id))
   30026                 :      194412 :         TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
   30027                 :             :       /* C++17 fallthrough attribute is equivalent to GNU's.  */
   30028                 :    10064742 :       else if (is_attribute_p ("fallthrough", attr_id))
   30029                 :       11962 :         TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
   30030                 :             :       /* C++23 assume attribute is equivalent to GNU's.  */
   30031                 :    10052780 :       else if (is_attribute_p ("assume", attr_id))
   30032                 :         273 :         TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
   30033                 :             :       /* Transactional Memory TS optimize_for_synchronized attribute is
   30034                 :             :          equivalent to GNU transaction_callable.  */
   30035                 :    10052507 :       else if (is_attribute_p ("optimize_for_synchronized", attr_id))
   30036                 :           6 :         TREE_PURPOSE (attribute)
   30037                 :           3 :           = get_identifier ("transaction_callable");
   30038                 :             :       /* Transactional Memory attributes are GNU attributes.  */
   30039                 :    10052504 :       else if (tm_attr_to_mask (attr_id))
   30040                 :           0 :         TREE_PURPOSE (attribute) = attr_id;
   30041                 :             :     }
   30042                 :             : 
   30043                 :             :   /* Now parse the optional argument clause of the attribute.  */
   30044                 :             : 
   30045                 :    11516777 :   if (token->type != CPP_OPEN_PAREN)
   30046                 :             :     {
   30047                 :    11465826 :       if ((flag_openmp || flag_openmp_simd)
   30048                 :        6663 :           && attr_ns == omp_identifier
   30049                 :    11472501 :           && (is_attribute_p ("directive", attr_id)
   30050                 :           9 :               || is_attribute_p ("sequence", attr_id)
   30051                 :           6 :               || is_attribute_p ("decl", attr_id)))
   30052                 :             :         {
   30053                 :          12 :           error_at (token->location, "%<omp::%E%> attribute requires argument",
   30054                 :             :                     attr_id);
   30055                 :          12 :           return NULL_TREE;
   30056                 :             :         }
   30057                 :             :       return attribute;
   30058                 :             :     }
   30059                 :             : 
   30060                 :       44288 :   {
   30061                 :       44288 :     vec<tree, va_gc> *vec;
   30062                 :       44288 :     int attr_flag = normal_attr;
   30063                 :             : 
   30064                 :             :     /* Maybe we don't expect to see any arguments for this attribute.  */
   30065                 :       44288 :     const attribute_spec *as
   30066                 :       44288 :       = lookup_attribute_spec (TREE_PURPOSE (attribute));
   30067                 :       44288 :     if (as && as->max_length == 0)
   30068                 :             :       {
   30069                 :          18 :         error_at (token->location, "%qE attribute does not take any arguments",
   30070                 :             :                   attr_id);
   30071                 :          18 :         cp_parser_skip_to_closing_parenthesis (parser,
   30072                 :             :                                                /*recovering=*/true,
   30073                 :             :                                                /*or_comma=*/false,
   30074                 :             :                                                /*consume_paren=*/true);
   30075                 :          18 :         return error_mark_node;
   30076                 :             :       }
   30077                 :             : 
   30078                 :       44270 :     if (is_attribute_p ("assume", attr_id)
   30079                 :       44270 :         && (attr_ns == NULL_TREE || attr_ns == gnu_identifier))
   30080                 :             :       /* The assume attribute needs special handling of the argument.  */
   30081                 :             :       attr_flag = assume_attr;
   30082                 :       43907 :     else if (attr_ns == gnu_identifier
   30083                 :       43907 :              && attribute_takes_identifier_p (attr_id))
   30084                 :             :       /* A GNU attribute that takes an identifier in parameter.  */
   30085                 :             :       attr_flag = id_attr;
   30086                 :       34277 :     else if (attr_ns == NULL_TREE
   30087                 :       31780 :              && cxx_dialect >= cxx26
   30088                 :       35345 :              && (is_attribute_p ("deprecated", attr_id)
   30089                 :          21 :                  || is_attribute_p ("nodiscard", attr_id)))
   30090                 :             :       attr_flag = uneval_string_attr;
   30091                 :             : 
   30092                 :             :     /* If this is a fake attribute created to handle -Wno-attributes,
   30093                 :             :        we must skip parsing the arguments.  */
   30094                 :       44270 :     if (as == NULL || attribute_ignored_p (as))
   30095                 :             :       {
   30096                 :        2234 :         if ((flag_openmp || flag_openmp_simd) && attr_ns == omp_identifier)
   30097                 :             :           {
   30098                 :        2148 :             if (is_attribute_p ("directive", attr_id))
   30099                 :             :               {
   30100                 :        1623 :                 cp_parser_omp_directive_args (parser, attribute, false);
   30101                 :        1623 :                 return attribute;
   30102                 :             :               }
   30103                 :         525 :             else if (is_attribute_p ("decl", attr_id))
   30104                 :             :               {
   30105                 :         237 :                 TREE_VALUE (TREE_PURPOSE (attribute))
   30106                 :         237 :                   = get_identifier ("directive");
   30107                 :         237 :                 cp_parser_omp_directive_args (parser, attribute, true);
   30108                 :         237 :                 return attribute;
   30109                 :             :               }
   30110                 :         288 :             else if (is_attribute_p ("sequence", attr_id))
   30111                 :             :               {
   30112                 :         288 :                 TREE_VALUE (TREE_PURPOSE (attribute))
   30113                 :         288 :                   = get_identifier ("directive");
   30114                 :         288 :                 cp_parser_omp_sequence_args (parser, attribute);
   30115                 :         288 :                 TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
   30116                 :         288 :                 return attribute;
   30117                 :             :               }
   30118                 :             :           }
   30119                 :             : 
   30120                 :             :         /* For unknown attributes, just skip balanced tokens instead of
   30121                 :             :            trying to parse the arguments.  Set TREE_VALUE (attribute) to
   30122                 :             :            error_mark_node to distinguish skipped arguments from attributes
   30123                 :             :            with no arguments.  */
   30124                 :         593 :         for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; n; --n)
   30125                 :         507 :           cp_lexer_consume_token (parser->lexer);
   30126                 :          86 :         TREE_VALUE (attribute) = error_mark_node;
   30127                 :          86 :         return attribute;
   30128                 :             :       }
   30129                 :             : 
   30130                 :       42036 :     vec = cp_parser_parenthesized_expression_list
   30131                 :       42036 :       (parser, attr_flag, /*cast_p=*/false,
   30132                 :             :        /*allow_expansion_p=*/true,
   30133                 :             :        /*non_constant_p=*/NULL);
   30134                 :       42036 :     if (vec == NULL)
   30135                 :          27 :       arguments = error_mark_node;
   30136                 :             :     else
   30137                 :             :       {
   30138                 :       42009 :         if (vec->is_empty ())
   30139                 :             :           /* e.g. [[attr()]].  */
   30140                 :          15 :           error_at (token->location, "parentheses must be omitted if "
   30141                 :             :                     "%qE attribute argument list is empty",
   30142                 :             :                     attr_id);
   30143                 :       42009 :         arguments = build_tree_list_vec (vec);
   30144                 :       42009 :         release_tree_vector (vec);
   30145                 :             :       }
   30146                 :             : 
   30147                 :       42036 :     if (arguments == error_mark_node)
   30148                 :             :       attribute = error_mark_node;
   30149                 :             :     else
   30150                 :       42009 :       TREE_VALUE (attribute) = arguments;
   30151                 :             :   }
   30152                 :             : 
   30153                 :             :   return attribute;
   30154                 :    11516996 : }
   30155                 :             : 
   30156                 :             : /* Warn if the attribute ATTRIBUTE appears more than once in the
   30157                 :             :    attribute-list ATTRIBUTES.  This used to be enforced for certain
   30158                 :             :    attributes, but the restriction was removed in P2156.
   30159                 :             :    LOC is the location of ATTRIBUTE.  Returns true if ATTRIBUTE was not
   30160                 :             :    found in ATTRIBUTES.  */
   30161                 :             : 
   30162                 :             : static bool
   30163                 :    11516720 : cp_parser_check_std_attribute (location_t loc, tree attributes, tree attribute)
   30164                 :             : {
   30165                 :    11516720 :   static auto alist = { "noreturn", "deprecated", "nodiscard", "maybe_unused",
   30166                 :             :                         "likely", "unlikely", "fallthrough",
   30167                 :             :                         "no_unique_address", "carries_dependency" };
   30168                 :    11516720 :   if (attributes)
   30169                 :     6192884 :     for (const auto &a : alist)
   30170                 :     5573611 :       if (is_attribute_p (a, get_attribute_name (attribute))
   30171                 :       37935 :           && is_attribute_namespace_p ("", attribute)
   30172                 :     5611541 :           && lookup_attribute ("", a, attributes))
   30173                 :             :         {
   30174                 :          39 :           if (!from_macro_expansion_at (loc))
   30175                 :          36 :             warning_at (loc, OPT_Wattributes, "attribute %qs specified "
   30176                 :             :                         "multiple times", a);
   30177                 :          39 :           return false;
   30178                 :             :         }
   30179                 :             :   return true;
   30180                 :             : }
   30181                 :             : 
   30182                 :             : /* Parse a list of standard C++-11 attributes.
   30183                 :             : 
   30184                 :             :    attribute-list:
   30185                 :             :      attribute [opt]
   30186                 :             :      attribute-list , attribute[opt]
   30187                 :             :      attribute ...
   30188                 :             :      attribute-list , attribute ...
   30189                 :             : */
   30190                 :             : 
   30191                 :             : static tree
   30192                 :    10897674 : cp_parser_std_attribute_list (cp_parser *parser, tree attr_ns)
   30193                 :             : {
   30194                 :    10897674 :   tree attributes = NULL_TREE, attribute = NULL_TREE;
   30195                 :    10897674 :   cp_token *token = NULL;
   30196                 :             : 
   30197                 :    12136318 :   while (true)
   30198                 :             :     {
   30199                 :    11516996 :       location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   30200                 :    11516996 :       attribute = cp_parser_std_attribute (parser, attr_ns);
   30201                 :    11516996 :       if (attribute == error_mark_node)
   30202                 :             :         break;
   30203                 :    11516948 :       if (attribute != NULL_TREE)
   30204                 :             :         {
   30205                 :    11516720 :           if (cp_parser_check_std_attribute (loc, attributes, attribute))
   30206                 :             :             {
   30207                 :    11516681 :               TREE_CHAIN (attribute) = attributes;
   30208                 :    11516681 :               attributes = attribute;
   30209                 :             :             }
   30210                 :             :         }
   30211                 :    11516948 :       token = cp_lexer_peek_token (parser->lexer);
   30212                 :    11516948 :       if (token->type == CPP_ELLIPSIS)
   30213                 :             :         {
   30214                 :          48 :           cp_lexer_consume_token (parser->lexer);
   30215                 :          48 :           if (attribute == NULL_TREE)
   30216                 :           6 :             error_at (token->location,
   30217                 :             :                       "expected attribute before %<...%>");
   30218                 :          42 :           else if (TREE_VALUE (attribute) == NULL_TREE)
   30219                 :             :             {
   30220                 :          21 :               error_at (token->location, "attribute with no arguments "
   30221                 :             :                                          "contains no parameter packs");
   30222                 :          21 :               return error_mark_node;
   30223                 :             :             }
   30224                 :          21 :           else if (TREE_VALUE (attribute) != error_mark_node)
   30225                 :             :             {
   30226                 :          18 :               tree pack = make_pack_expansion (TREE_VALUE (attribute));
   30227                 :          18 :               if (pack == error_mark_node)
   30228                 :           9 :                 return error_mark_node;
   30229                 :           9 :               TREE_VALUE (attribute) = pack;
   30230                 :             :             }
   30231                 :          18 :           token = cp_lexer_peek_token (parser->lexer);
   30232                 :             :         }
   30233                 :    11516918 :       if (token->type != CPP_COMMA)
   30234                 :             :         break;
   30235                 :      619322 :       cp_lexer_consume_token (parser->lexer);
   30236                 :      619322 :     }
   30237                 :    10897644 :   attributes = nreverse (attributes);
   30238                 :    10897644 :   return attributes;
   30239                 :             : }
   30240                 :             : 
   30241                 :             : /* Optionally parse a C++20 contract role. A NULL return means that no
   30242                 :             :    contract role was specified.
   30243                 :             : 
   30244                 :             :     contract-role:
   30245                 :             :       % default
   30246                 :             :       % identifier
   30247                 :             : 
   30248                 :             :    If the identifier does not name a known contract role, it will
   30249                 :             :    be assumed to be default. Returns the identifier for the role
   30250                 :             :    token.  */
   30251                 :             : 
   30252                 :             : static tree
   30253                 :          31 : cp_parser_contract_role (cp_parser *parser)
   30254                 :             : {
   30255                 :          31 :   gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_MOD));
   30256                 :          31 :   cp_lexer_consume_token (parser->lexer);
   30257                 :             : 
   30258                 :          31 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   30259                 :          31 :   tree role_id = NULL_TREE;
   30260                 :          31 :   if (token->type == CPP_NAME)
   30261                 :          12 :     role_id = token->u.value;
   30262                 :          19 :   else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
   30263                 :          19 :     role_id = get_identifier ("default");
   30264                 :             :   else
   30265                 :             :     {
   30266                 :           0 :       error_at (token->location, "expected contract-role");
   30267                 :           0 :       return error_mark_node;
   30268                 :             :     }
   30269                 :          31 :   cp_lexer_consume_token (parser->lexer);
   30270                 :             : 
   30271                 :             :   /* FIXME: Warn about invalid/unknown roles?  */
   30272                 :          31 :   return role_id;
   30273                 :             : }
   30274                 :             : 
   30275                 :             : /* Parse an optional contract mode.
   30276                 :             : 
   30277                 :             :      contract-mode:
   30278                 :             :         contract-semantic
   30279                 :             :         [contract-level] [contract-role]
   30280                 :             : 
   30281                 :             :      contract-semantic:
   30282                 :             :        check_never_continue
   30283                 :             :        check_maybe_continue
   30284                 :             :        check_always_continue
   30285                 :             : 
   30286                 :             :      contract-level:
   30287                 :             :        default
   30288                 :             :        audit
   30289                 :             :        axiom
   30290                 :             : 
   30291                 :             :      contract-role:
   30292                 :             :        default
   30293                 :             :        identifier
   30294                 :             : 
   30295                 :             :    This grammar is taken from P1332R0. During parsing, this sets options
   30296                 :             :    on the MODE object to determine the configuration of the contract.
   30297                 :             : 
   30298                 :             :    Returns a tree containing the identifiers used in the configuration.
   30299                 :             :    This is either an IDENTIFIER with the literal semantic or a TREE_LIST
   30300                 :             :    whose TREE_VALUE is the contract-level and whose TREE_PURPOSE is the
   30301                 :             :    contract-role, if any. NULL_TREE is returned if no information is
   30302                 :             :    given (i.e., all defaults selected).  */
   30303                 :             : 
   30304                 :             : static tree
   30305                 :         824 : cp_parser_contract_mode_opt (cp_parser *parser,
   30306                 :             :                              bool postcondition_p)
   30307                 :             : {
   30308                 :             :   /* The mode is empty; the level and role are default.  */
   30309                 :         824 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   30310                 :             :     return NULL_TREE;
   30311                 :             : 
   30312                 :             :   /* There is only a role; the level is default.  */
   30313                 :         186 :   if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
   30314                 :             :     {
   30315                 :          10 :       tree role_id = cp_parser_contract_role (parser);
   30316                 :          10 :       return build_tree_list (role_id, get_identifier ("default"));
   30317                 :             :     }
   30318                 :             : 
   30319                 :             :   /* Otherwise, match semantic or level.  */
   30320                 :         176 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   30321                 :         176 :   contract_level level = CONTRACT_INVALID;
   30322                 :         176 :   contract_semantic semantic = CCS_INVALID;
   30323                 :         176 :   tree config_id;
   30324                 :         176 :   if (token->type == CPP_NAME)
   30325                 :             :     {
   30326                 :         151 :       config_id = token->u.value;
   30327                 :             : 
   30328                 :             :       /* Either a named level, a concrete semantic, or an identifier
   30329                 :             :          for a postcondition.  */
   30330                 :         151 :       const char *ident = IDENTIFIER_POINTER (token->u.value);
   30331                 :         151 :       level = map_contract_level (ident);
   30332                 :         151 :       semantic = map_contract_semantic (ident);
   30333                 :             : 
   30334                 :             :       /* The identifier is the return value for a postcondition.  */
   30335                 :         151 :       if (level == CONTRACT_INVALID && semantic == CCS_INVALID
   30336                 :          72 :           && postcondition_p)
   30337                 :             :         return NULL_TREE;
   30338                 :             :     }
   30339                 :          25 :   else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
   30340                 :             :     {
   30341                 :          25 :       config_id = get_identifier ("default");
   30342                 :          25 :       level = CONTRACT_DEFAULT;
   30343                 :             :     }
   30344                 :             :   else
   30345                 :             :     {
   30346                 :             :       /* We got some other token other than a ':'.  */
   30347                 :           0 :       error_at (token->location, "expected contract semantic or level");
   30348                 :           0 :       return NULL_TREE;
   30349                 :             :     }
   30350                 :             : 
   30351                 :             :   /* Consume the literal semantic or level token.  */
   30352                 :         107 :   cp_lexer_consume_token (parser->lexer);
   30353                 :             : 
   30354                 :         107 :   if (semantic == CCS_INVALID && level == CONTRACT_INVALID)
   30355                 :             :     {
   30356                 :           3 :       error_at (token->location,
   30357                 :             :                 "expected contract level: "
   30358                 :             :                 "%<default%>, %<audit%>, or %<axiom%>");
   30359                 :           3 :       return NULL_TREE;
   30360                 :             :     }
   30361                 :             : 
   30362                 :             :   /* We matched an explicit semantic. */
   30363                 :         104 :   if (semantic != CCS_INVALID)
   30364                 :             :     {
   30365                 :          40 :       if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
   30366                 :             :         {
   30367                 :           0 :           error ("invalid use of contract role for explicit semantic");
   30368                 :           0 :           cp_lexer_consume_token (parser->lexer);
   30369                 :           0 :           cp_lexer_consume_token (parser->lexer);
   30370                 :             :         }
   30371                 :          40 :       return config_id;
   30372                 :             :     }
   30373                 :             : 
   30374                 :             :   /* We matched a level, there may be a role; otherwise this is default.  */
   30375                 :          64 :   if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
   30376                 :             :     {
   30377                 :          21 :       tree role_id = cp_parser_contract_role (parser);
   30378                 :          21 :       return build_tree_list (role_id, config_id);
   30379                 :             :     }
   30380                 :             : 
   30381                 :          43 :   return build_tree_list (NULL_TREE, config_id);
   30382                 :             : }
   30383                 :             : 
   30384                 :             : static tree
   30385                 :        2716 : find_error (tree *tp, int *, void *)
   30386                 :             : {
   30387                 :        2716 :   if (*tp == error_mark_node)
   30388                 :          11 :     return *tp;
   30389                 :             :   return NULL_TREE;
   30390                 :             : }
   30391                 :             : 
   30392                 :             : static bool
   30393                 :         588 : contains_error_p (tree t)
   30394                 :             : {
   30395                 :         588 :   return walk_tree (&t, find_error, NULL, NULL);
   30396                 :             : }
   30397                 :             : 
   30398                 :             : /* Parse a standard C++20 contract attribute specifier.
   30399                 :             : 
   30400                 :             :   contract-attribute-specifier:
   30401                 :             :     [ [ assert contract-level [opt] : conditional-expression ] ]
   30402                 :             :     [ [ pre contract-level [opt] : conditional-expression ] ]
   30403                 :             :     [ [ post contract-level [opt] identifier [opt] : conditional-expression ] ]
   30404                 :             : 
   30405                 :             :    For free functions, we cannot determine the type of the postcondition
   30406                 :             :    identifier because the we haven't called grokdeclarator yet. In those
   30407                 :             :    cases we parse the postcondition as if the identifier was declared as
   30408                 :             :    'auto <identifier>'. We then instantiate the postcondition once the
   30409                 :             :    return type is known.
   30410                 :             : 
   30411                 :             :    For member functions, contracts are in the complete-class context, so the
   30412                 :             :    parse is deferred. We also have the return type avaialable (unless it's
   30413                 :             :    deduced), so we don't need to parse the postcondition in terms of a
   30414                 :             :    placeholder.  */
   30415                 :             : 
   30416                 :             : static tree
   30417                 :         824 : cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute)
   30418                 :             : {
   30419                 :         824 :   gcc_assert (contract_attribute_p (attribute));
   30420                 :         824 :   cp_token *token = cp_lexer_consume_token (parser->lexer);
   30421                 :         824 :   location_t loc = token->location;
   30422                 :             : 
   30423                 :         824 :   bool assertion_p = is_attribute_p ("assert", attribute);
   30424                 :         824 :   bool postcondition_p = is_attribute_p ("post", attribute);
   30425                 :             : 
   30426                 :             :   /* Parse the optional mode.  */
   30427                 :         824 :   tree mode = cp_parser_contract_mode_opt (parser, postcondition_p);
   30428                 :             : 
   30429                 :             :   /* Check for postcondition identifiers.  */
   30430                 :         824 :   cp_expr identifier;
   30431                 :         824 :   if (postcondition_p && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   30432                 :          74 :     identifier = cp_parser_identifier (parser);
   30433                 :         824 :   if (identifier == error_mark_node)
   30434                 :             :     return error_mark_node;
   30435                 :             : 
   30436                 :         824 :   cp_parser_require (parser, CPP_COLON, RT_COLON);
   30437                 :             : 
   30438                 :             :   /* Defer the parsing of pre/post contracts inside class definitions.  */
   30439                 :         824 :   tree contract;
   30440                 :        1492 :   if (!assertion_p &&
   30441                 :         824 :       current_class_type &&
   30442                 :         339 :       TYPE_BEING_DEFINED (current_class_type))
   30443                 :             :     {
   30444                 :             :       /* Skip until we reach an unenclose ']'. If we ran into an unnested ']'
   30445                 :             :          that doesn't close the attribute, return an error and let the attribute
   30446                 :             :          handling code emit an error for missing ']]'.  */
   30447                 :         236 :       cp_token *first = cp_lexer_peek_token (parser->lexer);
   30448                 :         236 :       cp_parser_skip_to_closing_parenthesis_1 (parser,
   30449                 :             :                                                /*recovering=*/false,
   30450                 :             :                                                CPP_CLOSE_SQUARE,
   30451                 :             :                                                /*consume_paren=*/false);
   30452                 :         236 :       if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE
   30453                 :         236 :           || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_CLOSE_SQUARE)
   30454                 :           0 :         return error_mark_node;
   30455                 :         236 :       cp_token *last = cp_lexer_peek_token (parser->lexer);
   30456                 :             : 
   30457                 :             :       /* Build a deferred-parse node.  */
   30458                 :         236 :       tree condition = make_node (DEFERRED_PARSE);
   30459                 :         236 :       DEFPARSE_TOKENS (condition) = cp_token_cache_new (first, last);
   30460                 :         236 :       DEFPARSE_INSTANTIATIONS (condition) = NULL;
   30461                 :             : 
   30462                 :             :       /* And its corresponding contract.  */
   30463                 :         236 :       contract = grok_contract (attribute, mode, identifier, condition, loc);
   30464                 :             :     }
   30465                 :             :   else
   30466                 :             :     {
   30467                 :             :       /* Enable location wrappers when parsing contracts.  */
   30468                 :         588 :       auto suppression = make_temp_override (suppress_location_wrappers, 0);
   30469                 :             : 
   30470                 :             :       /* Build a fake variable for the result identifier.  */
   30471                 :         588 :       tree result = NULL_TREE;
   30472                 :         588 :       if (identifier)
   30473                 :             :         {
   30474                 :          66 :           begin_scope (sk_block, NULL_TREE);
   30475                 :          66 :           result = make_postcondition_variable (identifier);
   30476                 :          66 :           ++processing_template_decl;
   30477                 :             :         }
   30478                 :             : 
   30479                 :             :       /* Parse the condition, ensuring that parameters or the return variable
   30480                 :             :          aren't flagged for use outside the body of a function.  */
   30481                 :         588 :       ++processing_contract_condition;
   30482                 :         588 :       cp_expr condition = cp_parser_conditional_expression (parser);
   30483                 :         588 :       --processing_contract_condition;
   30484                 :             : 
   30485                 :             :       /* Try to recover from errors by scanning up to the end of the
   30486                 :             :          attribute.  Sometimes we get partially parsed expressions, so
   30487                 :             :          we need to search the condition for errors.  */
   30488                 :         588 :       if (contains_error_p (condition))
   30489                 :          11 :         cp_parser_skip_up_to_closing_square_bracket (parser);
   30490                 :             : 
   30491                 :             :       /* Build the contract.  */
   30492                 :         588 :       contract = grok_contract (attribute, mode, result, condition, loc);
   30493                 :             : 
   30494                 :             :       /* Leave our temporary scope for the postcondition result.  */
   30495                 :         588 :       if (result)
   30496                 :             :         {
   30497                 :          66 :           --processing_template_decl;
   30498                 :          66 :           pop_bindings_and_leave_scope ();
   30499                 :             :         }
   30500                 :         588 :     }
   30501                 :             : 
   30502                 :         824 :   if (!flag_contracts)
   30503                 :             :     {
   30504                 :           3 :       error_at (loc, "contracts are only available with %<-fcontracts%>");
   30505                 :           3 :       return error_mark_node;
   30506                 :             :     }
   30507                 :             : 
   30508                 :         821 :   return finish_contract_attribute (attribute, contract);
   30509                 :             : }
   30510                 :             : 
   30511                 :             : /* Parse a contract condition for a deferred contract.  */
   30512                 :             : 
   30513                 :         236 : void cp_parser_late_contract_condition (cp_parser *parser,
   30514                 :             :                                         tree fn,
   30515                 :             :                                         tree attribute)
   30516                 :             : {
   30517                 :         236 :   tree contract = TREE_VALUE (TREE_VALUE (attribute));
   30518                 :             : 
   30519                 :             :   /* Make sure we've gotten something that hasn't been parsed yet or that
   30520                 :             :      we're not parsing an invalid contract.  */
   30521                 :         236 :   tree condition = CONTRACT_CONDITION (contract);
   30522                 :         236 :   if (TREE_CODE (condition) != DEFERRED_PARSE)
   30523                 :             :     return;
   30524                 :             : 
   30525                 :         225 :   tree identifier = NULL_TREE;
   30526                 :         225 :   if (TREE_CODE (contract) == POSTCONDITION_STMT)
   30527                 :          35 :     identifier = POSTCONDITION_IDENTIFIER (contract);
   30528                 :             : 
   30529                 :             :   /* Build a fake variable for the result identifier.  */
   30530                 :          35 :   tree result = NULL_TREE;
   30531                 :          35 :   if (identifier)
   30532                 :             :     {
   30533                 :             :       /* TODO: Can we guarantee that the identifier has a location? */
   30534                 :           8 :       location_t loc = cp_expr_location (contract);
   30535                 :           8 :       tree type = TREE_TYPE (TREE_TYPE (fn));
   30536                 :           8 :       if (!check_postcondition_result (fn, type, loc))
   30537                 :             :         {
   30538                 :           4 :           invalidate_contract (contract);
   30539                 :           4 :           return;
   30540                 :             :         }
   30541                 :             : 
   30542                 :           4 :       begin_scope (sk_block, NULL_TREE);
   30543                 :           4 :       result = make_postcondition_variable (identifier, type);
   30544                 :           4 :       ++processing_template_decl;
   30545                 :             :     }
   30546                 :             : 
   30547                 :             :   /* 'this' is not allowed in preconditions of constructors or in postconditions
   30548                 :             :      of destructors.  Note that the previous value of this variable is
   30549                 :             :      established by the calling function, so we need to save it here.  */
   30550                 :         221 :   tree saved_ccr = current_class_ref;
   30551                 :         221 :   tree saved_ccp = current_class_ptr;
   30552                 :         442 :   if ((DECL_CONSTRUCTOR_P (fn) && PRECONDITION_P (contract)) ||
   30553                 :         192 :        (DECL_DESTRUCTOR_P (fn) && POSTCONDITION_P (contract)))
   30554                 :             :     {
   30555                 :          39 :       current_class_ref = current_class_ptr = NULL_TREE;
   30556                 :          39 :       parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
   30557                 :             :     }
   30558                 :             : 
   30559                 :         221 :   push_unparsed_function_queues (parser);
   30560                 :             : 
   30561                 :             :   /* Push the saved tokens onto the parser's lexer stack.  */
   30562                 :         221 :   cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
   30563                 :         221 :   cp_parser_push_lexer_for_tokens (parser, tokens);
   30564                 :             : 
   30565                 :             :   /* Parse the condition, ensuring that parameters or the return variable
   30566                 :             :      aren't flagged for use outside the body of a function.  */
   30567                 :         221 :   ++processing_contract_condition;
   30568                 :         221 :   condition = cp_parser_conditional_expression (parser);
   30569                 :         221 :   --processing_contract_condition;
   30570                 :             : 
   30571                 :             :   /* Revert to the main lexer.  */
   30572                 :         221 :   cp_parser_pop_lexer (parser);
   30573                 :             : 
   30574                 :             :   /* Restore the queue.  */
   30575                 :         221 :   pop_unparsed_function_queues (parser);
   30576                 :             : 
   30577                 :         221 :   current_class_ref = saved_ccr;
   30578                 :         221 :   current_class_ptr = saved_ccp;
   30579                 :             : 
   30580                 :             :   /* Commit to changes.  */
   30581                 :         221 :   update_late_contract (contract, result, condition);
   30582                 :             : 
   30583                 :             :   /* Leave our temporary scope for the postcondition result.  */
   30584                 :         221 :   if (result)
   30585                 :             :     {
   30586                 :           4 :       --processing_template_decl;
   30587                 :           4 :       pop_bindings_and_leave_scope ();
   30588                 :             :     }
   30589                 :             : }
   30590                 :             : 
   30591                 :             : /* Parse a standard C++-11 attribute specifier.
   30592                 :             : 
   30593                 :             :    attribute-specifier:
   30594                 :             :      [ [ attribute-using-prefix [opt] attribute-list ] ]
   30595                 :             :      contract-attribute-specifier
   30596                 :             :      alignment-specifier
   30597                 :             : 
   30598                 :             :    attribute-using-prefix:
   30599                 :             :      using attribute-namespace :
   30600                 :             : 
   30601                 :             :    alignment-specifier:
   30602                 :             :      alignas ( type-id ... [opt] )
   30603                 :             :      alignas ( alignment-expression ... [opt] ).
   30604                 :             : 
   30605                 :             :    Extensions for contracts:
   30606                 :             : 
   30607                 :             :    contract-attribute-specifier:
   30608                 :             :      [ [ assert :  contract-mode [opt] : conditional-expression ] ]
   30609                 :             :      [ [ pre :  contract-mode [opt] : conditional-expression ] ]
   30610                 :             :      [ [ post :  contract-mode [opt] identifier [opt] :
   30611                 :             :          conditional-expression ] ]
   30612                 :             : 
   30613                 :             :    Return void_list_node if the current token doesn't start an
   30614                 :             :    attribute-specifier to differentiate from NULL_TREE returned e.g.
   30615                 :             :    for [ [ ] ].  */
   30616                 :             : 
   30617                 :             : static tree
   30618                 :  1103229006 : cp_parser_std_attribute_spec (cp_parser *parser)
   30619                 :             : {
   30620                 :  1103229006 :   tree attributes = NULL_TREE;
   30621                 :  1103229006 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   30622                 :             : 
   30623                 :  1103229006 :   if (token->type == CPP_OPEN_SQUARE
   30624                 :  1103229006 :       && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_SQUARE)
   30625                 :             :     {
   30626                 :    10898498 :       tree attr_ns = NULL_TREE;
   30627                 :    10898498 :       tree attr_name = NULL_TREE;
   30628                 :             : 
   30629                 :    10898498 :       cp_lexer_consume_token (parser->lexer);
   30630                 :    10898498 :       cp_lexer_consume_token (parser->lexer);
   30631                 :             : 
   30632                 :    10898498 :       token = cp_lexer_peek_token (parser->lexer);
   30633                 :    10898498 :       if (token->type == CPP_NAME)
   30634                 :             :         {
   30635                 :    10898167 :           attr_name = token->u.value;
   30636                 :    10898167 :           attr_name = canonicalize_attr_name (attr_name);
   30637                 :             :         }
   30638                 :             : 
   30639                 :             :       /* Handle contract-attribute-specs specially.  */
   30640                 :    10898167 :       if (attr_name && contract_attribute_p (attr_name))
   30641                 :             :         {
   30642                 :         824 :           tree attrs = cp_parser_contract_attribute_spec (parser, attr_name);
   30643                 :         824 :           if (attrs != error_mark_node)
   30644                 :         821 :             attributes = attrs;
   30645                 :         824 :           goto finish_attrs;
   30646                 :             :         }
   30647                 :             : 
   30648                 :    10897674 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
   30649                 :             :         {
   30650                 :         116 :           token = cp_lexer_peek_nth_token (parser->lexer, 2);
   30651                 :         116 :           if (token->type == CPP_NAME)
   30652                 :         107 :             attr_ns = token->u.value;
   30653                 :           9 :           else if (token->type == CPP_KEYWORD)
   30654                 :           3 :             attr_ns = ridpointers[(int) token->keyword];
   30655                 :           6 :           else if (token->flags & NAMED_OP)
   30656                 :           3 :             attr_ns = get_identifier (cpp_type2name (token->type,
   30657                 :             :                                                      token->flags));
   30658                 :         113 :           if (attr_ns
   30659                 :         113 :               && cp_lexer_nth_token_is (parser->lexer, 3, CPP_COLON))
   30660                 :             :             {
   30661                 :         113 :               if (cxx_dialect < cxx17)
   30662                 :          22 :                 pedwarn (input_location, OPT_Wc__17_extensions,
   30663                 :             :                          "attribute using prefix only available "
   30664                 :             :                          "with %<-std=c++17%> or %<-std=gnu++17%>");
   30665                 :             : 
   30666                 :         113 :               cp_lexer_consume_token (parser->lexer);
   30667                 :         113 :               cp_lexer_consume_token (parser->lexer);
   30668                 :         113 :               cp_lexer_consume_token (parser->lexer);
   30669                 :             :             }
   30670                 :             :           else
   30671                 :             :             attr_ns = NULL_TREE;
   30672                 :             :         }
   30673                 :             : 
   30674                 :    10897674 :       attributes = cp_parser_std_attribute_list (parser, attr_ns);
   30675                 :             : 
   30676                 :    10898498 :       finish_attrs:
   30677                 :    10898498 :       if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)
   30678                 :    10898498 :           || !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
   30679                 :          50 :         cp_parser_skip_to_end_of_statement (parser);
   30680                 :             :       else
   30681                 :             :         /* Warn about parsing c++11 attribute in non-c++11 mode, only
   30682                 :             :            when we are sure that we have actually parsed them.  */
   30683                 :    10898448 :         maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
   30684                 :             :     }
   30685                 :             :   else
   30686                 :             :     {
   30687                 :  1092330508 :       tree alignas_expr;
   30688                 :             : 
   30689                 :             :       /* Look for an alignment-specifier.  */
   30690                 :             : 
   30691                 :  1092330508 :       token = cp_lexer_peek_token (parser->lexer);
   30692                 :             : 
   30693                 :  1092330508 :       if (token->type != CPP_KEYWORD
   30694                 :  1092330508 :           || token->keyword != RID_ALIGNAS)
   30695                 :  1092181814 :         return void_list_node;
   30696                 :             : 
   30697                 :      148754 :       cp_lexer_consume_token (parser->lexer);
   30698                 :      148754 :       maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
   30699                 :             : 
   30700                 :      148754 :       matching_parens parens;
   30701                 :      148754 :       if (!parens.require_open (parser))
   30702                 :          21 :         return error_mark_node;
   30703                 :             : 
   30704                 :      148733 :       cp_parser_parse_tentatively (parser);
   30705                 :      148733 :       alignas_expr = cp_parser_type_id (parser);
   30706                 :             : 
   30707                 :      148733 :       if (!cp_parser_parse_definitely (parser))
   30708                 :             :         {
   30709                 :       45598 :           alignas_expr = cp_parser_assignment_expression (parser);
   30710                 :       45598 :           if (alignas_expr == error_mark_node)
   30711                 :          21 :             cp_parser_skip_to_end_of_statement (parser);
   30712                 :       45598 :           if (alignas_expr == NULL_TREE
   30713                 :       45598 :               || alignas_expr == error_mark_node)
   30714                 :             :             return alignas_expr;
   30715                 :             :         }
   30716                 :             : 
   30717                 :      148712 :       alignas_expr = cxx_alignas_expr (alignas_expr);
   30718                 :      148712 :       alignas_expr = build_tree_list (NULL_TREE, alignas_expr);
   30719                 :             : 
   30720                 :             :       /* Handle alignas (pack...).  */
   30721                 :      148712 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   30722                 :             :         {
   30723                 :          18 :           cp_lexer_consume_token (parser->lexer);
   30724                 :          18 :           alignas_expr = make_pack_expansion (alignas_expr);
   30725                 :             :         }
   30726                 :             : 
   30727                 :             :       /* Something went wrong, so don't build the attribute.  */
   30728                 :      148712 :       if (alignas_expr == error_mark_node)
   30729                 :             :         return error_mark_node;
   30730                 :             : 
   30731                 :             :       /* Missing ')' means the code cannot possibly be valid; go ahead
   30732                 :             :          and commit to make sure we issue a hard error.  */
   30733                 :      350008 :       if (cp_parser_uncommitted_to_tentative_parse_p (parser)
   30734                 :       52590 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
   30735                 :          12 :         cp_parser_commit_to_tentative_parse (parser);
   30736                 :             : 
   30737                 :      148709 :       if (!parens.require_close (parser))
   30738                 :          15 :         return error_mark_node;
   30739                 :             : 
   30740                 :             :       /* Build the C++-11 representation of an 'aligned'
   30741                 :             :          attribute.  */
   30742                 :      148694 :       attributes
   30743                 :      148694 :         = build_tree_list (build_tree_list (gnu_identifier,
   30744                 :             :                                             aligned_identifier), alignas_expr);
   30745                 :             :     }
   30746                 :             : 
   30747                 :             :   return attributes;
   30748                 :             : }
   30749                 :             : 
   30750                 :             : /* Parse a standard C++-11 attribute-specifier-seq.
   30751                 :             : 
   30752                 :             :    attribute-specifier-seq:
   30753                 :             :      attribute-specifier-seq [opt] attribute-specifier  */
   30754                 :             : 
   30755                 :             : static tree
   30756                 :  1092181844 : cp_parser_std_attribute_spec_seq (cp_parser *parser)
   30757                 :             : {
   30758                 :  1092181844 :   tree attr_specs = NULL_TREE;
   30759                 :  1092181844 :   tree attr_last = NULL_TREE;
   30760                 :             : 
   30761                 :             :   /* Don't create wrapper nodes within attributes: the
   30762                 :             :      handlers don't know how to handle them.  */
   30763                 :  1092181844 :   auto_suppress_location_wrappers sentinel;
   30764                 :             : 
   30765                 :  1103229006 :   while (true)
   30766                 :             :     {
   30767                 :  1103229006 :       tree attr_spec = cp_parser_std_attribute_spec (parser);
   30768                 :  1103229006 :       if (attr_spec == void_list_node)
   30769                 :             :         break;
   30770                 :             :       /* Accept [[]][[]]; for which cp_parser_std_attribute_spec
   30771                 :             :          returns NULL_TREE as there are no attributes.  */
   30772                 :    11047252 :       if (attr_spec == NULL_TREE)
   30773                 :         269 :         continue;
   30774                 :    11046983 :       if (attr_spec == error_mark_node)
   30775                 :          90 :         return error_mark_node;
   30776                 :             : 
   30777                 :    11046893 :       if (attr_last)
   30778                 :       35065 :         TREE_CHAIN (attr_last) = attr_spec;
   30779                 :             :       else
   30780                 :             :         attr_specs = attr_last = attr_spec;
   30781                 :    11046893 :       attr_last = tree_last (attr_last);
   30782                 :             :     }
   30783                 :             : 
   30784                 :             :   return attr_specs;
   30785                 :             : }
   30786                 :             : 
   30787                 :             : /* Skip a balanced-token starting at Nth token (with 1 as the next token),
   30788                 :             :    return index of the first token after balanced-token, or N on failure.  */
   30789                 :             : 
   30790                 :             : static size_t
   30791                 :     3591365 : cp_parser_skip_balanced_tokens (cp_parser *parser, size_t n)
   30792                 :             : {
   30793                 :     3591365 :   size_t orig_n = n;
   30794                 :     3591365 :   int nparens = 0, nbraces = 0, nsquares = 0;
   30795                 :    12136695 :   do
   30796                 :    12136695 :     switch (cp_lexer_peek_nth_token (parser->lexer, n++)->type)
   30797                 :             :       {
   30798                 :           0 :       case CPP_PRAGMA_EOL:
   30799                 :           0 :         if (!parser->lexer->in_pragma)
   30800                 :             :           break;
   30801                 :             :         /* FALLTHRU */
   30802                 :             :       case CPP_EOF:
   30803                 :             :         /* Ran out of tokens.  */
   30804                 :             :         return orig_n;
   30805                 :      147650 :       case CPP_OPEN_PAREN:
   30806                 :      147650 :         ++nparens;
   30807                 :      147650 :         break;
   30808                 :          85 :       case CPP_OPEN_BRACE:
   30809                 :          85 :         ++nbraces;
   30810                 :          85 :         break;
   30811                 :     3508754 :       case CPP_OPEN_SQUARE:
   30812                 :     3508754 :         ++nsquares;
   30813                 :     3508754 :         break;
   30814                 :      147635 :       case CPP_CLOSE_PAREN:
   30815                 :      147635 :         --nparens;
   30816                 :      147635 :         break;
   30817                 :          85 :       case CPP_CLOSE_BRACE:
   30818                 :          85 :         --nbraces;
   30819                 :          85 :         break;
   30820                 :     3508758 :       case CPP_CLOSE_SQUARE:
   30821                 :     3508758 :         --nsquares;
   30822                 :     3508758 :         break;
   30823                 :             :       default:
   30824                 :             :         break;
   30825                 :             :       }
   30826                 :    12136672 :   while (nparens || nbraces || nsquares);
   30827                 :             :   return n;
   30828                 :             : }
   30829                 :             : 
   30830                 :             : /* Skip GNU attribute tokens starting at Nth token (with 1 as the next token),
   30831                 :             :    return index of the first token after the GNU attribute tokens, or N on
   30832                 :             :    failure.  */
   30833                 :             : 
   30834                 :             : static size_t
   30835                 :       29386 : cp_parser_skip_gnu_attributes_opt (cp_parser *parser, size_t n)
   30836                 :             : {
   30837                 :       88158 :   while (true)
   30838                 :             :     {
   30839                 :       58772 :       if (!cp_lexer_nth_token_is_keyword (parser->lexer, n, RID_ATTRIBUTE)
   30840                 :       29386 :           || !cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_PAREN)
   30841                 :       88158 :           || !cp_lexer_nth_token_is (parser->lexer, n + 2, CPP_OPEN_PAREN))
   30842                 :             :         break;
   30843                 :             : 
   30844                 :       29386 :       size_t n2 = cp_parser_skip_balanced_tokens (parser, n + 2);
   30845                 :       29386 :       if (n2 == n + 2)
   30846                 :             :         break;
   30847                 :       29386 :       if (!cp_lexer_nth_token_is (parser->lexer, n2, CPP_CLOSE_PAREN))
   30848                 :             :         break;
   30849                 :       29386 :       n = n2 + 1;
   30850                 :       29386 :     }
   30851                 :       29386 :   return n;
   30852                 :             : }
   30853                 :             : 
   30854                 :             : /* Skip standard C++11 attribute tokens starting at Nth token (with 1 as the
   30855                 :             :    next token), return index of the first token after the standard C++11
   30856                 :             :    attribute tokens, or N on failure.  */
   30857                 :             : 
   30858                 :             : static size_t
   30859                 :   305894735 : cp_parser_skip_std_attribute_spec_seq (cp_parser *parser, size_t n)
   30860                 :             : {
   30861                 :   309453985 :   while (true)
   30862                 :             :     {
   30863                 :   309453985 :       if (cp_lexer_nth_token_is (parser->lexer, n, CPP_OPEN_SQUARE)
   30864                 :   309453985 :           && cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_SQUARE))
   30865                 :             :         {
   30866                 :     3508579 :           size_t n2 = cp_parser_skip_balanced_tokens (parser, n + 1);
   30867                 :     3508579 :           if (n2 == n + 1)
   30868                 :             :             break;
   30869                 :     3508565 :           if (!cp_lexer_nth_token_is (parser->lexer, n2, CPP_CLOSE_SQUARE))
   30870                 :             :             break;
   30871                 :     3508565 :           n = n2 + 1;
   30872                 :             :         }
   30873                 :   305945406 :       else if (cp_lexer_nth_token_is_keyword (parser->lexer, n, RID_ALIGNAS)
   30874                 :   305945406 :                && cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_PAREN))
   30875                 :             :         {
   30876                 :       50691 :           size_t n2 = cp_parser_skip_balanced_tokens (parser, n + 1);
   30877                 :       50691 :           if (n2 == n + 1)
   30878                 :             :             break;
   30879                 :             :           n = n2;
   30880                 :             :         }
   30881                 :             :       else
   30882                 :             :         break;
   30883                 :             :     }
   30884                 :   305894735 :   return n;
   30885                 :             : }
   30886                 :             : 
   30887                 :             : /* Skip standard C++11 or GNU attribute tokens starting at Nth token (with 1
   30888                 :             :    as the next token), return index of the first token after the attribute
   30889                 :             :    tokens, or N on failure.  */
   30890                 :             : 
   30891                 :             : static size_t
   30892                 :       52838 : cp_parser_skip_attributes_opt (cp_parser *parser, size_t n)
   30893                 :             : {
   30894                 :       52838 :   if (cp_nth_tokens_can_be_gnu_attribute_p (parser, n))
   30895                 :       29364 :     return cp_parser_skip_gnu_attributes_opt (parser, n);
   30896                 :       23474 :   return cp_parser_skip_std_attribute_spec_seq (parser, n);
   30897                 :             : }
   30898                 :             : 
   30899                 :             : /* Parse an optional `__extension__' keyword.  Returns TRUE if it is
   30900                 :             :    present, and FALSE otherwise.  *SAVED_PEDANTIC is set to the
   30901                 :             :    current value of the PEDANTIC flag, regardless of whether or not
   30902                 :             :    the `__extension__' keyword is present.  The caller is responsible
   30903                 :             :    for restoring the value of the PEDANTIC flag.  */
   30904                 :             : 
   30905                 :             : static bool
   30906                 :   456270711 : cp_parser_extension_opt (cp_parser* parser, int* saved_pedantic)
   30907                 :             : {
   30908                 :             :   /* Save the old value of the PEDANTIC flag.  */
   30909                 :   456270711 :   *saved_pedantic = pedantic;
   30910                 :             : 
   30911                 :   456270711 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXTENSION))
   30912                 :             :     {
   30913                 :             :       /* Consume the `__extension__' token.  */
   30914                 :     1015022 :       cp_lexer_consume_token (parser->lexer);
   30915                 :             :       /* We're not being pedantic while the `__extension__' keyword is
   30916                 :             :          in effect.  */
   30917                 :     1015022 :       pedantic = 0;
   30918                 :             : 
   30919                 :     1015022 :       return true;
   30920                 :             :     }
   30921                 :             : 
   30922                 :             :   return false;
   30923                 :             : }
   30924                 :             : 
   30925                 :             : /* Parse a label declaration.
   30926                 :             : 
   30927                 :             :    label-declaration:
   30928                 :             :      __label__ label-declarator-seq ;
   30929                 :             : 
   30930                 :             :    label-declarator-seq:
   30931                 :             :      identifier , label-declarator-seq
   30932                 :             :      identifier  */
   30933                 :             : 
   30934                 :             : static void
   30935                 :         124 : cp_parser_label_declaration (cp_parser* parser)
   30936                 :             : {
   30937                 :             :   /* Look for the `__label__' keyword.  */
   30938                 :         124 :   cp_parser_require_keyword (parser, RID_LABEL, RT_LABEL);
   30939                 :             : 
   30940                 :         292 :   while (true)
   30941                 :             :     {
   30942                 :         208 :       tree identifier;
   30943                 :             : 
   30944                 :             :       /* Look for an identifier.  */
   30945                 :         208 :       identifier = cp_parser_identifier (parser);
   30946                 :             :       /* If we failed, stop.  */
   30947                 :         208 :       if (identifier == error_mark_node)
   30948                 :             :         break;
   30949                 :             :       /* Declare it as a label.  */
   30950                 :         208 :       finish_label_decl (identifier);
   30951                 :             :       /* If the next token is a `;', stop.  */
   30952                 :         208 :       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   30953                 :             :         break;
   30954                 :             :       /* Look for the `,' separating the label declarations.  */
   30955                 :          84 :       cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   30956                 :          84 :     }
   30957                 :             : 
   30958                 :             :   /* Look for the final `;'.  */
   30959                 :         124 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   30960                 :         124 : }
   30961                 :             : 
   30962                 :             : // -------------------------------------------------------------------------- //
   30963                 :             : // Concept definitions
   30964                 :             : 
   30965                 :             : static tree
   30966                 :      542344 : cp_parser_concept_definition (cp_parser *parser)
   30967                 :             : {
   30968                 :             :   /* A concept definition is an unevaluated context.  */
   30969                 :      542344 :   cp_unevaluated u;
   30970                 :             : 
   30971                 :      542344 :   gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT));
   30972                 :      542344 :   cp_lexer_consume_token (parser->lexer);
   30973                 :             : 
   30974                 :      542344 :   cp_expr id = cp_parser_identifier (parser);
   30975                 :      542344 :   if (id == error_mark_node)
   30976                 :             :     {
   30977                 :           0 :       cp_parser_skip_to_end_of_statement (parser);
   30978                 :           0 :       cp_parser_consume_semicolon_at_end_of_statement (parser);
   30979                 :           0 :       return NULL_TREE;
   30980                 :             :     }
   30981                 :             : 
   30982                 :      542344 :   tree attrs = cp_parser_attributes_opt (parser);
   30983                 :             : 
   30984                 :      542344 :   if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   30985                 :             :     {
   30986                 :           0 :       cp_parser_skip_to_end_of_statement (parser);
   30987                 :           0 :       cp_parser_consume_semicolon_at_end_of_statement (parser);
   30988                 :           0 :       return error_mark_node;
   30989                 :             :     }
   30990                 :             : 
   30991                 :      542344 :   processing_constraint_expression_sentinel parsing_constraint;
   30992                 :      542344 :   tree init = cp_parser_constraint_expression (parser);
   30993                 :      542344 :   if (init == error_mark_node)
   30994                 :           4 :     cp_parser_skip_to_end_of_statement (parser);
   30995                 :             : 
   30996                 :             :   /* Consume the trailing ';'. Diagnose the problem if it isn't there,
   30997                 :             :      but continue as if it were.  */
   30998                 :      542344 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   30999                 :             : 
   31000                 :      542344 :   return finish_concept_definition (id, init, attrs);
   31001                 :      542344 : }
   31002                 :             : 
   31003                 :             : // -------------------------------------------------------------------------- //
   31004                 :             : // Requires Clause
   31005                 :             : 
   31006                 :             : /* Diagnose an expression that should appear in ()'s within a requires-clause
   31007                 :             :    and suggest where to place those parentheses.  */
   31008                 :             : 
   31009                 :             : static void
   31010                 :           1 : cp_parser_diagnose_ungrouped_constraint_plain (location_t loc)
   31011                 :             : {
   31012                 :           0 :   error_at (loc, "expression must be enclosed in parentheses");
   31013                 :           0 : }
   31014                 :             : 
   31015                 :             : static void
   31016                 :          17 : cp_parser_diagnose_ungrouped_constraint_rich (location_t loc)
   31017                 :             : {
   31018                 :          17 :   gcc_rich_location richloc (loc);
   31019                 :          17 :   richloc.add_fixit_insert_before ("(");
   31020                 :          17 :   richloc.add_fixit_insert_after (")");
   31021                 :          17 :   error_at (&richloc, "expression must be enclosed in parentheses");
   31022                 :          17 : }
   31023                 :             : 
   31024                 :             : /* Characterizes the likely kind of expression intended by a mis-written
   31025                 :             :    primary constraint.  */
   31026                 :             : enum primary_constraint_error
   31027                 :             : {
   31028                 :             :   pce_ok,
   31029                 :             :   pce_maybe_operator,
   31030                 :             :   pce_maybe_postfix
   31031                 :             : };
   31032                 :             : 
   31033                 :             : /* Returns true if the token(s) following a primary-expression in a
   31034                 :             :    constraint-logical-* expression would require parentheses.  */
   31035                 :             : 
   31036                 :             : static primary_constraint_error
   31037                 :     3021977 : cp_parser_constraint_requires_parens (cp_parser *parser, bool lambda_p)
   31038                 :             : {
   31039                 :     3021977 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   31040                 :     3021977 :   switch (token->type)
   31041                 :             :     {
   31042                 :             :       default:
   31043                 :             :         return pce_ok;
   31044                 :             : 
   31045                 :       60475 :       case CPP_EQ:
   31046                 :       60475 :         {
   31047                 :             :           /* An equal sign may be part of the definition of a function,
   31048                 :             :              and not an assignment operator, when parsing the expression
   31049                 :             :              for a trailing requires-clause. For example:
   31050                 :             : 
   31051                 :             :                 template<typename T>
   31052                 :             :                 struct S {
   31053                 :             :                   S() requires C<T> = default;
   31054                 :             :                 };
   31055                 :             : 
   31056                 :             :              Don't try to reparse this a binary operator.  */
   31057                 :       60475 :           if (cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_DELETE)
   31058                 :       60475 :               || cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_DEFAULT))
   31059                 :             :             return pce_ok;
   31060                 :             : 
   31061                 :             :           gcc_fallthrough ();
   31062                 :             :         }
   31063                 :             : 
   31064                 :             :       /* Arithmetic operators.  */
   31065                 :             :       case CPP_PLUS:
   31066                 :             :       case CPP_MINUS:
   31067                 :             :       case CPP_MULT:
   31068                 :             :       case CPP_DIV:
   31069                 :             :       case CPP_MOD:
   31070                 :             :       /* Bitwise operators.  */
   31071                 :             :       case CPP_AND:
   31072                 :             :       case CPP_OR:
   31073                 :             :       case CPP_XOR:
   31074                 :             :       case CPP_RSHIFT:
   31075                 :             :       case CPP_LSHIFT:
   31076                 :             :       /* Relational operators.  */
   31077                 :             :       case CPP_EQ_EQ:
   31078                 :             :       case CPP_NOT_EQ:
   31079                 :             :       case CPP_LESS:
   31080                 :             :       case CPP_GREATER:
   31081                 :             :       case CPP_LESS_EQ:
   31082                 :             :       case CPP_GREATER_EQ:
   31083                 :             :       case CPP_SPACESHIP:
   31084                 :             :       /* Pointer-to-member.  */
   31085                 :             :       case CPP_DOT_STAR:
   31086                 :             :       case CPP_DEREF_STAR:
   31087                 :             :       /* Assignment operators.  */
   31088                 :             :       case CPP_PLUS_EQ:
   31089                 :             :       case CPP_MINUS_EQ:
   31090                 :             :       case CPP_MULT_EQ:
   31091                 :             :       case CPP_DIV_EQ:
   31092                 :             :       case CPP_MOD_EQ:
   31093                 :             :       case CPP_AND_EQ:
   31094                 :             :       case CPP_OR_EQ:
   31095                 :             :       case CPP_XOR_EQ:
   31096                 :             :       case CPP_RSHIFT_EQ:
   31097                 :             :       case CPP_LSHIFT_EQ:
   31098                 :             :       /* Conditional operator */
   31099                 :             :       case CPP_QUERY:
   31100                 :             :         /* Unenclosed binary or conditional operator.  */
   31101                 :             :         return pce_maybe_operator;
   31102                 :             : 
   31103                 :           5 :       case CPP_OPEN_PAREN:
   31104                 :           5 :         {
   31105                 :             :           /* A primary constraint that precedes the parameter-list of a
   31106                 :             :              lambda expression is followed by an open paren.
   31107                 :             : 
   31108                 :             :                 []<typename T> requires C (T a, T b) { ... }
   31109                 :             : 
   31110                 :             :              Don't try to re-parse this as a postfix expression.  */
   31111                 :           5 :           if (lambda_p)
   31112                 :             :             return pce_ok;
   31113                 :             : 
   31114                 :        9985 :           gcc_fallthrough ();
   31115                 :             :         }
   31116                 :        9985 :       case CPP_OPEN_SQUARE:
   31117                 :        9985 :         {
   31118                 :             :           /* A primary-constraint-expression followed by a '[[' is not a
   31119                 :             :              postfix expression.  */
   31120                 :        9985 :           if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE))
   31121                 :             :             return pce_ok;
   31122                 :             : 
   31123                 :             :           gcc_fallthrough ();
   31124                 :             :         }
   31125                 :             :       case CPP_PLUS_PLUS:
   31126                 :             :       case CPP_MINUS_MINUS:
   31127                 :             :       case CPP_DOT:
   31128                 :             :         /* Unenclosed postfix operator.  */
   31129                 :             :         return pce_maybe_postfix;
   31130                 :             : 
   31131                 :           6 :       case CPP_DEREF:
   31132                 :             :         /* A primary constraint that precedes the lambda-declarator of a
   31133                 :             :            lambda expression is followed by trailing return type.
   31134                 :             : 
   31135                 :             :               []<typename T> requires C -> void {}
   31136                 :             : 
   31137                 :             :            Don't try to re-parse this as a postfix expression in
   31138                 :             :            C++23 and later.  In C++20 ( needs to come in between but we
   31139                 :             :            allow it to be omitted with pedwarn.  */
   31140                 :           6 :         if (lambda_p)
   31141                 :             :           return pce_ok;
   31142                 :             :         /* Unenclosed postfix operator.  */
   31143                 :             :         return pce_maybe_postfix;
   31144                 :             :    }
   31145                 :             : }
   31146                 :             : 
   31147                 :             : /* Returns true if the next token begins a unary expression, preceded by
   31148                 :             :    an operator or keyword.  */
   31149                 :             : 
   31150                 :             : static bool
   31151                 :     3021986 : cp_parser_unary_constraint_requires_parens (cp_parser *parser)
   31152                 :             : {
   31153                 :     3021986 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   31154                 :     3021986 :   switch (token->type)
   31155                 :             :     {
   31156                 :             :       case CPP_NOT:
   31157                 :             :       case CPP_PLUS:
   31158                 :             :       case CPP_MINUS:
   31159                 :             :       case CPP_MULT:
   31160                 :             :       case CPP_COMPL:
   31161                 :             :       case CPP_PLUS_PLUS:
   31162                 :             :       case CPP_MINUS_MINUS:
   31163                 :             :         return true;
   31164                 :             : 
   31165                 :      161738 :       case CPP_KEYWORD:
   31166                 :      161738 :         {
   31167                 :      161738 :           switch (token->keyword)
   31168                 :             :             {
   31169                 :             :               case RID_STATCAST:
   31170                 :             :               case RID_DYNCAST:
   31171                 :             :               case RID_REINTCAST:
   31172                 :             :               case RID_CONSTCAST:
   31173                 :             :               case RID_TYPEID:
   31174                 :             :               case RID_SIZEOF:
   31175                 :             :               case RID_ALIGNOF:
   31176                 :             :               case RID_NOEXCEPT:
   31177                 :             :               case RID_NEW:
   31178                 :             :               case RID_DELETE:
   31179                 :             :               case RID_THROW:
   31180                 :             :                 return true;
   31181                 :             : 
   31182                 :             :              default:
   31183                 :             :                 break;
   31184                 :             :           }
   31185                 :             :         }
   31186                 :             : 
   31187                 :             :       default:
   31188                 :             :         break;
   31189                 :             :     }
   31190                 :             : 
   31191                 :             :   return false;
   31192                 :             : }
   31193                 :             : 
   31194                 :             : /* Parse a primary expression within a constraint.  */
   31195                 :             : 
   31196                 :             : static cp_expr
   31197                 :     3021986 : cp_parser_constraint_primary_expression (cp_parser *parser, bool lambda_p)
   31198                 :             : {
   31199                 :             :   /* If this looks like a unary expression, parse it as such, but diagnose
   31200                 :             :      it as ill-formed; it requires parens.  */
   31201                 :     3021986 :   if (cp_parser_unary_constraint_requires_parens (parser))
   31202                 :             :     {
   31203                 :           4 :       cp_expr e = cp_parser_assignment_expression (parser, NULL, false, false);
   31204                 :           4 :       cp_parser_diagnose_ungrouped_constraint_rich (e.get_location());
   31205                 :           4 :       return e;
   31206                 :             :     }
   31207                 :             : 
   31208                 :     3021982 :   cp_lexer_save_tokens (parser->lexer);
   31209                 :     3021982 :   cp_id_kind idk;
   31210                 :     3021982 :   location_t loc = input_location;
   31211                 :     3021982 :   cp_expr expr = cp_parser_primary_expression (parser,
   31212                 :             :                                                /*address_p=*/false,
   31213                 :             :                                                /*cast_p=*/false,
   31214                 :             :                                                /*template_arg_p=*/false,
   31215                 :             :                                                &idk);
   31216                 :     3021982 :   expr.maybe_add_location_wrapper ();
   31217                 :             : 
   31218                 :     3021982 :   primary_constraint_error pce = pce_ok;
   31219                 :     3021982 :   if (expr != error_mark_node)
   31220                 :             :     {
   31221                 :             :       /* The primary-expression could be part of an unenclosed non-logical
   31222                 :             :          compound expression.  */
   31223                 :     3021977 :       pce = cp_parser_constraint_requires_parens (parser, lambda_p);
   31224                 :             :     }
   31225                 :     3021977 :   if (pce == pce_ok)
   31226                 :             :     {
   31227                 :     3021968 :       cp_lexer_commit_tokens (parser->lexer);
   31228                 :     3021968 :       return finish_constraint_primary_expr (expr);
   31229                 :             :     }
   31230                 :             : 
   31231                 :             :   /* Retry the parse at a lower precedence. If that succeeds, diagnose the
   31232                 :             :      error, but return the expression as if it were valid.  */
   31233                 :          14 :   cp_lexer_rollback_tokens (parser->lexer);
   31234                 :          14 :   cp_parser_parse_tentatively (parser);
   31235                 :          14 :   if (pce == pce_maybe_operator)
   31236                 :           8 :     expr = cp_parser_assignment_expression (parser, NULL, false, false);
   31237                 :             :   else
   31238                 :           6 :     expr = cp_parser_simple_cast_expression (parser);
   31239                 :          14 :   if (cp_parser_parse_definitely (parser))
   31240                 :             :     {
   31241                 :          13 :       cp_parser_diagnose_ungrouped_constraint_rich (expr.get_location());
   31242                 :          13 :       return expr;
   31243                 :             :     }
   31244                 :             : 
   31245                 :             :   /* Otherwise, something has gone very wrong, and we can't generate a more
   31246                 :             :      meaningful diagnostic or recover.  */
   31247                 :           1 :   cp_parser_diagnose_ungrouped_constraint_plain (loc);
   31248                 :           1 :   return error_mark_node;
   31249                 :             : }
   31250                 :             : 
   31251                 :             : /* Parse a constraint-logical-and-expression.
   31252                 :             : 
   31253                 :             :      constraint-logical-and-expression:
   31254                 :             :        primary-expression
   31255                 :             :        constraint-logical-and-expression '&&' primary-expression  */
   31256                 :             : 
   31257                 :             : static cp_expr
   31258                 :     2274951 : cp_parser_constraint_logical_and_expression (cp_parser *parser, bool lambda_p)
   31259                 :             : {
   31260                 :     2274951 :   cp_expr lhs = cp_parser_constraint_primary_expression (parser, lambda_p);
   31261                 :     5296937 :   while (cp_lexer_next_token_is (parser->lexer, CPP_AND_AND))
   31262                 :             :     {
   31263                 :      747035 :       cp_token *op = cp_lexer_consume_token (parser->lexer);
   31264                 :      747035 :       tree rhs = cp_parser_constraint_primary_expression (parser, lambda_p);
   31265                 :      747035 :       lhs = finish_constraint_and_expr (op->location, lhs, rhs);
   31266                 :             :     }
   31267                 :     2274951 :   return lhs;
   31268                 :             : }
   31269                 :             : 
   31270                 :             : /* Parse a constraint-logical-or-expression.
   31271                 :             : 
   31272                 :             :      constraint-logical-or-expression:
   31273                 :             :        constraint-logical-and-expression
   31274                 :             :        constraint-logical-or-expression '||' constraint-logical-and-expression  */
   31275                 :             : 
   31276                 :             : static cp_expr
   31277                 :     2125551 : cp_parser_constraint_logical_or_expression (cp_parser *parser, bool lambda_p)
   31278                 :             : {
   31279                 :     2125551 :   cp_expr lhs = cp_parser_constraint_logical_and_expression (parser, lambda_p);
   31280                 :     4400502 :   while (cp_lexer_next_token_is (parser->lexer, CPP_OR_OR))
   31281                 :             :     {
   31282                 :      149400 :       cp_token *op = cp_lexer_consume_token (parser->lexer);
   31283                 :      149400 :       cp_expr rhs = cp_parser_constraint_logical_and_expression (parser, lambda_p);
   31284                 :      149400 :       lhs = finish_constraint_or_expr (op->location, lhs, rhs);
   31285                 :             :     }
   31286                 :     2125551 :   return lhs;
   31287                 :             : }
   31288                 :             : 
   31289                 :             : /* Parse the expression after a requires-clause. This has a different grammar
   31290                 :             :     than that in the concepts TS.  */
   31291                 :             : 
   31292                 :             : static tree
   31293                 :     2125551 : cp_parser_requires_clause_expression (cp_parser *parser, bool lambda_p)
   31294                 :             : {
   31295                 :     2125551 :   processing_constraint_expression_sentinel parsing_constraint;
   31296                 :     2125551 :   ++processing_template_decl;
   31297                 :     2125551 :   cp_expr expr = cp_parser_constraint_logical_or_expression (parser, lambda_p);
   31298                 :     2125551 :   --processing_template_decl;
   31299                 :     2125551 :   if (check_for_bare_parameter_packs (expr))
   31300                 :           1 :     expr = error_mark_node;
   31301                 :     4251102 :   return expr;
   31302                 :     2125551 : }
   31303                 :             : 
   31304                 :             : /* Parse a expression after a requires clause.
   31305                 :             : 
   31306                 :             :     constraint-expression:
   31307                 :             :       logical-or-expression
   31308                 :             : 
   31309                 :             :    The required logical-or-expression must be a constant expression. Note
   31310                 :             :    that we don't check that the expression is constepxr here. We defer until
   31311                 :             :    we analyze constraints and then, we only check atomic constraints.  */
   31312                 :             : 
   31313                 :             : static tree
   31314                 :      574394 : cp_parser_constraint_expression (cp_parser *parser)
   31315                 :             : {
   31316                 :      574394 :   processing_constraint_expression_sentinel parsing_constraint;
   31317                 :      574394 :   ++processing_template_decl;
   31318                 :      574394 :   cp_expr expr = cp_parser_binary_expression (parser, false, true,
   31319                 :             :                                               PREC_NOT_OPERATOR, NULL);
   31320                 :      574394 :   --processing_template_decl;
   31321                 :      574394 :   if (check_for_bare_parameter_packs (expr))
   31322                 :           1 :     expr = error_mark_node;
   31323                 :      574394 :   expr.maybe_add_location_wrapper ();
   31324                 :      574394 :   return expr;
   31325                 :      574394 : }
   31326                 :             : 
   31327                 :             : /* Optionally parse a requires clause:
   31328                 :             : 
   31329                 :             :       requires-clause:
   31330                 :             :         `requires` constraint-logical-or-expression.
   31331                 :             :    [ConceptsTS]
   31332                 :             :         `requires constraint-expression.
   31333                 :             : 
   31334                 :             :    LAMBDA_P is true when the requires-clause is parsed before the
   31335                 :             :    parameter-list of a lambda-declarator.  */
   31336                 :             : 
   31337                 :             : static tree
   31338                 :    22917283 : cp_parser_requires_clause_opt (cp_parser *parser, bool lambda_p)
   31339                 :             : {
   31340                 :             :   /* A requires clause is an unevaluated context.  */
   31341                 :    22917283 :   cp_unevaluated u;
   31342                 :             : 
   31343                 :    22917283 :   cp_token *tok = cp_lexer_peek_token (parser->lexer);
   31344                 :    22917283 :   if (tok->keyword != RID_REQUIRES)
   31345                 :             :     {
   31346                 :    20789665 :       if (!flag_concepts && tok->type == CPP_NAME
   31347                 :          24 :           && tok->u.value == ridpointers[RID_REQUIRES])
   31348                 :             :         {
   31349                 :           8 :           error_at (cp_lexer_peek_token (parser->lexer)->location,
   31350                 :             :                     "%<requires%> only available with "
   31351                 :             :                     "%<-std=c++20%> or %<-fconcepts%>");
   31352                 :             :           /* Parse and discard the requires-clause.  */
   31353                 :           8 :           cp_lexer_consume_token (parser->lexer);
   31354                 :           8 :           cp_parser_constraint_expression (parser);
   31355                 :             :         }
   31356                 :    20789665 :       return NULL_TREE;
   31357                 :             :     }
   31358                 :             : 
   31359                 :     2127618 :   cp_token *tok2 = cp_lexer_peek_nth_token (parser->lexer, 2);
   31360                 :     2127618 :   if (tok2->type == CPP_OPEN_BRACE)
   31361                 :             :     {
   31362                 :             :       /* An opening brace following the start of a requires-clause is
   31363                 :             :          ill-formed; the user likely forgot the second `requires' that
   31364                 :             :          would start a requires-expression.  */
   31365                 :           1 :       gcc_rich_location richloc (tok2->location);
   31366                 :           1 :       richloc.add_fixit_insert_after (tok->location, " requires");
   31367                 :           1 :       error_at (&richloc, "missing additional %<requires%> to start "
   31368                 :             :                 "a requires-expression");
   31369                 :             :       /* Don't consume the `requires', so that it's reused as the start of a
   31370                 :             :          requires-expression.  */
   31371                 :           1 :     }
   31372                 :             :   else
   31373                 :     2127617 :     cp_lexer_consume_token (parser->lexer);
   31374                 :             : 
   31375                 :     2127618 :   if (!flag_concepts_ts)
   31376                 :     2125551 :     return cp_parser_requires_clause_expression (parser, lambda_p);
   31377                 :             :   else
   31378                 :        2067 :     return cp_parser_constraint_expression (parser);
   31379                 :    22917283 : }
   31380                 :             : 
   31381                 :             : /*---------------------------------------------------------------------------
   31382                 :             :                            Requires expressions
   31383                 :             : ---------------------------------------------------------------------------*/
   31384                 :             : 
   31385                 :             : /* Parse a requires expression
   31386                 :             : 
   31387                 :             :    requirement-expression:
   31388                 :             :        'requires' requirement-parameter-list [opt] requirement-body */
   31389                 :             : 
   31390                 :             : static tree
   31391                 :      507825 : cp_parser_requires_expression (cp_parser *parser)
   31392                 :             : {
   31393                 :      507825 :   gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES));
   31394                 :      507825 :   location_t loc = cp_lexer_consume_token (parser->lexer)->location;
   31395                 :             : 
   31396                 :             :   /* Avoid committing to outer tentative parse.  */
   31397                 :      507825 :   tentative_firewall firewall (parser);
   31398                 :             : 
   31399                 :             :   /* This is definitely a requires-expression.  */
   31400                 :      507825 :   cp_parser_commit_to_tentative_parse (parser);
   31401                 :             : 
   31402                 :      507825 :   tree parms, reqs;
   31403                 :      507825 :   {
   31404                 :             :     /* Local parameters are delared as variables within the scope
   31405                 :             :        of the expression.  They are not visible past the end of
   31406                 :             :        the expression.  Expressions within the requires-expression
   31407                 :             :        are unevaluated.  */
   31408                 :      507825 :     struct scope_sentinel
   31409                 :             :     {
   31410                 :      507825 :       scope_sentinel ()
   31411                 :             :       {
   31412                 :      507825 :         ++cp_unevaluated_operand;
   31413                 :      507825 :         begin_scope (sk_function_parms, NULL_TREE);
   31414                 :      507825 :         current_binding_level->requires_expression = true;
   31415                 :      507825 :       }
   31416                 :             : 
   31417                 :      507825 :       ~scope_sentinel ()
   31418                 :             :       {
   31419                 :      507825 :         pop_bindings_and_leave_scope ();
   31420                 :           4 :         --cp_unevaluated_operand;
   31421                 :             :       }
   31422                 :      507825 :     } s;
   31423                 :             : 
   31424                 :             :     /* Parse the optional parameter list. */
   31425                 :      507825 :     if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   31426                 :             :       {
   31427                 :      238601 :         parms = cp_parser_requirement_parameter_list (parser);
   31428                 :      238601 :         if (parms == error_mark_node)
   31429                 :             :           return error_mark_node;
   31430                 :             :       }
   31431                 :             :     else
   31432                 :      269224 :       parms = NULL_TREE;
   31433                 :             : 
   31434                 :             :     /* Parse the requirement body. */
   31435                 :      507825 :     ++processing_template_decl;
   31436                 :      507825 :     reqs = cp_parser_requirement_body (parser);
   31437                 :      507825 :     --processing_template_decl;
   31438                 :      507825 :     if (reqs == error_mark_node)
   31439                 :             :       return error_mark_node;
   31440                 :             :   }
   31441                 :             : 
   31442                 :             :   /* This needs to happen after pop_bindings_and_leave_scope, as it reverses
   31443                 :             :      the parm chain.  */
   31444                 :      507821 :   grokparms (parms, &parms);
   31445                 :      507821 :   loc = make_location (loc, loc, parser->lexer);
   31446                 :      507821 :   tree expr = finish_requires_expr (loc, parms, reqs);
   31447                 :      507821 :   if (!processing_template_decl)
   31448                 :             :     {
   31449                 :             :       /* Perform semantic processing now to diagnose any invalid types and
   31450                 :             :          expressions.  */
   31451                 :          67 :       int saved_errorcount = errorcount;
   31452                 :          67 :       tsubst_requires_expr (expr, NULL_TREE, tf_warning_or_error, NULL_TREE);
   31453                 :          67 :       if (errorcount > saved_errorcount)
   31454                 :           3 :         return error_mark_node;
   31455                 :             :     }
   31456                 :             :   return expr;
   31457                 :      507825 : }
   31458                 :             : 
   31459                 :             : /* Parse a parameterized requirement.
   31460                 :             : 
   31461                 :             :    requirement-parameter-list:
   31462                 :             :        '(' parameter-declaration-clause ')' */
   31463                 :             : 
   31464                 :             : static tree
   31465                 :      238601 : cp_parser_requirement_parameter_list (cp_parser *parser)
   31466                 :             : {
   31467                 :      238601 :   matching_parens parens;
   31468                 :      238601 :   if (!parens.require_open (parser))
   31469                 :           0 :     return error_mark_node;
   31470                 :             : 
   31471                 :      238601 :   tree parms = (cp_parser_parameter_declaration_clause
   31472                 :      238601 :                 (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL));
   31473                 :             : 
   31474                 :      238601 :   if (!parens.require_close (parser))
   31475                 :           0 :     return error_mark_node;
   31476                 :             : 
   31477                 :             :   /* Modify the declared parameters by removing their context
   31478                 :             :      so they don't refer to the enclosing scope and explicitly
   31479                 :             :      indicating that they are constraint variables. */
   31480                 :      593300 :   for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
   31481                 :             :     {
   31482                 :      593299 :       if (parm == void_list_node || parm == explicit_void_list_node)
   31483                 :             :         break;
   31484                 :      354699 :       tree decl = TREE_VALUE (parm);
   31485                 :      354699 :       if (decl != error_mark_node)
   31486                 :             :         {
   31487                 :      354697 :           DECL_CONTEXT (decl) = NULL_TREE;
   31488                 :      354697 :           CONSTRAINT_VAR_P (decl) = true;
   31489                 :             :         }
   31490                 :             :     }
   31491                 :             : 
   31492                 :             :   return parms;
   31493                 :             : }
   31494                 :             : 
   31495                 :             : /* Parse the body of a requirement.
   31496                 :             : 
   31497                 :             :    requirement-body:
   31498                 :             :        '{' requirement-list '}' */
   31499                 :             : static tree
   31500                 :      507825 : cp_parser_requirement_body (cp_parser *parser)
   31501                 :             : {
   31502                 :      507825 :   matching_braces braces;
   31503                 :      507825 :   if (!braces.require_open (parser))
   31504                 :           0 :     return error_mark_node;
   31505                 :             : 
   31506                 :      507825 :   tree reqs = cp_parser_requirement_seq (parser);
   31507                 :             : 
   31508                 :      507825 :   if (!braces.require_close (parser))
   31509                 :           1 :     return error_mark_node;
   31510                 :             : 
   31511                 :             :   return reqs;
   31512                 :             : }
   31513                 :             : 
   31514                 :             : /* Parse a sequence of requirements.
   31515                 :             : 
   31516                 :             :    requirement-seq:
   31517                 :             :        requirement
   31518                 :             :        requirement-seq requirement */
   31519                 :             : 
   31520                 :             : static tree
   31521                 :      507825 : cp_parser_requirement_seq (cp_parser *parser)
   31522                 :             : {
   31523                 :      507825 :   tree result = NULL_TREE;
   31524                 :      724078 :   do
   31525                 :             :     {
   31526                 :      724078 :       tree req = cp_parser_requirement (parser);
   31527                 :      724078 :       if (req != error_mark_node)
   31528                 :      724073 :         result = tree_cons (NULL_TREE, req, result);
   31529                 :             :     }
   31530                 :      724078 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE)
   31531                 :     1231903 :          && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF));
   31532                 :             : 
   31533                 :             :   /* If there are no valid requirements, this is not a valid expression. */
   31534                 :      507825 :   if (!result)
   31535                 :           3 :     return error_mark_node;
   31536                 :             : 
   31537                 :             :   /* Reverse the order of requirements so they are analyzed in order. */
   31538                 :      507822 :   return nreverse (result);
   31539                 :             : }
   31540                 :             : 
   31541                 :             : /* Parse a syntactic requirement or type requirement.
   31542                 :             : 
   31543                 :             :      requirement:
   31544                 :             :        simple-requirement
   31545                 :             :        compound-requirement
   31546                 :             :        type-requirement
   31547                 :             :        nested-requirement */
   31548                 :             : 
   31549                 :             : static tree
   31550                 :      724078 : cp_parser_requirement (cp_parser *parser)
   31551                 :             : {
   31552                 :      724078 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   31553                 :      271537 :     return cp_parser_compound_requirement (parser);
   31554                 :      452541 :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
   31555                 :             :     {
   31556                 :             :       /* It's probably a type-requirement.  */
   31557                 :      134781 :       cp_parser_parse_tentatively (parser);
   31558                 :      134781 :       tree req = cp_parser_type_requirement (parser);
   31559                 :      134781 :       if (cp_parser_parse_definitely (parser))
   31560                 :             :         return req;
   31561                 :             :       /* No, maybe it's something like typename T::type(); */
   31562                 :           1 :       cp_parser_parse_tentatively (parser);
   31563                 :           1 :       req = cp_parser_simple_requirement (parser);
   31564                 :           1 :       if (cp_parser_parse_definitely (parser))
   31565                 :             :         return req;
   31566                 :             :       /* Non-tentative for the error.  */
   31567                 :           0 :       return cp_parser_type_requirement (parser);
   31568                 :             :     }
   31569                 :      317760 :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES))
   31570                 :       29975 :     return cp_parser_nested_requirement (parser);
   31571                 :             :   else
   31572                 :      287785 :     return cp_parser_simple_requirement (parser);
   31573                 :             : }
   31574                 :             : 
   31575                 :             : /* Parse a simple requirement.
   31576                 :             : 
   31577                 :             :      simple-requirement:
   31578                 :             :        expression ';' */
   31579                 :             : 
   31580                 :             : static tree
   31581                 :      287786 : cp_parser_simple_requirement (cp_parser *parser)
   31582                 :             : {
   31583                 :      287786 :   location_t start = cp_lexer_peek_token (parser->lexer)->location;
   31584                 :      287786 :   cp_expr expr = cp_parser_expression (parser, NULL, false, false);
   31585                 :      287786 :   if (expr == error_mark_node)
   31586                 :           1 :     cp_parser_skip_to_end_of_statement (parser);
   31587                 :             : 
   31588                 :      287786 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   31589                 :             : 
   31590                 :      287786 :   if (!expr || expr == error_mark_node)
   31591                 :           1 :     return error_mark_node;
   31592                 :             : 
   31593                 :             :   /* Sometimes we don't get locations, so use the cached token location
   31594                 :             :      as a reasonable approximation.  */
   31595                 :      287785 :   if (expr.get_location() == UNKNOWN_LOCATION)
   31596                 :           0 :     expr.set_location (start);
   31597                 :             : 
   31598                 :      287785 :   for (tree t = expr; ; )
   31599                 :             :     {
   31600                 :      287945 :       if (TREE_CODE (t) == TRUTH_ANDIF_EXPR
   31601                 :      287865 :           || TREE_CODE (t) == TRUTH_ORIF_EXPR)
   31602                 :             :         {
   31603                 :          80 :           t = TREE_OPERAND (t, 0);
   31604                 :          80 :           continue;
   31605                 :             :         }
   31606                 :      287785 :       if (concept_check_p (t))
   31607                 :             :         {
   31608                 :           2 :           gcc_rich_location richloc (get_start (start));
   31609                 :           2 :           richloc.add_fixit_insert_before (start, "requires ");
   31610                 :           2 :           warning_at (&richloc, OPT_Wmissing_requires, "testing "
   31611                 :             :                       "if a concept-id is a valid expression; add "
   31612                 :             :                       "%<requires%> to check satisfaction");
   31613                 :           2 :         }
   31614                 :      287785 :       break;
   31615                 :          80 :     }
   31616                 :             : 
   31617                 :      287785 :   return finish_simple_requirement (expr.get_location (), expr);
   31618                 :             : }
   31619                 :             : 
   31620                 :             : /* Parse a type requirement
   31621                 :             : 
   31622                 :             :      type-requirement
   31623                 :             :          nested-name-specifier [opt] required-type-name ';'
   31624                 :             : 
   31625                 :             :      required-type-name:
   31626                 :             :          type-name
   31627                 :             :          'template' [opt] simple-template-id  */
   31628                 :             : 
   31629                 :             : static tree
   31630                 :      134781 : cp_parser_type_requirement (cp_parser *parser)
   31631                 :             : {
   31632                 :      134781 :   cp_token *start_tok = cp_lexer_consume_token (parser->lexer);
   31633                 :      134781 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   31634                 :             : 
   31635                 :             :   // Save the scope before parsing name specifiers.
   31636                 :      134781 :   tree saved_scope = parser->scope;
   31637                 :      134781 :   tree saved_object_scope = parser->object_scope;
   31638                 :      134781 :   tree saved_qualifying_scope = parser->qualifying_scope;
   31639                 :      134781 :   cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
   31640                 :      134781 :   cp_parser_nested_name_specifier_opt (parser,
   31641                 :             :                                        /*typename_keyword_p=*/true,
   31642                 :             :                                        /*check_dependency_p=*/true,
   31643                 :             :                                        /*type_p=*/true,
   31644                 :             :                                        /*is_declaration=*/false);
   31645                 :             : 
   31646                 :      134781 :   tree type;
   31647                 :      134781 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
   31648                 :             :     {
   31649                 :           5 :       cp_lexer_consume_token (parser->lexer);
   31650                 :           5 :       type = cp_parser_template_id (parser,
   31651                 :             :                                     /*template_keyword_p=*/true,
   31652                 :             :                                     /*check_dependency_p=*/true,
   31653                 :             :                                     /*tag_type=*/none_type,
   31654                 :             :                                     /*is_declaration=*/false);
   31655                 :           5 :       type = make_typename_type (parser->scope, type, typename_type,
   31656                 :             :                                  /*complain=*/tf_error);
   31657                 :             :     }
   31658                 :             :   else
   31659                 :      134776 :    type = cp_parser_type_name (parser, /*typename_keyword_p=*/true);
   31660                 :             : 
   31661                 :      134781 :   if (TREE_CODE (type) == TYPE_DECL)
   31662                 :      134776 :     type = TREE_TYPE (type);
   31663                 :             : 
   31664                 :      134781 :   parser->scope = saved_scope;
   31665                 :      134781 :   parser->object_scope = saved_object_scope;
   31666                 :      134781 :   parser->qualifying_scope = saved_qualifying_scope;
   31667                 :             : 
   31668                 :      134781 :   if (type == error_mark_node)
   31669                 :           0 :     cp_parser_skip_to_end_of_statement (parser);
   31670                 :             : 
   31671                 :      134781 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   31672                 :             : 
   31673                 :      134781 :   if (type == error_mark_node)
   31674                 :             :     return error_mark_node;
   31675                 :             : 
   31676                 :      134781 :   loc = make_location (loc, start_tok->location, parser->lexer);
   31677                 :      134781 :   return finish_type_requirement (loc, type);
   31678                 :             : }
   31679                 :             : 
   31680                 :             : /* Parse a compound requirement
   31681                 :             : 
   31682                 :             :      compound-requirement:
   31683                 :             :          '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] ';' */
   31684                 :             : 
   31685                 :             : static tree
   31686                 :      271537 : cp_parser_compound_requirement (cp_parser *parser)
   31687                 :             : {
   31688                 :             :   /* Parse an expression enclosed in '{ }'s. */
   31689                 :      271537 :   matching_braces braces;
   31690                 :      271537 :   if (!braces.require_open (parser))
   31691                 :           0 :     return error_mark_node;
   31692                 :             : 
   31693                 :      271537 :   cp_token *expr_token = cp_lexer_peek_token (parser->lexer);
   31694                 :             : 
   31695                 :      271537 :   tree expr = cp_parser_expression (parser, NULL, false, false);
   31696                 :      271537 :   if (expr == error_mark_node)
   31697                 :           1 :     cp_parser_skip_to_closing_brace (parser);
   31698                 :             : 
   31699                 :      271537 :   if (!braces.require_close (parser))
   31700                 :             :     {
   31701                 :           0 :       cp_parser_skip_to_end_of_statement (parser);
   31702                 :           0 :       cp_parser_consume_semicolon_at_end_of_statement (parser);
   31703                 :           0 :       return error_mark_node;
   31704                 :             :     }
   31705                 :             : 
   31706                 :             :   /* If the expression was invalid, skip the remainder of the requirement.  */
   31707                 :      271537 :   if (!expr || expr == error_mark_node)
   31708                 :             :     {
   31709                 :           1 :       cp_parser_skip_to_end_of_statement (parser);
   31710                 :           1 :       cp_parser_consume_semicolon_at_end_of_statement (parser);
   31711                 :           1 :       return error_mark_node;
   31712                 :             :     }
   31713                 :             : 
   31714                 :             :   /* Parse the optional noexcept. */
   31715                 :      271536 :   bool noexcept_p = false;
   31716                 :      271536 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_NOEXCEPT))
   31717                 :             :     {
   31718                 :        2860 :       cp_lexer_consume_token (parser->lexer);
   31719                 :        2860 :       noexcept_p = true;
   31720                 :             :     }
   31721                 :             : 
   31722                 :             :   /* Parse the optional trailing return type. */
   31723                 :      271536 :   tree type = NULL_TREE;
   31724                 :      271536 :   if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
   31725                 :             :     {
   31726                 :      268670 :       cp_lexer_consume_token (parser->lexer);
   31727                 :      268670 :       cp_token *tok = cp_lexer_peek_token (parser->lexer);
   31728                 :             : 
   31729                 :      268670 :       bool saved_result_type_constraint_p = parser->in_result_type_constraint_p;
   31730                 :      268670 :       parser->in_result_type_constraint_p = true;
   31731                 :             :       /* C++20 allows either a type-id or a type-constraint. Parsing
   31732                 :             :          a type-id will subsume the parsing for a type-constraint but
   31733                 :             :          allow for more syntactic forms (e.g., const C<T>*).  */
   31734                 :      268670 :       type = cp_parser_trailing_type_id (parser);
   31735                 :      268670 :       parser->in_result_type_constraint_p = saved_result_type_constraint_p;
   31736                 :      268670 :       if (type == error_mark_node)
   31737                 :             :         return error_mark_node;
   31738                 :             : 
   31739                 :      268670 :       location_t type_loc = make_location (tok->location, tok->location,
   31740                 :             :                                            parser->lexer);
   31741                 :             : 
   31742                 :             :       /* Check that we haven't written something like 'const C<T>*'.  */
   31743                 :      268670 :       if (type_uses_auto (type))
   31744                 :             :         {
   31745                 :      268663 :           if (!is_auto (type))
   31746                 :             :             {
   31747                 :           2 :               error_at (type_loc,
   31748                 :             :                         "result type is not a plain type-constraint");
   31749                 :           2 :               cp_parser_consume_semicolon_at_end_of_statement (parser);
   31750                 :           2 :               return error_mark_node;
   31751                 :             :             }
   31752                 :             :         }
   31753                 :           7 :       else if (!flag_concepts_ts)
   31754                 :             :         /* P1452R2 removed the trailing-return-type option.  */
   31755                 :           0 :         error_at (type_loc,
   31756                 :             :                   "return-type-requirement is not a type-constraint");
   31757                 :             :     }
   31758                 :             : 
   31759                 :      271534 :   location_t loc = make_location (expr_token->location,
   31760                 :             :                                   braces.open_location (),
   31761                 :             :                                   parser->lexer);
   31762                 :             : 
   31763                 :      271534 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   31764                 :             : 
   31765                 :      271534 :   if (expr == error_mark_node || type == error_mark_node)
   31766                 :             :     return error_mark_node;
   31767                 :             : 
   31768                 :      271534 :   return finish_compound_requirement (loc, expr, type, noexcept_p);
   31769                 :             : }
   31770                 :             : 
   31771                 :             : /* Parse a nested requirement. This is the same as a requires clause.
   31772                 :             : 
   31773                 :             :    nested-requirement:
   31774                 :             :      requires-clause */
   31775                 :             : 
   31776                 :             : static tree
   31777                 :       29975 : cp_parser_nested_requirement (cp_parser *parser)
   31778                 :             : {
   31779                 :       29975 :   gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES));
   31780                 :       29975 :   cp_token *tok = cp_lexer_consume_token (parser->lexer);
   31781                 :       29975 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   31782                 :       29975 :   tree req = cp_parser_constraint_expression (parser);
   31783                 :       29975 :   if (req == error_mark_node)
   31784                 :           1 :     cp_parser_skip_to_end_of_statement (parser);
   31785                 :       29975 :   loc = make_location (loc, tok->location, parser->lexer);
   31786                 :       29975 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   31787                 :       29975 :   if (req == error_mark_node)
   31788                 :             :     return error_mark_node;
   31789                 :       29974 :   return finish_nested_requirement (loc, req);
   31790                 :             : }
   31791                 :             : 
   31792                 :             : /* Support Functions */
   31793                 :             : 
   31794                 :             : /* Return the appropriate prefer_type argument for lookup_name based on
   31795                 :             :    tag_type.  */
   31796                 :             : 
   31797                 :             : static inline LOOK_want
   31798                 :  3677765506 : prefer_type_arg (tag_types tag_type)
   31799                 :             : {
   31800                 :  3370905636 :   switch (tag_type)
   31801                 :             :     {
   31802                 :             :     case none_type:  return LOOK_want::NORMAL;  // No preference.
   31803                 :   129718660 :     case scope_type: return LOOK_want::TYPE_NAMESPACE;  // Type or namespace.
   31804                 :    50591995 :     default:         return LOOK_want::TYPE;    // Type only.
   31805                 :             :     }
   31806                 :             : }
   31807                 :             : 
   31808                 :             : /* Looks up NAME in the current scope, as given by PARSER->SCOPE.
   31809                 :             :    NAME should have one of the representations used for an
   31810                 :             :    id-expression.  If NAME is the ERROR_MARK_NODE, the ERROR_MARK_NODE
   31811                 :             :    is returned.  If PARSER->SCOPE is a dependent type, then a
   31812                 :             :    SCOPE_REF is returned.
   31813                 :             : 
   31814                 :             :    If NAME is a TEMPLATE_ID_EXPR, then it will be immediately
   31815                 :             :    returned; the name was already resolved when the TEMPLATE_ID_EXPR
   31816                 :             :    was formed.  Abstractly, such entities should not be passed to this
   31817                 :             :    function, because they do not need to be looked up, but it is
   31818                 :             :    simpler to check for this special case here, rather than at the
   31819                 :             :    call-sites.
   31820                 :             : 
   31821                 :             :    In cases not explicitly covered above, this function returns a
   31822                 :             :    DECL, OVERLOAD, or baselink representing the result of the lookup.
   31823                 :             :    If there was no entity with the indicated NAME, the ERROR_MARK_NODE
   31824                 :             :    is returned.
   31825                 :             : 
   31826                 :             :    If TAG_TYPE is not NONE_TYPE, it indicates an explicit type keyword
   31827                 :             :    (e.g., "struct") that was used.  In that case bindings that do not
   31828                 :             :    refer to types are ignored.
   31829                 :             : 
   31830                 :             :    If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
   31831                 :             :    ignored.  If IS_TEMPLATE IS 2, the 'template' keyword was specified.
   31832                 :             : 
   31833                 :             :    If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
   31834                 :             :    are ignored.
   31835                 :             : 
   31836                 :             :    If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
   31837                 :             :    types.
   31838                 :             : 
   31839                 :             :    If AMBIGUOUS_DECLS is non-NULL, *AMBIGUOUS_DECLS is set to a
   31840                 :             :    TREE_LIST of candidates if name-lookup results in an ambiguity, and
   31841                 :             :    NULL_TREE otherwise.  */
   31842                 :             : 
   31843                 :             : static cp_expr
   31844                 :  3925907627 : cp_parser_lookup_name (cp_parser *parser, tree name,
   31845                 :             :                        enum tag_types tag_type,
   31846                 :             :                        int is_template,
   31847                 :             :                        bool is_namespace,
   31848                 :             :                        bool check_dependency,
   31849                 :             :                        tree *ambiguous_decls,
   31850                 :             :                        location_t name_location)
   31851                 :             : {
   31852                 :  3925907627 :   tree decl;
   31853                 :  3925907627 :   tree object_type = parser->context->object_type;
   31854                 :             : 
   31855                 :             :   /* Assume that the lookup will be unambiguous.  */
   31856                 :  3925907627 :   if (ambiguous_decls)
   31857                 :  2012388807 :     *ambiguous_decls = NULL_TREE;
   31858                 :             : 
   31859                 :             :   /* Now that we have looked up the name, the OBJECT_TYPE (if any) is
   31860                 :             :      no longer valid.  Note that if we are parsing tentatively, and
   31861                 :             :      the parse fails, OBJECT_TYPE will be automatically restored.  */
   31862                 :  3925907627 :   parser->context->object_type = NULL_TREE;
   31863                 :             : 
   31864                 :  3925907627 :   if (name == error_mark_node)
   31865                 :    52048640 :     return error_mark_node;
   31866                 :             : 
   31867                 :             :   /* A template-id has already been resolved; there is no lookup to
   31868                 :             :      do.  */
   31869                 :  3873858987 :   if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
   31870                 :      557504 :     return name;
   31871                 :  3873301483 :   if (BASELINK_P (name))
   31872                 :             :     {
   31873                 :       70222 :       gcc_assert (TREE_CODE (BASELINK_FUNCTIONS (name))
   31874                 :             :                   == TEMPLATE_ID_EXPR);
   31875                 :       70222 :       return name;
   31876                 :             :     }
   31877                 :             : 
   31878                 :             :   /* A BIT_NOT_EXPR is used to represent a destructor.  By this point,
   31879                 :             :      it should already have been checked to make sure that the name
   31880                 :             :      used matches the type being destroyed.  */
   31881                 :  3873231261 :   if (TREE_CODE (name) == BIT_NOT_EXPR)
   31882                 :             :     {
   31883                 :       29643 :       tree type;
   31884                 :             : 
   31885                 :             :       /* Figure out to which type this destructor applies.  */
   31886                 :       29643 :       if (parser->scope)
   31887                 :             :         type = parser->scope;
   31888                 :          12 :       else if (object_type)
   31889                 :             :         type = object_type;
   31890                 :             :       else
   31891                 :          12 :         type = current_class_type;
   31892                 :             :       /* If that's not a class type, there is no destructor.  */
   31893                 :       29643 :       if (!type || !CLASS_TYPE_P (type))
   31894                 :          29 :         return error_mark_node;
   31895                 :             : 
   31896                 :             :       /* In a non-static member function, check implicit this->.  */
   31897                 :       29614 :       if (current_class_ref)
   31898                 :          20 :         return lookup_destructor (current_class_ref, parser->scope, name,
   31899                 :          20 :                                   tf_warning_or_error);
   31900                 :             : 
   31901                 :       29594 :       if (CLASSTYPE_LAZY_DESTRUCTOR (type))
   31902                 :           7 :         lazily_declare_fn (sfk_destructor, type);
   31903                 :             : 
   31904                 :       29594 :       if (tree dtor = CLASSTYPE_DESTRUCTOR (type))
   31905                 :       29584 :         return dtor;
   31906                 :             : 
   31907                 :          10 :       return error_mark_node;
   31908                 :             :     }
   31909                 :             : 
   31910                 :             :   /* By this point, the NAME should be an ordinary identifier.  If
   31911                 :             :      the id-expression was a qualified name, the qualifying scope is
   31912                 :             :      stored in PARSER->SCOPE at this point.  */
   31913                 :  3873201618 :   gcc_assert (identifier_p (name));
   31914                 :             : 
   31915                 :             :   /* Perform the lookup.  */
   31916                 :  3873201618 :   if (parser->scope)
   31917                 :             :     {
   31918                 :   415642244 :       bool dependent_p;
   31919                 :             : 
   31920                 :   415642244 :       if (parser->scope == error_mark_node)
   31921                 :         150 :         return error_mark_node;
   31922                 :             : 
   31923                 :             :       /* If the SCOPE is dependent, the lookup must be deferred until
   31924                 :             :          the template is instantiated -- unless we are explicitly
   31925                 :             :          looking up names in uninstantiated templates.  Even then, we
   31926                 :             :          cannot look up the name if the scope is not a class type; it
   31927                 :             :          might, for example, be a template type parameter.  */
   31928                 :   831284188 :       dependent_p = (TYPE_P (parser->scope)
   31929                 :   415642094 :                      && dependent_scope_p (parser->scope));
   31930                 :    12390497 :       if ((check_dependency || !CLASS_TYPE_P (parser->scope))
   31931                 :   426112295 :           && dependent_p)
   31932                 :             :         /* Defer lookup.  */
   31933                 :   108782224 :         decl = error_mark_node;
   31934                 :             :       else
   31935                 :             :         {
   31936                 :   306859870 :           tree pushed_scope = NULL_TREE;
   31937                 :             : 
   31938                 :             :           /* If PARSER->SCOPE is a dependent type, then it must be a
   31939                 :             :              class type, and we must not be checking dependencies;
   31940                 :             :              otherwise, we would have processed this lookup above.  So
   31941                 :             :              that PARSER->SCOPE is not considered a dependent base by
   31942                 :             :              lookup_member, we must enter the scope here.  */
   31943                 :   306859870 :           if (dependent_p)
   31944                 :     1570270 :             pushed_scope = push_scope (parser->scope);
   31945                 :             : 
   31946                 :             :           /* If the PARSER->SCOPE is a template specialization, it
   31947                 :             :              may be instantiated during name lookup.  In that case,
   31948                 :             :              errors may be issued.  Even if we rollback the current
   31949                 :             :              tentative parse, those errors are valid.  */
   31950                 :   325030842 :           decl = lookup_qualified_name (parser->scope, name,
   31951                 :             :                                         prefer_type_arg (tag_type),
   31952                 :             :                                         /*complain=*/true);
   31953                 :             : 
   31954                 :             :           /* 3.4.3.1: In a lookup in which the constructor is an acceptable
   31955                 :             :              lookup result and the nested-name-specifier nominates a class C:
   31956                 :             :                * if the name specified after the nested-name-specifier, when
   31957                 :             :                looked up in C, is the injected-class-name of C (Clause 9), or
   31958                 :             :                * if the name specified after the nested-name-specifier is the
   31959                 :             :                same as the identifier or the simple-template-id's template-
   31960                 :             :                name in the last component of the nested-name-specifier,
   31961                 :             :              the name is instead considered to name the constructor of
   31962                 :             :              class C. [ Note: for example, the constructor is not an
   31963                 :             :              acceptable lookup result in an elaborated-type-specifier so
   31964                 :             :              the constructor would not be used in place of the
   31965                 :             :              injected-class-name. --end note ] Such a constructor name
   31966                 :             :              shall be used only in the declarator-id of a declaration that
   31967                 :             :              names a constructor or in a using-declaration.  */
   31968                 :   306859870 :           if (tag_type == none_type
   31969                 :   288688898 :               && DECL_SELF_REFERENCE_P (decl)
   31970                 :   307005049 :               && same_type_p (DECL_CONTEXT (decl), parser->scope))
   31971                 :      145157 :             decl = lookup_qualified_name (parser->scope, ctor_identifier,
   31972                 :             :                                           prefer_type_arg (tag_type),
   31973                 :             :                                           /*complain=*/true);
   31974                 :             : 
   31975                 :   306859870 :           if (pushed_scope)
   31976                 :     1570270 :             pop_scope (pushed_scope);
   31977                 :             :         }
   31978                 :             : 
   31979                 :             :       /* If the scope is a dependent type and either we deferred lookup or
   31980                 :             :          we did lookup but didn't find the name, rememeber the name.  */
   31981                 :   108790628 :       if (decl == error_mark_node && TYPE_P (parser->scope)
   31982                 :   524430692 :           && dependent_type_p (parser->scope))
   31983                 :             :         {
   31984                 :   108787524 :           if (tag_type)
   31985                 :             :             {
   31986                 :      345513 :               tree type;
   31987                 :             : 
   31988                 :             :               /* The resolution to Core Issue 180 says that `struct
   31989                 :             :                  A::B' should be considered a type-name, even if `A'
   31990                 :             :                  is dependent.  */
   31991                 :      345513 :               type = make_typename_type (parser->scope, name, tag_type,
   31992                 :             :                                          /*complain=*/tf_error);
   31993                 :      345513 :               if (type != error_mark_node)
   31994                 :      345507 :                 decl = TYPE_NAME (type);
   31995                 :             :             }
   31996                 :   108442011 :           else if (is_template
   31997                 :   108442011 :                    && (cp_parser_next_token_ends_template_argument_p (parser)
   31998                 :     2723192 :                        || cp_lexer_next_token_is (parser->lexer,
   31999                 :             :                                                   CPP_CLOSE_PAREN)))
   32000                 :       42723 :             decl = make_unbound_class_template (parser->scope,
   32001                 :             :                                                 name, NULL_TREE,
   32002                 :             :                                                 /*complain=*/tf_error);
   32003                 :             :           else
   32004                 :   108399288 :             decl = build_qualified_name (/*type=*/NULL_TREE,
   32005                 :             :                                          parser->scope, name,
   32006                 :             :                                          is_template);
   32007                 :             :         }
   32008                 :   415642094 :       parser->qualifying_scope = parser->scope;
   32009                 :   415642094 :       parser->object_scope = NULL_TREE;
   32010                 :             :     }
   32011                 :  3457559374 :   else if (object_type)
   32012                 :             :     {
   32013                 :     1887256 :       bool dep = dependent_scope_p (object_type);
   32014                 :             : 
   32015                 :             :       /* Look up the name in the scope of the OBJECT_TYPE, unless the
   32016                 :             :          OBJECT_TYPE is not a class.  */
   32017                 :     1887256 :       if (!dep && CLASS_TYPE_P (object_type))
   32018                 :             :         /* If the OBJECT_TYPE is a template specialization, it may
   32019                 :             :            be instantiated during name lookup.  In that case, errors
   32020                 :             :            may be issued.  Even if we rollback the current tentative
   32021                 :             :            parse, those errors are valid.  */
   32022                 :      747576 :         decl = lookup_member (object_type,
   32023                 :             :                               name,
   32024                 :             :                               /*protect=*/0,
   32025                 :             :                               /*prefer_type=*/tag_type != none_type,
   32026                 :             :                               tf_warning_or_error);
   32027                 :             :       else
   32028                 :             :         decl = NULL_TREE;
   32029                 :             : 
   32030                 :             :       /* If we didn't find a member and have dependent bases, the member lookup
   32031                 :             :          is now dependent.  */
   32032                 :     1887256 :       if (!dep && !decl && any_dependent_bases_p (object_type))
   32033                 :             :         dep = true;
   32034                 :             : 
   32035                 :     1887256 :       if (dep && is_template == 2)
   32036                 :             :         /* The template keyword specifies a dependent template.  */;
   32037                 :     1878084 :       else if (!decl)
   32038                 :             :         /* Look it up in the enclosing context.  DR 141: When looking for a
   32039                 :             :            template-name after -> or ., only consider class templates.  */
   32040                 :     1231087 :         decl = lookup_name (name, is_namespace ? LOOK_want::NAMESPACE
   32041                 :             :                             /* DR 141: When looking in the
   32042                 :             :                                current enclosing context for a
   32043                 :             :                                template-name after -> or ., only
   32044                 :             :                                consider class templates.  */
   32045                 :     1231005 :                             : is_template ? LOOK_want::TYPE
   32046                 :     1231087 :                             : prefer_type_arg (tag_type));
   32047                 :             : 
   32048                 :             :       /* If we did unqualified lookup of a dependent member-qualified name and
   32049                 :             :          found something, do we want to use it?  P1787 clarified that we need
   32050                 :             :          to look in the object scope first even if it's dependent, but for now
   32051                 :             :          let's still use it in some cases.
   32052                 :             :          FIXME remember unqualified lookup result to use if member lookup fails
   32053                 :             :          at instantiation time.  */
   32054                 :     1887256 :       if (decl && dep && is_template)
   32055                 :             :         {
   32056                 :      103338 :           saved_token_sentinel toks (parser->lexer, STS_ROLLBACK);
   32057                 :             :           /* Only use the unqualified class template lookup if we're actually
   32058                 :             :              looking at a template arg list.  */
   32059                 :      103338 :           if (!cp_parser_skip_entire_template_parameter_list (parser))
   32060                 :          12 :             decl = NULL_TREE;
   32061                 :      103338 :         }
   32062                 :             : 
   32063                 :             :       /* If we know we're looking for a type (e.g. A in p->A::x),
   32064                 :             :          mock up a typename.  */
   32065                 :     1887256 :       if (!decl && dep && tag_type != none_type)
   32066                 :             :         {
   32067                 :          23 :           tree type = build_typename_type (object_type, name, name,
   32068                 :             :                                            typename_type);
   32069                 :          23 :           decl = TYPE_NAME (type);
   32070                 :             :         }
   32071                 :             : 
   32072                 :     1887256 :       parser->object_scope = object_type;
   32073                 :     1887256 :       parser->qualifying_scope = NULL_TREE;
   32074                 :             :     }
   32075                 :             :   else
   32076                 :             :     {
   32077                 :  3455672118 :       decl = lookup_name (name, is_namespace ? LOOK_want::NAMESPACE
   32078                 :  3455672118 :                           : prefer_type_arg (tag_type));
   32079                 :  3455672118 :       parser->qualifying_scope = NULL_TREE;
   32080                 :  3455672118 :       parser->object_scope = NULL_TREE;
   32081                 :             :     }
   32082                 :             : 
   32083                 :             :   /* If the lookup failed, let our caller know.  */
   32084                 :  3873201468 :   if (!decl || decl == error_mark_node)
   32085                 :    17055457 :     return error_mark_node;
   32086                 :             : 
   32087                 :             :   /* If we have resolved the name of a member declaration, check to
   32088                 :             :      see if the declaration is accessible.  When the name resolves to
   32089                 :             :      set of overloaded functions, accessibility is checked when
   32090                 :             :      overload resolution is done.  If we have a TREE_LIST, then the lookup
   32091                 :             :      is either ambiguous or it found multiple injected-class-names, the
   32092                 :             :      accessibility of which is trivially satisfied.
   32093                 :             : 
   32094                 :             :      During an explicit instantiation, access is not checked at all,
   32095                 :             :      as per [temp.explicit].  */
   32096                 :  3856146011 :   if (DECL_P (decl))
   32097                 :  3464826420 :     check_accessibility_of_qualified_id (decl, object_type, parser->scope,
   32098                 :             :                                          tf_warning_or_error);
   32099                 :             : 
   32100                 :             :   /* Pull out the template from an injected-class-name (or multiple).  */
   32101                 :  3856146011 :   if (is_template)
   32102                 :   269411495 :     decl = maybe_get_template_decl_from_type_decl (decl);
   32103                 :             : 
   32104                 :             :   /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
   32105                 :  3856146011 :   if (TREE_CODE (decl) == TREE_LIST)
   32106                 :             :     {
   32107                 :       18947 :       if (ambiguous_decls)
   32108                 :         352 :         *ambiguous_decls = decl;
   32109                 :             :       /* The error message we have to print is too complicated for
   32110                 :             :          cp_parser_error, so we incorporate its actions directly.  */
   32111                 :       18796 :       if (!cp_parser_simulate_error (parser))
   32112                 :             :         {
   32113                 :         151 :           error_at (name_location, "reference to %qD is ambiguous",
   32114                 :             :                     name);
   32115                 :         151 :           print_candidates (decl);
   32116                 :             :         }
   32117                 :       18947 :       return error_mark_node;
   32118                 :             :     }
   32119                 :             : 
   32120                 :  3856127064 :   gcc_assert (DECL_P (decl)
   32121                 :             :               || TREE_CODE (decl) == OVERLOAD
   32122                 :             :               || TREE_CODE (decl) == SCOPE_REF
   32123                 :             :               || TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE
   32124                 :             :               || BASELINK_P (decl));
   32125                 :             : 
   32126                 :  3856127064 :   maybe_record_typedef_use (decl);
   32127                 :             : 
   32128                 :  3856127064 :   return cp_expr (decl, name_location);
   32129                 :             : }
   32130                 :             : 
   32131                 :             : /* Like cp_parser_lookup_name, but for use in the typical case where
   32132                 :             :    CHECK_ACCESS is TRUE, IS_TYPE is FALSE, IS_TEMPLATE is FALSE,
   32133                 :             :    IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE.  */
   32134                 :             : 
   32135                 :             : static tree
   32136                 :   839086289 : cp_parser_lookup_name_simple (cp_parser* parser, tree name, location_t location)
   32137                 :             : {
   32138                 :   839086289 :   return cp_parser_lookup_name (parser, name,
   32139                 :             :                                 none_type,
   32140                 :             :                                 /*is_template=*/false,
   32141                 :             :                                 /*is_namespace=*/false,
   32142                 :             :                                 /*check_dependency=*/true,
   32143                 :             :                                 /*ambiguous_decls=*/NULL,
   32144                 :   839086289 :                                 location);
   32145                 :             : }
   32146                 :             : 
   32147                 :             : /* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
   32148                 :             :    the current context, return the TYPE_DECL.  If TAG_NAME_P is
   32149                 :             :    true, the DECL indicates the class being defined in a class-head,
   32150                 :             :    or declared in an elaborated-type-specifier.
   32151                 :             : 
   32152                 :             :    Otherwise, return DECL.  */
   32153                 :             : 
   32154                 :             : static tree
   32155                 :  1837133583 : cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
   32156                 :             : {
   32157                 :             :   /* If the TEMPLATE_DECL is being declared as part of a class-head,
   32158                 :             :      the translation from TEMPLATE_DECL to TYPE_DECL occurs:
   32159                 :             : 
   32160                 :             :        struct A {
   32161                 :             :          template <typename T> struct B;
   32162                 :             :        };
   32163                 :             : 
   32164                 :             :        template <typename T> struct A::B {};
   32165                 :             : 
   32166                 :             :      Similarly, in an elaborated-type-specifier:
   32167                 :             : 
   32168                 :             :        namespace N { struct X{}; }
   32169                 :             : 
   32170                 :             :        struct A {
   32171                 :             :          template <typename T> friend struct N::X;
   32172                 :             :        };
   32173                 :             : 
   32174                 :             :      However, if the DECL refers to a class type, and we are in
   32175                 :             :      the scope of the class, then the name lookup automatically
   32176                 :             :      finds the TYPE_DECL created by build_self_reference rather
   32177                 :             :      than a TEMPLATE_DECL.  For example, in:
   32178                 :             : 
   32179                 :             :        template <class T> struct S {
   32180                 :             :          S s;
   32181                 :             :        };
   32182                 :             : 
   32183                 :             :      there is no need to handle such case.  */
   32184                 :             : 
   32185                 :  1837133583 :   if (DECL_CLASS_TEMPLATE_P (decl) && tag_name_p)
   32186                 :             :     return DECL_TEMPLATE_RESULT (decl);
   32187                 :             : 
   32188                 :             :   return decl;
   32189                 :             : }
   32190                 :             : 
   32191                 :             : /* If too many, or too few, template-parameter lists apply to the
   32192                 :             :    declarator, issue an error message.  Returns TRUE if all went well,
   32193                 :             :    and FALSE otherwise.  */
   32194                 :             : 
   32195                 :             : static bool
   32196                 :   149923162 : cp_parser_check_declarator_template_parameters (cp_parser* parser,
   32197                 :             :                                                 cp_declarator *declarator,
   32198                 :             :                                                 location_t declarator_location)
   32199                 :             : {
   32200                 :   253527583 :   switch (declarator->kind)
   32201                 :             :     {
   32202                 :   149923162 :     case cdk_id:
   32203                 :   149923162 :       {
   32204                 :   149923162 :         unsigned num_templates = 0;
   32205                 :   149923162 :         tree scope = declarator->u.id.qualifying_scope;
   32206                 :   149923162 :         bool template_id_p = false;
   32207                 :             : 
   32208                 :   149923162 :         if (scope)
   32209                 :     8656979 :           num_templates = num_template_headers_for_class (scope);
   32210                 :   141266183 :         else if (TREE_CODE (declarator->u.id.unqualified_name)
   32211                 :             :                  == TEMPLATE_ID_EXPR)
   32212                 :             :           {
   32213                 :             :             /* If the DECLARATOR has the form `X<y>' then it uses one
   32214                 :             :                additional level of template parameters.  */
   32215                 :      805485 :             ++num_templates;
   32216                 :      805485 :             template_id_p = true;
   32217                 :             :           }
   32218                 :             : 
   32219                 :   149923162 :         return cp_parser_check_template_parameters
   32220                 :   149923162 :           (parser, num_templates, template_id_p, declarator_location,
   32221                 :   149923162 :            declarator);
   32222                 :             :       }
   32223                 :             : 
   32224                 :   103604421 :     case cdk_function:
   32225                 :   103604421 :     case cdk_array:
   32226                 :   103604421 :     case cdk_pointer:
   32227                 :   103604421 :     case cdk_reference:
   32228                 :   103604421 :     case cdk_ptrmem:
   32229                 :   103604421 :       return (cp_parser_check_declarator_template_parameters
   32230                 :   103604421 :               (parser, declarator->declarator, declarator_location));
   32231                 :             : 
   32232                 :             :     case cdk_decomp:
   32233                 :             :     case cdk_error:
   32234                 :             :       return true;
   32235                 :             : 
   32236                 :           0 :     default:
   32237                 :           0 :       gcc_unreachable ();
   32238                 :             :     }
   32239                 :             :   return false;
   32240                 :             : }
   32241                 :             : 
   32242                 :             : /* NUM_TEMPLATES were used in the current declaration.  If that is
   32243                 :             :    invalid, return FALSE and issue an error messages.  Otherwise,
   32244                 :             :    return TRUE.  If DECLARATOR is non-NULL, then we are checking a
   32245                 :             :    declarator and we can print more accurate diagnostics.  */
   32246                 :             : 
   32247                 :             : static bool
   32248                 :   179701866 : cp_parser_check_template_parameters (cp_parser* parser,
   32249                 :             :                                      unsigned num_templates,
   32250                 :             :                                      bool template_id_p,
   32251                 :             :                                      location_t location,
   32252                 :             :                                      cp_declarator *declarator)
   32253                 :             : {
   32254                 :             :   /* If there are the same number of template classes and parameter
   32255                 :             :      lists, that's OK.  */
   32256                 :   179701866 :   if (parser->num_template_parameter_lists == num_templates)
   32257                 :             :     return true;
   32258                 :             :   /* If there are more, but only one more, and the name ends in an identifier,
   32259                 :             :      then we are declaring a primary template.  That's OK too.  */
   32260                 :    59600458 :   if (!template_id_p
   32261                 :    59600398 :       && parser->num_template_parameter_lists == num_templates + 1)
   32262                 :             :     return true;
   32263                 :             : 
   32264                 :         238 :   if (cp_parser_simulate_error (parser))
   32265                 :          12 :     return false;
   32266                 :             : 
   32267                 :             :   /* If there are more template classes than parameter lists, we have
   32268                 :             :      something like:
   32269                 :             : 
   32270                 :             :        template <class T> void S<T>::R<T>::f ();  */
   32271                 :         107 :   if (parser->num_template_parameter_lists < num_templates)
   32272                 :             :     {
   32273                 :          65 :       if (declarator && !current_function_decl)
   32274                 :          21 :         error_at (location, "specializing member %<%T::%E%> "
   32275                 :             :                   "requires %<template<>%> syntax",
   32276                 :             :                   declarator->u.id.qualifying_scope,
   32277                 :             :                   declarator->u.id.unqualified_name);
   32278                 :           8 :       else if (declarator)
   32279                 :           8 :         error_at (location, "invalid declaration of %<%T::%E%>",
   32280                 :             :                   declarator->u.id.qualifying_scope,
   32281                 :             :                   declarator->u.id.unqualified_name);
   32282                 :             :       else
   32283                 :          36 :         error_at (location, "too few template-parameter-lists");
   32284                 :          65 :       return false;
   32285                 :             :     }
   32286                 :             :   /* Otherwise, there are too many template parameter lists.  We have
   32287                 :             :      something like:
   32288                 :             : 
   32289                 :             :      template <class T> template <class U> void S::f();  */
   32290                 :          42 :   error_at (location, "too many template-parameter-lists");
   32291                 :          42 :   return false;
   32292                 :             : }
   32293                 :             : 
   32294                 :             : /* Parse an optional `::' token indicating that the following name is
   32295                 :             :    from the global namespace.  If so, PARSER->SCOPE is set to the
   32296                 :             :    GLOBAL_NAMESPACE. Otherwise, PARSER->SCOPE is set to NULL_TREE,
   32297                 :             :    unless CURRENT_SCOPE_VALID_P is TRUE, in which case it is left alone.
   32298                 :             :    Returns the new value of PARSER->SCOPE, if the `::' token is
   32299                 :             :    present, and NULL_TREE otherwise.  */
   32300                 :             : 
   32301                 :             : static tree
   32302                 :  4409996839 : cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
   32303                 :             : {
   32304                 :  4409996839 :   cp_token *token;
   32305                 :             : 
   32306                 :             :   /* Peek at the next token.  */
   32307                 :  4409996839 :   token = cp_lexer_peek_token (parser->lexer);
   32308                 :             :   /* If we're looking at a `::' token then we're starting from the
   32309                 :             :      global namespace, not our current location.  */
   32310                 :  4409996839 :   if (token->type == CPP_SCOPE)
   32311                 :             :     {
   32312                 :             :       /* Consume the `::' token.  */
   32313                 :     7549980 :       cp_lexer_consume_token (parser->lexer);
   32314                 :             :       /* Set the SCOPE so that we know where to start the lookup.  */
   32315                 :     7549980 :       parser->scope = global_namespace;
   32316                 :     7549980 :       parser->qualifying_scope = global_namespace;
   32317                 :     7549980 :       parser->object_scope = NULL_TREE;
   32318                 :             : 
   32319                 :     7549980 :       return parser->scope;
   32320                 :             :     }
   32321                 :  4402446859 :   else if (!current_scope_valid_p)
   32322                 :             :     {
   32323                 :  4339779079 :       parser->scope = NULL_TREE;
   32324                 :  4339779079 :       parser->qualifying_scope = NULL_TREE;
   32325                 :  4339779079 :       parser->object_scope = NULL_TREE;
   32326                 :             :     }
   32327                 :             : 
   32328                 :             :   return NULL_TREE;
   32329                 :             : }
   32330                 :             : 
   32331                 :             : /* Returns TRUE if the upcoming token sequence is the start of a
   32332                 :             :    constructor declarator or C++17 deduction guide.  If FRIEND_P is true, the
   32333                 :             :    declarator is preceded by the `friend' specifier.  The parser flags FLAGS
   32334                 :             :    is used to control type-specifier parsing.  */
   32335                 :             : 
   32336                 :             : static bool
   32337                 :   406050691 : cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags,
   32338                 :             :                                     bool friend_p)
   32339                 :             : {
   32340                 :   406050691 :   bool constructor_p;
   32341                 :   406050691 :   bool outside_class_specifier_p;
   32342                 :   406050691 :   tree nested_name_specifier;
   32343                 :   406050691 :   cp_token *next_token;
   32344                 :             : 
   32345                 :             :   /* The common case is that this is not a constructor declarator, so
   32346                 :             :      try to avoid doing lots of work if at all possible.  It's not
   32347                 :             :      valid declare a constructor at function scope.  */
   32348                 :   406050691 :   if (parser->in_function_body)
   32349                 :             :     return false;
   32350                 :             :   /* And only certain tokens can begin a constructor declarator.  */
   32351                 :   229545438 :   next_token = cp_lexer_peek_token (parser->lexer);
   32352                 :   229545438 :   if (next_token->type != CPP_NAME
   32353                 :             :       && next_token->type != CPP_SCOPE
   32354                 :             :       && next_token->type != CPP_NESTED_NAME_SPECIFIER
   32355                 :             :       && next_token->type != CPP_TEMPLATE_ID)
   32356                 :             :     return false;
   32357                 :             : 
   32358                 :             :   /* Parse tentatively; we are going to roll back all of the tokens
   32359                 :             :      consumed here.  */
   32360                 :    98370076 :   cp_parser_parse_tentatively (parser);
   32361                 :             :   /* Assume that we are looking at a constructor declarator.  */
   32362                 :    98370076 :   constructor_p = true;
   32363                 :             : 
   32364                 :             :   /* Look for the optional `::' operator.  */
   32365                 :    98370076 :   cp_parser_global_scope_opt (parser,
   32366                 :             :                               /*current_scope_valid_p=*/false);
   32367                 :             :   /* Look for the nested-name-specifier.  */
   32368                 :    98370076 :   nested_name_specifier
   32369                 :    98370076 :     = (cp_parser_nested_name_specifier_opt (parser,
   32370                 :             :                                             /*typename_keyword_p=*/false,
   32371                 :             :                                             /*check_dependency_p=*/false,
   32372                 :             :                                             /*type_p=*/false,
   32373                 :             :                                             /*is_declaration=*/false));
   32374                 :             : 
   32375                 :             :   /* Resolve the TYPENAME_TYPE, because the call above didn't do it.  */
   32376                 :    98370074 :   if (nested_name_specifier
   32377                 :     6904449 :       && TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
   32378                 :             :     {
   32379                 :       17640 :       tree s = resolve_typename_type (nested_name_specifier,
   32380                 :             :                                       /*only_current_p=*/false);
   32381                 :       17640 :       if (TREE_CODE (s) != TYPENAME_TYPE)
   32382                 :    98370074 :         nested_name_specifier = s;
   32383                 :             :     }
   32384                 :             : 
   32385                 :    98370074 :   outside_class_specifier_p = (!at_class_scope_p ()
   32386                 :    67284171 :                                || !TYPE_BEING_DEFINED (current_class_type)
   32387                 :    98370074 :                                || friend_p);
   32388                 :             : 
   32389                 :             :   /* Outside of a class-specifier, there must be a
   32390                 :             :      nested-name-specifier.  Except in C++17 mode, where we
   32391                 :             :      might be declaring a guiding declaration.  */
   32392                 :    98370074 :   if (!nested_name_specifier && outside_class_specifier_p
   32393                 :    27843825 :       && cxx_dialect < cxx17)
   32394                 :             :     constructor_p = false;
   32395                 :    97193329 :   else if (nested_name_specifier == error_mark_node)
   32396                 :     1176754 :     constructor_p = false;
   32397                 :             : 
   32398                 :             :   /* If we have a class scope, this is easy; DR 147 says that S::S always
   32399                 :             :      names the constructor, and no other qualified name could.  */
   32400                 :    98370074 :   if (constructor_p && nested_name_specifier
   32401                 :    98370074 :       && CLASS_TYPE_P (nested_name_specifier))
   32402                 :             :     {
   32403                 :     1425444 :       tree id = cp_parser_unqualified_id (parser,
   32404                 :             :                                           /*template_keyword_p=*/false,
   32405                 :             :                                           /*check_dependency_p=*/false,
   32406                 :             :                                           /*declarator_p=*/true,
   32407                 :             :                                           /*optional_p=*/false);
   32408                 :     1425444 :       if (is_overloaded_fn (id))
   32409                 :          21 :         id = DECL_NAME (get_first_fn (id));
   32410                 :     1425444 :       if (!constructor_name_p (id, nested_name_specifier))
   32411                 :    77490334 :         constructor_p = false;
   32412                 :             :     }
   32413                 :             :   /* If we still think that this might be a constructor-declarator,
   32414                 :             :      look for a class-name.  */
   32415                 :    96944630 :   else if (constructor_p)
   32416                 :             :     {
   32417                 :             :       /* If we have:
   32418                 :             : 
   32419                 :             :            template <typename T> struct S {
   32420                 :             :              S();
   32421                 :             :            };
   32422                 :             : 
   32423                 :             :          we must recognize that the nested `S' names a class.  */
   32424                 :    95767876 :       if (cxx_dialect >= cxx17)
   32425                 :    94739741 :         cp_parser_parse_tentatively (parser);
   32426                 :             : 
   32427                 :    95767876 :       tree type_decl;
   32428                 :    95767876 :       type_decl = cp_parser_class_name (parser,
   32429                 :             :                                         /*typename_keyword_p=*/false,
   32430                 :             :                                         /*template_keyword_p=*/false,
   32431                 :             :                                         none_type,
   32432                 :             :                                         /*check_dependency_p=*/false,
   32433                 :             :                                         /*class_head_p=*/false,
   32434                 :             :                                         /*is_declaration=*/false);
   32435                 :             : 
   32436                 :    95767876 :       if (cxx_dialect >= cxx17
   32437                 :    95767876 :           && !cp_parser_parse_definitely (parser))
   32438                 :             :         {
   32439                 :    22092852 :           type_decl = NULL_TREE;
   32440                 :    22092852 :           tree tmpl = cp_parser_template_name (parser,
   32441                 :             :                                                /*template_keyword*/false,
   32442                 :             :                                                /*check_dependency_p*/false,
   32443                 :             :                                                /*is_declaration*/false,
   32444                 :             :                                                none_type,
   32445                 :             :                                                /*is_identifier*/NULL);
   32446                 :     1912842 :           if (DECL_CLASS_TEMPLATE_P (tmpl)
   32447                 :    23193920 :               || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))
   32448                 :             :             /* It's a deduction guide, return true.  */;
   32449                 :             :           else
   32450                 :   117048934 :             cp_parser_simulate_error (parser);
   32451                 :             :         }
   32452                 :             : 
   32453                 :             :       /* If there was no class-name, then this is not a constructor.
   32454                 :             :          Otherwise, if we are in a class-specifier and we aren't
   32455                 :             :          handling a friend declaration, check that its type matches
   32456                 :             :          current_class_type (c++/38313).  Note: error_mark_node
   32457                 :             :          is left alone for error recovery purposes.  */
   32458                 :   285857429 :       constructor_p = (!cp_parser_error_occurred (parser)
   32459                 :    74196287 :                        && (outside_class_specifier_p
   32460                 :    74196287 :                            || type_decl == NULL_TREE
   32461                 :    53176637 :                            || type_decl == error_mark_node
   32462                 :    53176545 :                            || same_type_p (current_class_type,
   32463                 :             :                                            TREE_TYPE (type_decl))));
   32464                 :             : 
   32465                 :             :       /* If we're still considering a constructor, we have to see a `(',
   32466                 :             :          to begin the parameter-declaration-clause, followed by either a
   32467                 :             :          `)', an `...', or a decl-specifier.  We need to check for a
   32468                 :             :          type-specifier to avoid being fooled into thinking that:
   32469                 :             : 
   32470                 :             :            S (f) (int);
   32471                 :             : 
   32472                 :             :          is a constructor.  (It is actually a function named `f' that
   32473                 :             :          takes one parameter (of type `int') and returns a value of type
   32474                 :             :          `S'.  */
   32475                 :    49008935 :       if (constructor_p
   32476                 :    49008935 :           && !cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   32477                 :             :         constructor_p = false;
   32478                 :             : 
   32479                 :    66884331 :       if (constructor_p
   32480                 :    20125390 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
   32481                 :    16481730 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)
   32482                 :             :           /* A parameter declaration begins with a decl-specifier,
   32483                 :             :              which is either the "attribute" keyword, a storage class
   32484                 :             :              specifier, or (usually) a type-specifier.  */
   32485                 :    16480228 :           && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)
   32486                 :             :           /* GNU attributes can actually appear both at the start of
   32487                 :             :              a parameter and parenthesized declarator.
   32488                 :             :              S (__attribute__((unused)) int);
   32489                 :             :              is a constructor, but
   32490                 :             :              S (__attribute__((unused)) foo) (int);
   32491                 :             :              is a function declaration. [[attribute]] can appear in the
   32492                 :             :              first form too, but not in the second form.  */
   32493                 :    76882686 :           && !cp_next_tokens_can_be_std_attribute_p (parser))
   32494                 :             :         {
   32495                 :     9998343 :           tree type;
   32496                 :     9998343 :           tree pushed_scope = NULL_TREE;
   32497                 :     9998343 :           unsigned saved_num_template_parameter_lists;
   32498                 :             : 
   32499                 :     9998343 :           if (cp_parser_allow_gnu_extensions_p (parser)
   32500                 :     9998343 :               && cp_next_tokens_can_be_gnu_attribute_p (parser))
   32501                 :             :             {
   32502                 :          22 :               unsigned int n = cp_parser_skip_gnu_attributes_opt (parser, 1);
   32503                 :         154 :               while (--n)
   32504                 :         132 :                 cp_lexer_consume_token (parser->lexer);
   32505                 :             :             }
   32506                 :             : 
   32507                 :             :           /* Names appearing in the type-specifier should be looked up
   32508                 :             :              in the scope of the class.  */
   32509                 :     9998343 :           if (current_class_type)
   32510                 :     9998343 :             type = NULL_TREE;
   32511                 :      798363 :           else if (type_decl)
   32512                 :             :             {
   32513                 :         134 :               type = TREE_TYPE (type_decl);
   32514                 :         134 :               if (TREE_CODE (type) == TYPENAME_TYPE)
   32515                 :             :                 {
   32516                 :           0 :                   type = resolve_typename_type (type,
   32517                 :             :                                                 /*only_current_p=*/false);
   32518                 :           0 :                   if (TREE_CODE (type) == TYPENAME_TYPE)
   32519                 :             :                     {
   32520                 :           0 :                       cp_parser_abort_tentative_parse (parser);
   32521                 :           0 :                       return false;
   32522                 :             :                     }
   32523                 :             :                 }
   32524                 :         134 :               pushed_scope = push_scope (type);
   32525                 :             :             }
   32526                 :             : 
   32527                 :             :           /* Inside the constructor parameter list, surrounding
   32528                 :             :              template-parameter-lists do not apply.  */
   32529                 :     9998343 :           saved_num_template_parameter_lists
   32530                 :     9998343 :             = parser->num_template_parameter_lists;
   32531                 :     9998343 :           parser->num_template_parameter_lists = 0;
   32532                 :             : 
   32533                 :             :           /* Look for the type-specifier.  It's not optional, but its typename
   32534                 :             :              might be.  Unless this is a friend declaration; we don't want to
   32535                 :             :              treat
   32536                 :             : 
   32537                 :             :                friend S (T::fn)(int);
   32538                 :             : 
   32539                 :             :              as a constructor, but with P0634, we might assume a type when
   32540                 :             :              looking for the type-specifier.  It is actually a function named
   32541                 :             :              `T::fn' that takes one parameter (of type `int') and returns a
   32542                 :             :              value of type `S'.  Constructors can be friends, but they must
   32543                 :             :              use a qualified name.
   32544                 :             : 
   32545                 :             :              Parse with an empty set of declaration specifiers since we're
   32546                 :             :              trying to match a decl-specifier-seq of the first parameter.  
   32547                 :             :              This must be non-null so that cp_parser_simple_type_specifier
   32548                 :             :              will recognize a constrained placeholder type such as:
   32549                 :             :              'C<int> auto' where C is a type concept.  */
   32550                 :     9998343 :           cp_decl_specifier_seq ctor_specs;
   32551                 :     9998343 :           clear_decl_specs (&ctor_specs);
   32552                 :     9998343 :           cp_parser_type_specifier (parser,
   32553                 :             :                                     (friend_p ? CP_PARSER_FLAGS_NONE
   32554                 :             :                                      : (flags & ~CP_PARSER_FLAGS_OPTIONAL)),
   32555                 :             :                                     /*decl_specs=*/&ctor_specs,
   32556                 :             :                                     /*is_declarator=*/true,
   32557                 :             :                                     /*declares_class_or_enum=*/NULL,
   32558                 :             :                                     /*is_cv_qualifier=*/NULL);
   32559                 :             : 
   32560                 :     9998343 :           parser->num_template_parameter_lists
   32561                 :     9998343 :             = saved_num_template_parameter_lists;
   32562                 :             : 
   32563                 :             :           /* Leave the scope of the class.  */
   32564                 :     9998343 :           if (pushed_scope)
   32565                 :         134 :             pop_scope (pushed_scope);
   32566                 :             : 
   32567                 :     9998343 :           constructor_p = !cp_parser_error_occurred (parser);
   32568                 :             :         }
   32569                 :             :     }
   32570                 :             : 
   32571                 :             :   /* We did not really want to consume any tokens.  */
   32572                 :    98370074 :   cp_parser_abort_tentative_parse (parser);
   32573                 :             : 
   32574                 :             :   /* DR 2237 (C++20 only): A simple-template-id is no longer valid as the
   32575                 :             :      declarator-id of a constructor or destructor.  */
   32576                 :    98370074 :   if (constructor_p
   32577                 :    98370074 :       && cp_lexer_peek_token (parser->lexer)->type == CPP_TEMPLATE_ID)
   32578                 :             :     {
   32579                 :          70 :       auto_diagnostic_group d;
   32580                 :         124 :       if (emit_diagnostic (cxx_dialect >= cxx20 ? DK_PEDWARN : DK_WARNING,
   32581                 :             :                            input_location, OPT_Wtemplate_id_cdtor,
   32582                 :             :                            "template-id not allowed for constructor in C++20"))
   32583                 :          24 :         inform (input_location, "remove the %qs", "< >");
   32584                 :          70 :     }
   32585                 :             : 
   32586                 :             :   return constructor_p;
   32587                 :             : }
   32588                 :             : 
   32589                 :             : /* Parse the definition of the function given by the DECL_SPECIFIERS,
   32590                 :             :    ATTRIBUTES, and DECLARATOR.  The access checks have been deferred;
   32591                 :             :    they must be performed once we are in the scope of the function.
   32592                 :             : 
   32593                 :             :    Returns the function defined.  */
   32594                 :             : 
   32595                 :             : static tree
   32596                 :    36389629 : cp_parser_function_definition_from_specifiers_and_declarator
   32597                 :             :   (cp_parser* parser,
   32598                 :             :    cp_decl_specifier_seq *decl_specifiers,
   32599                 :             :    tree attributes,
   32600                 :             :    const cp_declarator *declarator)
   32601                 :             : {
   32602                 :    36389629 :   tree fn;
   32603                 :    36389629 :   bool success_p;
   32604                 :             : 
   32605                 :             :   /* Begin the function-definition.  */
   32606                 :    36389629 :   success_p = start_function (decl_specifiers, declarator, attributes);
   32607                 :             : 
   32608                 :             :   /* The things we're about to see are not directly qualified by any
   32609                 :             :      template headers we've seen thus far.  */
   32610                 :    36389629 :   reset_specialization ();
   32611                 :             : 
   32612                 :             :   /* If there were names looked up in the decl-specifier-seq that we
   32613                 :             :      did not check, check them now.  We must wait until we are in the
   32614                 :             :      scope of the function to perform the checks, since the function
   32615                 :             :      might be a friend.  */
   32616                 :    36389629 :   perform_deferred_access_checks (tf_warning_or_error);
   32617                 :             : 
   32618                 :    36389629 :   if (success_p)
   32619                 :             :     {
   32620                 :    36389273 :       cp_finalize_omp_declare_simd (parser, current_function_decl);
   32621                 :    36389273 :       parser->omp_declare_simd = NULL;
   32622                 :    36389273 :       cp_finalize_oacc_routine (parser, current_function_decl, true);
   32623                 :    36389273 :       parser->oacc_routine = NULL;
   32624                 :             :     }
   32625                 :             : 
   32626                 :    36389629 :   if (!success_p)
   32627                 :             :     {
   32628                 :             :       /* Skip the entire function.  */
   32629                 :         356 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   32630                 :         356 :       fn = error_mark_node;
   32631                 :             :     }
   32632                 :    36389273 :   else if (DECL_INITIAL (current_function_decl) != error_mark_node)
   32633                 :             :     {
   32634                 :             :       /* Seen already, skip it.  An error message has already been output.  */
   32635                 :           0 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   32636                 :           0 :       fn = current_function_decl;
   32637                 :           0 :       current_function_decl = NULL_TREE;
   32638                 :             :       /* If this is a function from a class, pop the nested class.  */
   32639                 :           0 :       if (current_class_name)
   32640                 :           0 :         pop_nested_class ();
   32641                 :             :     }
   32642                 :             :   else
   32643                 :             :     {
   32644                 :    36389273 :       auto_timevar tv (DECL_DECLARED_INLINE_P (current_function_decl)
   32645                 :    45147330 :                        ? TV_PARSE_INLINE : TV_PARSE_FUNC);
   32646                 :    36389273 :       fn = cp_parser_function_definition_after_declarator (parser,
   32647                 :             :                                                          /*inline_p=*/false);
   32648                 :    36389248 :     }
   32649                 :             : 
   32650                 :    36389604 :   return fn;
   32651                 :             : }
   32652                 :             : 
   32653                 :             : /* Parse the part of a function-definition that follows the
   32654                 :             :    declarator.  INLINE_P is TRUE iff this function is an inline
   32655                 :             :    function defined within a class-specifier.
   32656                 :             : 
   32657                 :             :    Returns the function defined.  */
   32658                 :             : 
   32659                 :             : static tree
   32660                 :    98020965 : cp_parser_function_definition_after_declarator (cp_parser* parser,
   32661                 :             :                                                 bool inline_p)
   32662                 :             : {
   32663                 :    98020965 :   tree fn;
   32664                 :    98020965 :   bool saved_in_unbraced_linkage_specification_p;
   32665                 :    98020965 :   bool saved_in_function_body;
   32666                 :    98020965 :   unsigned saved_num_template_parameter_lists;
   32667                 :    98020965 :   cp_token *token;
   32668                 :    98020965 :   bool fully_implicit_function_template_p
   32669                 :             :     = parser->fully_implicit_function_template_p;
   32670                 :    98020965 :   parser->fully_implicit_function_template_p = false;
   32671                 :    98020965 :   tree implicit_template_parms
   32672                 :             :     = parser->implicit_template_parms;
   32673                 :    98020965 :   parser->implicit_template_parms = 0;
   32674                 :    98020965 :   cp_binding_level* implicit_template_scope
   32675                 :             :     = parser->implicit_template_scope;
   32676                 :    98020965 :   parser->implicit_template_scope = 0;
   32677                 :             : 
   32678                 :    98020965 :   saved_in_function_body = parser->in_function_body;
   32679                 :    98020965 :   parser->in_function_body = true;
   32680                 :             :   /* If the next token is `return', then the code may be trying to
   32681                 :             :      make use of the "named return value" extension that G++ used to
   32682                 :             :      support.  */
   32683                 :    98020965 :   token = cp_lexer_peek_token (parser->lexer);
   32684                 :    98020965 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN))
   32685                 :             :     {
   32686                 :             :       /* Consume the `return' keyword.  */
   32687                 :         288 :       cp_lexer_consume_token (parser->lexer);
   32688                 :             :       /* Look for the identifier that indicates what value is to be
   32689                 :             :          returned.  */
   32690                 :         288 :       cp_parser_identifier (parser);
   32691                 :             :       /* Issue an error message.  */
   32692                 :         288 :       error_at (token->location,
   32693                 :             :                 "named return values are no longer supported");
   32694                 :             :       /* Skip tokens until we reach the start of the function body.  */
   32695                 :        1912 :       while (true)
   32696                 :             :         {
   32697                 :        1100 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   32698                 :        1100 :           if (token->type == CPP_OPEN_BRACE
   32699                 :             :               || token->type == CPP_EOF
   32700                 :             :               || token->type == CPP_PRAGMA_EOL)
   32701                 :             :             break;
   32702                 :         812 :           cp_lexer_consume_token (parser->lexer);
   32703                 :         812 :         }
   32704                 :             :     }
   32705                 :             :   /* The `extern' in `extern "C" void f () { ... }' does not apply to
   32706                 :             :      anything declared inside `f'.  */
   32707                 :    98020965 :   saved_in_unbraced_linkage_specification_p
   32708                 :    98020965 :     = parser->in_unbraced_linkage_specification_p;
   32709                 :    98020965 :   parser->in_unbraced_linkage_specification_p = false;
   32710                 :             :   /* Inside the function, surrounding template-parameter-lists do not
   32711                 :             :      apply.  */
   32712                 :    98020965 :   saved_num_template_parameter_lists
   32713                 :    98020965 :     = parser->num_template_parameter_lists;
   32714                 :    98020965 :   parser->num_template_parameter_lists = 0;
   32715                 :             : 
   32716                 :             :   /* If the next token is `try', `__transaction_atomic', or
   32717                 :             :      `__transaction_relaxed`, then we are looking at either function-try-block
   32718                 :             :      or function-transaction-block.  Note that all of these include the
   32719                 :             :      function-body.  */
   32720                 :    98020965 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_ATOMIC))
   32721                 :          24 :     cp_parser_function_transaction (parser, RID_TRANSACTION_ATOMIC);
   32722                 :    98020941 :   else if (cp_lexer_next_token_is_keyword (parser->lexer,
   32723                 :             :       RID_TRANSACTION_RELAXED))
   32724                 :           0 :     cp_parser_function_transaction (parser, RID_TRANSACTION_RELAXED);
   32725                 :    98020941 :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
   32726                 :         308 :     cp_parser_function_try_block (parser);
   32727                 :             :   else
   32728                 :    98020633 :     cp_parser_ctor_initializer_opt_and_function_body
   32729                 :    98020633 :       (parser, /*in_function_try_block=*/false);
   32730                 :             : 
   32731                 :             :   /* Finish the function.  */
   32732                 :    98020940 :   fn = finish_function (inline_p);
   32733                 :             : 
   32734                 :    98020940 :   if (modules_p ()
   32735                 :      450471 :       && !inline_p
   32736                 :      158796 :       && TYPE_P (DECL_CONTEXT (fn))
   32737                 :    98046904 :       && (DECL_DECLARED_INLINE_P (fn)
   32738                 :       14972 :           || processing_template_decl))
   32739                 :       25913 :     set_defining_module (fn);
   32740                 :             : 
   32741                 :             :   /* Generate code for it, if necessary.  */
   32742                 :    98020940 :   expand_or_defer_fn (fn);
   32743                 :             : 
   32744                 :             :   /* Restore the saved values.  */
   32745                 :    98020940 :   parser->in_unbraced_linkage_specification_p
   32746                 :    98020940 :     = saved_in_unbraced_linkage_specification_p;
   32747                 :    98020940 :   parser->num_template_parameter_lists
   32748                 :    98020940 :     = saved_num_template_parameter_lists;
   32749                 :    98020940 :   parser->in_function_body = saved_in_function_body;
   32750                 :             : 
   32751                 :    98020940 :   parser->fully_implicit_function_template_p
   32752                 :    98020940 :     = fully_implicit_function_template_p;
   32753                 :    98020940 :   parser->implicit_template_parms
   32754                 :    98020940 :     = implicit_template_parms;
   32755                 :    98020940 :   parser->implicit_template_scope
   32756                 :    98020940 :     = implicit_template_scope;
   32757                 :             : 
   32758                 :    98020940 :   if (parser->fully_implicit_function_template_p)
   32759                 :         182 :     finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
   32760                 :             : 
   32761                 :    98020940 :   return fn;
   32762                 :             : }
   32763                 :             : 
   32764                 :             : /* Parse a template-declaration body (following argument list).  */
   32765                 :             : 
   32766                 :             : static void
   32767                 :    74681356 : cp_parser_template_declaration_after_parameters (cp_parser* parser,
   32768                 :             :                                                  tree parameter_list,
   32769                 :             :                                                  bool member_p)
   32770                 :             : {
   32771                 :    74681356 :   tree decl = NULL_TREE;
   32772                 :    74681356 :   bool friend_p = false;
   32773                 :             : 
   32774                 :             :   /* We just processed one more parameter list.  */
   32775                 :    74681356 :   ++parser->num_template_parameter_lists;
   32776                 :             : 
   32777                 :             :   /* Get the deferred access checks from the parameter list.  These
   32778                 :             :      will be checked once we know what is being declared, as for a
   32779                 :             :      member template the checks must be performed in the scope of the
   32780                 :             :      class containing the member.  */
   32781                 :    74681356 :   vec<deferred_access_check, va_gc> *checks = get_deferred_access_checks ();
   32782                 :             : 
   32783                 :             :   /* Tentatively parse for a new template parameter list, which can either be
   32784                 :             :      the template keyword or a template introduction.  */
   32785                 :    74681356 :   if (cp_parser_template_declaration_after_export (parser, member_p))
   32786                 :             :     /* OK */;
   32787                 :    72767850 :   else if (cxx_dialect >= cxx11
   32788                 :    72767850 :            && cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
   32789                 :     3415758 :     decl = cp_parser_alias_declaration (parser);
   32790                 :    69352092 :   else if (flag_concepts
   32791                 :    17478253 :            && cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT)
   32792                 :    69894686 :            && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   32793                 :             :     /* -fconcept-ts 'concept bool' syntax is handled below, in
   32794                 :             :         cp_parser_single_declaration.  */
   32795                 :      542344 :     decl = cp_parser_concept_definition (parser);
   32796                 :             :   else
   32797                 :             :     {
   32798                 :    68809748 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   32799                 :    68809748 :       decl = cp_parser_single_declaration (parser,
   32800                 :             :                                            checks,
   32801                 :             :                                            member_p,
   32802                 :             :                                            /*explicit_specialization_p=*/false,
   32803                 :             :                                            &friend_p);
   32804                 :             : 
   32805                 :             :       /* If this is a member template declaration, let the front
   32806                 :             :          end know.  */
   32807                 :    68809739 :       if (member_p && !friend_p && decl)
   32808                 :             :         {
   32809                 :    16537332 :           if (TREE_CODE (decl) == TYPE_DECL)
   32810                 :     1133701 :             cp_parser_check_access_in_redeclaration (decl, token->location);
   32811                 :             : 
   32812                 :    16537332 :           decl = finish_member_template_decl (decl);
   32813                 :             :         }
   32814                 :     1799698 :       else if (friend_p && decl
   32815                 :    54072105 :                && DECL_DECLARES_TYPE_P (decl))
   32816                 :      530020 :         make_friend_class (current_class_type, TREE_TYPE (decl),
   32817                 :             :                            /*complain=*/true);
   32818                 :             :     }
   32819                 :             :   /* We are done with the current parameter list.  */
   32820                 :    74681347 :   --parser->num_template_parameter_lists;
   32821                 :             : 
   32822                 :    74681347 :   pop_deferring_access_checks ();
   32823                 :             : 
   32824                 :             :   /* Finish up.  */
   32825                 :    74681347 :   finish_template_decl (parameter_list);
   32826                 :             : 
   32827                 :             :   /* Check the template arguments for a literal operator template.  */
   32828                 :    74681347 :   if (decl
   32829                 :    72278592 :       && DECL_DECLARES_FUNCTION_P (decl)
   32830                 :   123276757 :       && UDLIT_OPER_P (DECL_NAME (decl)))
   32831                 :             :     {
   32832                 :       56387 :       bool ok = true;
   32833                 :       56387 :       if (parameter_list == NULL_TREE)
   32834                 :             :         ok = false;
   32835                 :             :       else
   32836                 :             :         {
   32837                 :       56387 :           int num_parms = TREE_VEC_LENGTH (parameter_list);
   32838                 :       56387 :           if (num_parms == 1)
   32839                 :             :             {
   32840                 :       56354 :               tree parm_list = TREE_VEC_ELT (parameter_list, 0);
   32841                 :       56354 :               tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
   32842                 :       56354 :               if (TREE_CODE (parm) != PARM_DECL)
   32843                 :             :                 ok = false;
   32844                 :       56348 :               else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (parm))
   32845                 :           6 :                        && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
   32846                 :             :                 /* OK, C++20 string literal operator template.  We don't need
   32847                 :             :                    to warn in lower dialects here because we will have already
   32848                 :             :                    warned about the template parameter.  */;
   32849                 :       56344 :               else if (TREE_TYPE (parm) != char_type_node
   32850                 :       56344 :                        || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
   32851                 :             :                 ok = false;
   32852                 :             :             }
   32853                 :          33 :           else if (num_parms == 2 && cxx_dialect >= cxx14)
   32854                 :             :             {
   32855                 :          33 :               tree parm_type = TREE_VEC_ELT (parameter_list, 0);
   32856                 :          33 :               tree type = INNERMOST_TEMPLATE_PARMS (parm_type);
   32857                 :          33 :               tree parm_list = TREE_VEC_ELT (parameter_list, 1);
   32858                 :          33 :               tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
   32859                 :          33 :               if (TREE_CODE (parm) != PARM_DECL
   32860                 :          30 :                   || TREE_TYPE (parm) != TREE_TYPE (type)
   32861                 :          63 :                   || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
   32862                 :             :                 ok = false;
   32863                 :             :               else
   32864                 :             :                 /* http://cplusplus.github.io/EWG/ewg-active.html#66  */
   32865                 :          30 :                 pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
   32866                 :             :                          "ISO C++ did not adopt string literal operator templa"
   32867                 :             :                          "tes taking an argument pack of characters");
   32868                 :             :             }
   32869                 :             :           else
   32870                 :             :             ok = false;
   32871                 :             :         }
   32872                 :          30 :       if (!ok)
   32873                 :             :         {
   32874                 :          18 :           if (cxx_dialect > cxx17)
   32875                 :           8 :             error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
   32876                 :             :                       "template %qD has invalid parameter list; expected "
   32877                 :             :                       "non-type template parameter pack %<<char...>%> or "
   32878                 :             :                       "single non-type parameter of class type",
   32879                 :             :                       decl);
   32880                 :             :           else
   32881                 :          10 :             error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
   32882                 :             :                       "template %qD has invalid parameter list; expected "
   32883                 :             :                       "non-type template parameter pack %<<char...>%>",
   32884                 :             :                       decl);
   32885                 :             :         }
   32886                 :             :     }
   32887                 :             : 
   32888                 :             :   /* Register member declarations.  */
   32889                 :    74681347 :   if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
   32890                 :    16666818 :     finish_member_declaration (decl);
   32891                 :             :   /* If DECL is a function template, we must return to parse it later.
   32892                 :             :      (Even though there is no definition, there might be default
   32893                 :             :      arguments that need handling.)  */
   32894                 :    19600315 :   if (member_p && decl
   32895                 :    93792330 :       && DECL_DECLARES_FUNCTION_P (decl))
   32896                 :    16582025 :     vec_safe_push (unparsed_funs_with_definitions, decl);
   32897                 :    74681347 : }
   32898                 :             : 
   32899                 :             : /* Parse a template introduction header for a template-declaration.  Returns
   32900                 :             :    false if tentative parse fails.  */
   32901                 :             : 
   32902                 :             : static bool
   32903                 :    61215339 : cp_parser_template_introduction (cp_parser* parser, bool member_p)
   32904                 :             : {
   32905                 :    61215339 :   cp_parser_parse_tentatively (parser);
   32906                 :             : 
   32907                 :    61215339 :   tree saved_scope = parser->scope;
   32908                 :    61215339 :   tree saved_object_scope = parser->object_scope;
   32909                 :    61215339 :   tree saved_qualifying_scope = parser->qualifying_scope;
   32910                 :    61215339 :   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   32911                 :             : 
   32912                 :    61215339 :   cp_token *start_token = cp_lexer_peek_token (parser->lexer);
   32913                 :             : 
   32914                 :             :   /* In classes don't parse valid unnamed bitfields as invalid
   32915                 :             :      template introductions.  */
   32916                 :    61215339 :   if (member_p)
   32917                 :    35757708 :     parser->colon_corrects_to_scope_p = false;
   32918                 :             : 
   32919                 :             :   /* Look for the optional `::' operator.  */
   32920                 :    61215339 :   cp_parser_global_scope_opt (parser,
   32921                 :             :                               /*current_scope_valid_p=*/false);
   32922                 :             :   /* Look for the nested-name-specifier.  */
   32923                 :    61215339 :   cp_parser_nested_name_specifier_opt (parser,
   32924                 :             :                                        /*typename_keyword_p=*/false,
   32925                 :             :                                        /*check_dependency_p=*/true,
   32926                 :             :                                        /*type_p=*/false,
   32927                 :             :                                        /*is_declaration=*/false);
   32928                 :             : 
   32929                 :    61215338 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   32930                 :    61215338 :   tree concept_name = cp_parser_identifier (parser);
   32931                 :             : 
   32932                 :             :   /* Look up the concept for which we will be matching
   32933                 :             :      template parameters.  */
   32934                 :    61215338 :   tree tmpl_decl = cp_parser_lookup_name_simple (parser, concept_name,
   32935                 :             :                                                  token->location);
   32936                 :    61215338 :   parser->scope = saved_scope;
   32937                 :    61215338 :   parser->object_scope = saved_object_scope;
   32938                 :    61215338 :   parser->qualifying_scope = saved_qualifying_scope;
   32939                 :    61215338 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   32940                 :             : 
   32941                 :    61215338 :   if (concept_name == error_mark_node
   32942                 :    61215338 :       || (seen_error () && !concept_definition_p (tmpl_decl)))
   32943                 :   113266346 :     cp_parser_simulate_error (parser);
   32944                 :             : 
   32945                 :             :   /* Look for opening brace for introduction.  */
   32946                 :    61215338 :   matching_braces braces;
   32947                 :    61215338 :   braces.require_open (parser);
   32948                 :    61215338 :   location_t open_loc = input_location;
   32949                 :             : 
   32950                 :    61215338 :   if (!cp_parser_parse_definitely (parser))
   32951                 :             :     return false;
   32952                 :             : 
   32953                 :          40 :   push_deferring_access_checks (dk_deferred);
   32954                 :             : 
   32955                 :             :   /* Build vector of placeholder parameters and grab
   32956                 :             :      matching identifiers.  */
   32957                 :          40 :   tree introduction_list = cp_parser_introduction_list (parser);
   32958                 :             : 
   32959                 :             :   /* Look for closing brace for introduction.  */
   32960                 :          40 :   if (!braces.require_close (parser))
   32961                 :             :     return true;
   32962                 :             : 
   32963                 :             :   /* The introduction-list shall not be empty.  */
   32964                 :          40 :   int nargs = TREE_VEC_LENGTH (introduction_list);
   32965                 :          40 :   if (nargs == 0)
   32966                 :             :     {
   32967                 :             :       /* In cp_parser_introduction_list we have already issued an error.  */
   32968                 :             :       return true;
   32969                 :             :     }
   32970                 :             : 
   32971                 :          39 :   if (tmpl_decl == error_mark_node)
   32972                 :             :     {
   32973                 :           0 :       cp_parser_name_lookup_error (parser, concept_name, tmpl_decl, NLE_NULL,
   32974                 :             :                                    token->location);
   32975                 :           0 :       return true;
   32976                 :             :     }
   32977                 :             : 
   32978                 :             :   /* Build and associate the constraint.  */
   32979                 :          39 :   location_t introduction_loc = make_location (open_loc,
   32980                 :             :                                                start_token->location,
   32981                 :             :                                                parser->lexer);
   32982                 :          39 :   tree parms = finish_template_introduction (tmpl_decl,
   32983                 :             :                                              introduction_list,
   32984                 :             :                                              introduction_loc);
   32985                 :          39 :   if (parms && parms != error_mark_node)
   32986                 :             :     {
   32987                 :          35 :       if (!flag_concepts_ts)
   32988                 :           0 :         pedwarn (introduction_loc, 0, "template-introductions"
   32989                 :             :                  " are not part of C++20 concepts; use %qs to enable",
   32990                 :             :                  "-fconcepts-ts");
   32991                 :             : 
   32992                 :          35 :       cp_parser_template_declaration_after_parameters (parser, parms,
   32993                 :             :                                                        member_p);
   32994                 :          35 :       return true;
   32995                 :             :     }
   32996                 :             : 
   32997                 :             :   if (parms == NULL_TREE)
   32998                 :           0 :     error_at (token->location, "no matching concept for template-introduction");
   32999                 :             : 
   33000                 :             :   return true;
   33001                 :             : }
   33002                 :             : 
   33003                 :             : /* Parse a normal template-declaration following the template keyword.  */
   33004                 :             : 
   33005                 :             : static void
   33006                 :    74681329 : cp_parser_explicit_template_declaration (cp_parser* parser, bool member_p)
   33007                 :             : {
   33008                 :    74681329 :   tree parameter_list;
   33009                 :    74681329 :   bool need_lang_pop;
   33010                 :    74681329 :   location_t location = input_location;
   33011                 :             : 
   33012                 :             :   /* Look for the `<' token.  */
   33013                 :    74681329 :   if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
   33014                 :             :     return;
   33015                 :    74681325 :   if (at_class_scope_p () && current_function_decl)
   33016                 :             :     {
   33017                 :             :       /* 14.5.2.2 [temp.mem]
   33018                 :             : 
   33019                 :             :          A local class shall not have member templates.  */
   33020                 :           4 :       error_at (location,
   33021                 :             :                 "invalid declaration of member template in local class");
   33022                 :           4 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   33023                 :           4 :       return;
   33024                 :             :     }
   33025                 :             :   /* [temp]
   33026                 :             : 
   33027                 :             :      A template ... shall not have C linkage.  */
   33028                 :    74681321 :   if (current_lang_name == lang_name_c)
   33029                 :             :     {
   33030                 :          24 :       error_at (location, "template with C linkage");
   33031                 :          24 :       maybe_show_extern_c_location ();
   33032                 :             :       /* Give it C++ linkage to avoid confusing other parts of the
   33033                 :             :          front end.  */
   33034                 :          24 :       push_lang_context (lang_name_cplusplus);
   33035                 :          24 :       need_lang_pop = true;
   33036                 :             :     }
   33037                 :             :   else
   33038                 :             :     need_lang_pop = false;
   33039                 :             : 
   33040                 :             :   /* We cannot perform access checks on the template parameter
   33041                 :             :      declarations until we know what is being declared, just as we
   33042                 :             :      cannot check the decl-specifier list.  */
   33043                 :    74681321 :   push_deferring_access_checks (dk_deferred);
   33044                 :             : 
   33045                 :             :   /* If the next token is `>', then we have an invalid
   33046                 :             :      specialization.  Rather than complain about an invalid template
   33047                 :             :      parameter, issue an error message here.  */
   33048                 :    74681321 :   if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
   33049                 :             :     {
   33050                 :           8 :       cp_parser_error (parser, "invalid explicit specialization");
   33051                 :           8 :       begin_specialization ();
   33052                 :           8 :       parameter_list = NULL_TREE;
   33053                 :             :     }
   33054                 :             :   else
   33055                 :             :     {
   33056                 :             :       /* Parse the template parameters.  */
   33057                 :    74681313 :       parameter_list = cp_parser_template_parameter_list (parser);
   33058                 :             :     }
   33059                 :             : 
   33060                 :             :   /* Look for the `>'.  */
   33061                 :    74681321 :   cp_parser_require_end_of_template_parameter_list (parser);
   33062                 :             : 
   33063                 :             :   /* Manage template requirements */
   33064                 :    74681321 :   if (flag_concepts)
   33065                 :             :   {
   33066                 :    18876733 :     tree reqs = get_shorthand_constraints (current_template_parms);
   33067                 :    18876733 :     if (tree treqs = cp_parser_requires_clause_opt (parser, false))
   33068                 :     1174760 :       reqs = combine_constraint_expressions (reqs, treqs);
   33069                 :    18876733 :     TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
   33070                 :             :   }
   33071                 :             : 
   33072                 :    74681321 :   cp_parser_template_declaration_after_parameters (parser, parameter_list,
   33073                 :             :                                                    member_p);
   33074                 :             : 
   33075                 :             :   /* For the erroneous case of a template with C linkage, we pushed an
   33076                 :             :      implicit C++ linkage scope; exit that scope now.  */
   33077                 :    74681312 :   if (need_lang_pop)
   33078                 :          24 :     pop_lang_context ();
   33079                 :             : }
   33080                 :             : 
   33081                 :             : /* Parse a template-declaration, assuming that the `export' (and
   33082                 :             :    `extern') keywords, if present, has already been scanned.  MEMBER_P
   33083                 :             :    is as for cp_parser_template_declaration.  */
   33084                 :             : 
   33085                 :             : static bool
   33086                 :   278614345 : cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
   33087                 :             : {
   33088                 :   278614345 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
   33089                 :             :     {
   33090                 :    74681329 :       cp_lexer_consume_token (parser->lexer);
   33091                 :    74681329 :       cp_parser_explicit_template_declaration (parser, member_p);
   33092                 :    74681329 :       return true;
   33093                 :             :     }
   33094                 :   203933016 :   else if (flag_concepts)
   33095                 :    61215339 :     return cp_parser_template_introduction (parser, member_p);
   33096                 :             : 
   33097                 :             :   return false;
   33098                 :             : }
   33099                 :             : 
   33100                 :             : /* Perform the deferred access checks from a template-parameter-list.
   33101                 :             :    CHECKS is a TREE_LIST of access checks, as returned by
   33102                 :             :    get_deferred_access_checks.  */
   33103                 :             : 
   33104                 :             : static void
   33105                 :   118432447 : cp_parser_perform_template_parameter_access_checks (vec<deferred_access_check, va_gc> *checks)
   33106                 :             : {
   33107                 :   118432447 :   ++processing_template_parmlist;
   33108                 :   118432447 :   perform_access_checks (checks, tf_warning_or_error);
   33109                 :   118432447 :   --processing_template_parmlist;
   33110                 :   118432447 : }
   33111                 :             : 
   33112                 :             : /* Parse a `decl-specifier-seq [opt] init-declarator [opt] ;' or
   33113                 :             :    `function-definition' sequence that follows a template header.
   33114                 :             :    If MEMBER_P is true, this declaration appears in a class scope.
   33115                 :             : 
   33116                 :             :    Returns the DECL for the declared entity.  If FRIEND_P is non-NULL,
   33117                 :             :    *FRIEND_P is set to TRUE iff the declaration is a friend.  */
   33118                 :             : 
   33119                 :             : static tree
   33120                 :    73548893 : cp_parser_single_declaration (cp_parser* parser,
   33121                 :             :                               vec<deferred_access_check, va_gc> *checks,
   33122                 :             :                               bool member_p,
   33123                 :             :                               bool explicit_specialization_p,
   33124                 :             :                               bool* friend_p)
   33125                 :             : {
   33126                 :    73548893 :   int declares_class_or_enum;
   33127                 :    73548893 :   tree decl = NULL_TREE;
   33128                 :    73548893 :   cp_decl_specifier_seq decl_specifiers;
   33129                 :    73548893 :   bool function_definition_p = false;
   33130                 :    73548893 :   cp_token *decl_spec_token_start;
   33131                 :             : 
   33132                 :             :   /* This function is only used when processing a template
   33133                 :             :      declaration.  */
   33134                 :    73548893 :   gcc_assert (innermost_scope_kind () == sk_template_parms
   33135                 :             :               || innermost_scope_kind () == sk_template_spec);
   33136                 :             : 
   33137                 :             :   /* Defer access checks until we know what is being declared.  */
   33138                 :    73548893 :   push_deferring_access_checks (dk_deferred);
   33139                 :             : 
   33140                 :             :   /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
   33141                 :             :      alternative.  */
   33142                 :    73548893 :   decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
   33143                 :    73548893 :   cp_parser_decl_specifier_seq (parser,
   33144                 :             :                                 (CP_PARSER_FLAGS_OPTIONAL
   33145                 :             :                                  | CP_PARSER_FLAGS_TYPENAME_OPTIONAL),
   33146                 :             :                                 &decl_specifiers,
   33147                 :             :                                 &declares_class_or_enum);
   33148                 :             : 
   33149                 :    73548884 :   cp_omp_declare_simd_data odsd;
   33150                 :    73548884 :   if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
   33151                 :        3288 :     cp_parser_handle_directive_omp_attributes (parser,
   33152                 :             :                                                &decl_specifiers.attributes,
   33153                 :             :                                                &odsd, true);
   33154                 :             : 
   33155                 :    73548884 :   if (friend_p)
   33156                 :    68809739 :     *friend_p = cp_parser_friend_p (&decl_specifiers);
   33157                 :             : 
   33158                 :             :   /* There are no template typedefs.  */
   33159                 :    73548884 :   if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
   33160                 :             :     {
   33161                 :           4 :       error_at (decl_spec_token_start->location,
   33162                 :             :                 "template declaration of %<typedef%>");
   33163                 :           4 :       decl = error_mark_node;
   33164                 :             :     }
   33165                 :             : 
   33166                 :             :   /* Gather up the access checks that occurred the
   33167                 :             :      decl-specifier-seq.  */
   33168                 :    73548884 :   stop_deferring_access_checks ();
   33169                 :             : 
   33170                 :             :   /* Check for the declaration of a template class.  */
   33171                 :    73548884 :   if (declares_class_or_enum)
   33172                 :             :     {
   33173                 :    43280913 :       if (cp_parser_declares_only_class_p (parser)
   33174                 :         102 :           || (declares_class_or_enum & 2))
   33175                 :             :         {
   33176                 :    21640374 :           decl = shadow_tag (&decl_specifiers);
   33177                 :             : 
   33178                 :             :           /* In this case:
   33179                 :             : 
   33180                 :             :                struct C {
   33181                 :             :                  friend template <typename T> struct A<T>::B;
   33182                 :             :                };
   33183                 :             : 
   33184                 :             :              A<T>::B will be represented by a TYPENAME_TYPE, and
   33185                 :             :              therefore not recognized by shadow_tag.  */
   33186                 :    21640374 :           if (friend_p && *friend_p
   33187                 :      530036 :               && !decl
   33188                 :          93 :               && decl_specifiers.type
   33189                 :          93 :               && TYPE_P (decl_specifiers.type))
   33190                 :    21110431 :             decl = decl_specifiers.type;
   33191                 :             : 
   33192                 :    21640374 :           if (decl && decl != error_mark_node)
   33193                 :    21638482 :             decl = TYPE_NAME (decl);
   33194                 :             :           else
   33195                 :        1892 :             decl = error_mark_node;
   33196                 :             : 
   33197                 :             :           /* If this is a declaration, but not a definition, associate
   33198                 :             :              any constraints with the type declaration. Constraints
   33199                 :             :              are associated with definitions in cp_parser_class_specifier.  */
   33200                 :    21640374 :           if (declares_class_or_enum == 1)
   33201                 :     3413565 :             associate_classtype_constraints (TREE_TYPE (decl));
   33202                 :             : 
   33203                 :             :           /* Perform access checks for template parameters.  */
   33204                 :    21640374 :           cp_parser_perform_template_parameter_access_checks (checks);
   33205                 :             : 
   33206                 :             :           /* Give a helpful diagnostic for
   33207                 :             :                template <class T> struct A { } a;
   33208                 :             :              if we aren't already recovering from an error.  */
   33209                 :    95189294 :           if (!cp_parser_declares_only_class_p (parser)
   33210                 :          39 :               && !seen_error ())
   33211                 :             :             {
   33212                 :           3 :               error_at (cp_lexer_peek_token (parser->lexer)->location,
   33213                 :             :                         "a class template declaration must not declare "
   33214                 :             :                         "anything else");
   33215                 :           3 :               cp_parser_skip_to_end_of_block_or_statement (parser);
   33216                 :           3 :               goto out;
   33217                 :             :             }
   33218                 :             :         }
   33219                 :             :     }
   33220                 :             : 
   33221                 :             :   /* Complain about missing 'typename' or other invalid type names.  */
   33222                 :    73548881 :   if (!decl_specifiers.any_type_specifiers_p
   33223                 :    73548881 :       && cp_parser_parse_and_diagnose_invalid_type_name (parser))
   33224                 :             :     {
   33225                 :             :       /* cp_parser_parse_and_diagnose_invalid_type_name calls
   33226                 :             :          cp_parser_skip_to_end_of_block_or_statement, so don't try to parse
   33227                 :             :          the rest of this declaration.  */
   33228                 :          55 :       decl = error_mark_node;
   33229                 :          55 :       goto out;
   33230                 :             :     }
   33231                 :             : 
   33232                 :             :   /* If it's not a template class, try for a template function.  If
   33233                 :             :      the next token is a `;', then this declaration does not declare
   33234                 :             :      anything.  But, if there were errors in the decl-specifiers, then
   33235                 :             :      the error might well have come from an attempted class-specifier.
   33236                 :             :      In that case, there's no need to warn about a missing declarator.  */
   33237                 :    73548826 :   if (!decl
   33238                 :    73548826 :       && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
   33239                 :          45 :           || decl_specifiers.type != error_mark_node))
   33240                 :             :     {
   33241                 :    51908455 :       int flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
   33242                 :             :       /* We don't delay parsing for friends, though CWG 2510 may change
   33243                 :             :          that.  */
   33244                 :    51908455 :       if (member_p && !(friend_p && *friend_p))
   33245                 :    51908455 :         flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT;
   33246                 :    51908455 :       decl = cp_parser_init_declarator (parser,
   33247                 :             :                                         flags,
   33248                 :             :                                         &decl_specifiers,
   33249                 :             :                                         checks,
   33250                 :             :                                         /*function_definition_allowed_p=*/true,
   33251                 :             :                                         member_p,
   33252                 :             :                                         declares_class_or_enum,
   33253                 :             :                                         &function_definition_p,
   33254                 :             :                                         NULL, NULL, NULL);
   33255                 :             : 
   33256                 :             :     /* 7.1.1-1 [dcl.stc]
   33257                 :             : 
   33258                 :             :        A storage-class-specifier shall not be specified in an explicit
   33259                 :             :        specialization...  */
   33260                 :    51908455 :     if (decl
   33261                 :    51908455 :         && explicit_specialization_p
   33262                 :      826330 :         && decl_specifiers.storage_class != sc_none)
   33263                 :             :       {
   33264                 :           8 :         error_at (decl_spec_token_start->location,
   33265                 :             :                   "explicit template specialization cannot have a storage class");
   33266                 :           8 :         decl = error_mark_node;
   33267                 :             :       }
   33268                 :             : 
   33269                 :    51908455 :     if (decl && VAR_P (decl))
   33270                 :     2769542 :       check_template_variable (decl);
   33271                 :             :     }
   33272                 :             : 
   33273                 :             :   /* Look for a trailing `;' after the declaration.  */
   33274                 :    73548826 :   if (!function_definition_p
   33275                 :    73548826 :       && (decl == error_mark_node
   33276                 :    33639026 :           || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)))
   33277                 :        2403 :     cp_parser_skip_to_end_of_block_or_statement (parser);
   33278                 :             : 
   33279                 :    73548884 :  out:
   33280                 :    73548884 :   pop_deferring_access_checks ();
   33281                 :             : 
   33282                 :             :   /* Clear any current qualification; whatever comes next is the start
   33283                 :             :      of something new.  */
   33284                 :    73548884 :   parser->scope = NULL_TREE;
   33285                 :    73548884 :   parser->qualifying_scope = NULL_TREE;
   33286                 :    73548884 :   parser->object_scope = NULL_TREE;
   33287                 :             : 
   33288                 :    73548884 :   cp_finalize_omp_declare_simd (parser, &odsd);
   33289                 :             : 
   33290                 :    73548884 :   return decl;
   33291                 :             : }
   33292                 :             : 
   33293                 :             : /* Parse a cast-expression that is not the operand of a unary "&".  */
   33294                 :             : 
   33295                 :             : static cp_expr
   33296                 :   112309094 : cp_parser_simple_cast_expression (cp_parser *parser)
   33297                 :             : {
   33298                 :   112309094 :   return cp_parser_cast_expression (parser, /*address_p=*/false,
   33299                 :   112309094 :                                     /*cast_p=*/false, /*decltype*/false, NULL);
   33300                 :             : }
   33301                 :             : 
   33302                 :             : /* Parse a functional cast to TYPE.  Returns an expression
   33303                 :             :    representing the cast.  */
   33304                 :             : 
   33305                 :             : static cp_expr
   33306                 :    37958502 : cp_parser_functional_cast (cp_parser* parser, tree type)
   33307                 :             : {
   33308                 :    37958502 :   vec<tree, va_gc> *vec;
   33309                 :    37958502 :   tree expression_list;
   33310                 :    37958502 :   cp_expr cast;
   33311                 :             : 
   33312                 :    37958502 :   location_t start_loc = input_location;
   33313                 :             : 
   33314                 :    37958502 :   if (!type)
   33315                 :           0 :     type = error_mark_node;
   33316                 :             : 
   33317                 :    37958502 :   if (TREE_CODE (type) == TYPE_DECL
   33318                 :    37958502 :       && is_auto (TREE_TYPE (type)))
   33319                 :        3679 :     type = TREE_TYPE (type);
   33320                 :             : 
   33321                 :    37958502 :   if (is_auto (type)
   33322                 :      175946 :       && !AUTO_IS_DECLTYPE (type)
   33323                 :      175939 :       && !PLACEHOLDER_TYPE_CONSTRAINTS (type)
   33324                 :    38134437 :       && !CLASS_PLACEHOLDER_TEMPLATE (type))
   33325                 :             :     /* auto(x) and auto{x} need to use a level-less auto.  */
   33326                 :        3675 :     type = make_cast_auto ();
   33327                 :             : 
   33328                 :    37958502 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   33329                 :             :     {
   33330                 :     3372685 :       cp_lexer_set_source_position (parser->lexer);
   33331                 :     3372685 :       maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   33332                 :     3372685 :       expression_list = cp_parser_braced_list (parser);
   33333                 :     3372685 :       CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
   33334                 :     3372685 :       if (TREE_CODE (type) == TYPE_DECL)
   33335                 :     3235086 :         type = TREE_TYPE (type);
   33336                 :             : 
   33337                 :     3372685 :       cast = finish_compound_literal (type, expression_list,
   33338                 :             :                                       tf_warning_or_error, fcl_functional);
   33339                 :             :       /* Create a location of the form:
   33340                 :             :             type_name{i, f}
   33341                 :             :             ^~~~~~~~~~~~~~~
   33342                 :             :          with caret == start at the start of the type name,
   33343                 :             :          finishing at the closing brace.  */
   33344                 :     3372685 :       location_t combined_loc = make_location (start_loc, start_loc,
   33345                 :             :                                                parser->lexer);
   33346                 :     3372685 :       cast.set_location (combined_loc);
   33347                 :     3372685 :       return cast;
   33348                 :             :    }
   33349                 :             : 
   33350                 :             : 
   33351                 :    34585817 :   vec = cp_parser_parenthesized_expression_list (parser, non_attr,
   33352                 :             :                                                  /*cast_p=*/true,
   33353                 :             :                                                  /*allow_expansion_p=*/true,
   33354                 :             :                                                  /*non_constant_p=*/NULL);
   33355                 :    34585817 :   if (vec == NULL)
   33356                 :         613 :     expression_list = error_mark_node;
   33357                 :             :   else
   33358                 :             :     {
   33359                 :    34585204 :       expression_list = build_tree_list_vec (vec);
   33360                 :    34585204 :       release_tree_vector (vec);
   33361                 :             :     }
   33362                 :             : 
   33363                 :             :   /* Create a location of the form:
   33364                 :             :        float(i)
   33365                 :             :        ^~~~~~~~
   33366                 :             :      with caret == start at the start of the type name,
   33367                 :             :      finishing at the closing paren.  */
   33368                 :    34585817 :   location_t combined_loc = make_location (start_loc, start_loc,
   33369                 :             :                                            parser->lexer);
   33370                 :    34585817 :   cast = build_functional_cast (combined_loc, type, expression_list,
   33371                 :             :                                 tf_warning_or_error);
   33372                 :             :   
   33373                 :             :   /* [expr.const]/1: In an integral constant expression "only type
   33374                 :             :      conversions to integral or enumeration type can be used".  */
   33375                 :    34585817 :   if (TREE_CODE (type) == TYPE_DECL)
   33376                 :    34348394 :     type = TREE_TYPE (type);
   33377                 :    34585817 :   if (cast != error_mark_node
   33378                 :    34584964 :       && !cast_valid_in_integral_constant_expression_p (type)
   33379                 :    34596035 :       && cp_parser_non_integral_constant_expression (parser,
   33380                 :             :                                                      NIC_CONSTRUCTOR))
   33381                 :           1 :     return error_mark_node;
   33382                 :             : 
   33383                 :    34585816 :   return cast;
   33384                 :             : }
   33385                 :             : 
   33386                 :             : /* Save the tokens that make up the body of a member function defined
   33387                 :             :    in a class-specifier.  The DECL_SPECIFIERS and DECLARATOR have
   33388                 :             :    already been parsed.  The ATTRIBUTES are any GNU "__attribute__"
   33389                 :             :    specifiers applied to the declaration.  Returns the FUNCTION_DECL
   33390                 :             :    for the member function.  */
   33391                 :             : 
   33392                 :             : static tree
   33393                 :    61631838 : cp_parser_save_member_function_body (cp_parser* parser,
   33394                 :             :                                      cp_decl_specifier_seq *decl_specifiers,
   33395                 :             :                                      cp_declarator *declarator,
   33396                 :             :                                      tree attributes)
   33397                 :             : {
   33398                 :    61631838 :   cp_token *first;
   33399                 :    61631838 :   cp_token *last;
   33400                 :    61631838 :   tree fn;
   33401                 :    61631838 :   bool function_try_block = false;
   33402                 :             : 
   33403                 :             :   /* Create the FUNCTION_DECL.  */
   33404                 :    61631838 :   fn = grokmethod (decl_specifiers, declarator, attributes);
   33405                 :    61631838 :   cp_finalize_omp_declare_simd (parser, fn);
   33406                 :    61631838 :   cp_finalize_oacc_routine (parser, fn, true);
   33407                 :             :   /* If something went badly wrong, bail out now.  */
   33408                 :    61631838 :   if (fn == error_mark_node)
   33409                 :             :     {
   33410                 :             :       /* If there's a function-body, skip it.  */
   33411                 :         105 :       if (cp_parser_token_starts_function_definition_p
   33412                 :         105 :           (cp_lexer_peek_token (parser->lexer)))
   33413                 :         105 :         cp_parser_skip_to_end_of_block_or_statement (parser);
   33414                 :         105 :       return error_mark_node;
   33415                 :             :     }
   33416                 :             : 
   33417                 :             :   /* Remember it, if there are default args to post process.  */
   33418                 :    61631733 :   cp_parser_save_default_args (parser, fn);
   33419                 :             : 
   33420                 :             :   /* Save away the tokens that make up the body of the
   33421                 :             :      function.  */
   33422                 :    61631733 :   first = parser->lexer->next_token;
   33423                 :             : 
   33424                 :    61631733 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_RELAXED))
   33425                 :           0 :     cp_lexer_consume_token (parser->lexer);
   33426                 :    61631733 :   else if (cp_lexer_next_token_is_keyword (parser->lexer,
   33427                 :             :                                            RID_TRANSACTION_ATOMIC))
   33428                 :             :     {
   33429                 :           6 :       cp_lexer_consume_token (parser->lexer);
   33430                 :             :       /* Match cp_parser_txn_attribute_opt [[ identifier ]].  */
   33431                 :           6 :       if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)
   33432                 :           3 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE)
   33433                 :           3 :           && (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME)
   33434                 :           0 :               || cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD))
   33435                 :           3 :           && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_SQUARE)
   33436                 :           9 :           && cp_lexer_nth_token_is (parser->lexer, 5, CPP_CLOSE_SQUARE))
   33437                 :             :         {
   33438                 :           3 :           cp_lexer_consume_token (parser->lexer);
   33439                 :           3 :           cp_lexer_consume_token (parser->lexer);
   33440                 :           3 :           cp_lexer_consume_token (parser->lexer);
   33441                 :           3 :           cp_lexer_consume_token (parser->lexer);
   33442                 :           3 :           cp_lexer_consume_token (parser->lexer);
   33443                 :             :         }
   33444                 :             :       else
   33445                 :           6 :         while (cp_next_tokens_can_be_gnu_attribute_p (parser)
   33446                 :           6 :                && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
   33447                 :             :           {
   33448                 :           3 :             cp_lexer_consume_token (parser->lexer);
   33449                 :           3 :             if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
   33450                 :             :               break;
   33451                 :             :           }
   33452                 :             :     }
   33453                 :             : 
   33454                 :             :   /* Handle function try blocks.  */
   33455                 :    61631733 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
   33456                 :             :     {
   33457                 :         127 :       cp_lexer_consume_token (parser->lexer);
   33458                 :         127 :       function_try_block = true;
   33459                 :             :     }
   33460                 :             :   /* We can have braced-init-list mem-initializers before the fn body.  */
   33461                 :    61631733 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   33462                 :             :     {
   33463                 :    12002507 :       cp_lexer_consume_token (parser->lexer);
   33464                 :    41622377 :       while (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
   33465                 :             :         {
   33466                 :             :           /* cache_group will stop after an un-nested { } pair, too.  */
   33467                 :    17617378 :           if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
   33468                 :             :             break;
   33469                 :             : 
   33470                 :             :           /* variadic mem-inits have ... after the ')'.  */
   33471                 :    17617363 :           if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   33472                 :          31 :             cp_lexer_consume_token (parser->lexer);
   33473                 :             :         }
   33474                 :             :     }
   33475                 :    61631733 :   cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
   33476                 :             :   /* Handle function try blocks.  */
   33477                 :    61631733 :   if (function_try_block)
   33478                 :         268 :     while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
   33479                 :         141 :       cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
   33480                 :    61631733 :   last = parser->lexer->next_token;
   33481                 :             : 
   33482                 :             :   /* Save away the inline definition; we will process it when the
   33483                 :             :      class is complete.  */
   33484                 :    61631733 :   DECL_PENDING_INLINE_INFO (fn) = cp_token_cache_new (first, last);
   33485                 :    61631733 :   DECL_PENDING_INLINE_P (fn) = 1;
   33486                 :             : 
   33487                 :             :   /* We need to know that this was defined in the class, so that
   33488                 :             :      friend templates are handled correctly.  */
   33489                 :    61631733 :   DECL_INITIALIZED_IN_CLASS_P (fn) = 1;
   33490                 :             : 
   33491                 :             :   /* Add FN to the queue of functions to be parsed later.  */
   33492                 :    61631733 :   vec_safe_push (unparsed_funs_with_definitions, fn);
   33493                 :             : 
   33494                 :    61631733 :   return fn;
   33495                 :             : }
   33496                 :             : 
   33497                 :             : /* Save the tokens that make up the in-class initializer for a non-static
   33498                 :             :    data member.  Returns a DEFERRED_PARSE.  */
   33499                 :             : 
   33500                 :             : static tree
   33501                 :      856550 : cp_parser_save_nsdmi (cp_parser* parser)
   33502                 :             : {
   33503                 :      856550 :   return cp_parser_cache_defarg (parser, /*nsdmi=*/true);
   33504                 :             : }
   33505                 :             : 
   33506                 :             : /* Parse a template-argument-list, as well as the trailing ">" (but
   33507                 :             :    not the opening "<").  See cp_parser_template_argument_list for the
   33508                 :             :    return value.  */
   33509                 :             : 
   33510                 :             : static tree
   33511                 :   179876492 : cp_parser_enclosed_template_argument_list (cp_parser* parser)
   33512                 :             : {
   33513                 :   179876492 :   tree arguments;
   33514                 :   179876492 :   tree saved_scope;
   33515                 :   179876492 :   tree saved_qualifying_scope;
   33516                 :   179876492 :   tree saved_object_scope;
   33517                 :   179876492 :   bool saved_greater_than_is_operator_p;
   33518                 :             : 
   33519                 :             :   /* [temp.names]
   33520                 :             : 
   33521                 :             :      When parsing a template-id, the first non-nested `>' is taken as
   33522                 :             :      the end of the template-argument-list rather than a greater-than
   33523                 :             :      operator.  */
   33524                 :   179876492 :   saved_greater_than_is_operator_p
   33525                 :   179876492 :     = parser->greater_than_is_operator_p;
   33526                 :   179876492 :   parser->greater_than_is_operator_p = false;
   33527                 :             :   /* Parsing the argument list may modify SCOPE, so we save it
   33528                 :             :      here.  */
   33529                 :   179876492 :   saved_scope = parser->scope;
   33530                 :   179876492 :   saved_qualifying_scope = parser->qualifying_scope;
   33531                 :   179876492 :   saved_object_scope = parser->object_scope;
   33532                 :             :   /* We need to evaluate the template arguments, even though this
   33533                 :             :      template-id may be nested within a "sizeof".  */
   33534                 :   179876492 :   cp_evaluated ev;
   33535                 :             :   /* Parse the template-argument-list itself.  */
   33536                 :   179876492 :   if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER)
   33537                 :             :       || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT)
   33538                 :             :       || cp_lexer_next_token_is (parser->lexer, CPP_GREATER_EQ)
   33539                 :             :       || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT_EQ))
   33540                 :             :     {
   33541                 :      472188 :       arguments = make_tree_vec (0);
   33542                 :      472188 :       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (arguments, 0);
   33543                 :             :     }
   33544                 :             :   else
   33545                 :   179404304 :     arguments = cp_parser_template_argument_list (parser);
   33546                 :             :   /* Look for the `>' that ends the template-argument-list. If we find
   33547                 :             :      a '>>' instead, it's probably just a typo.  */
   33548                 :   179876492 :   if (cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
   33549                 :             :     {
   33550                 :    11151798 :       if (cxx_dialect != cxx98)
   33551                 :             :         {
   33552                 :             :           /* In C++0x, a `>>' in a template argument list or cast
   33553                 :             :              expression is considered to be two separate `>'
   33554                 :             :              tokens. So, change the current token to a `>', but don't
   33555                 :             :              consume it: it will be consumed later when the outer
   33556                 :             :              template argument list (or cast expression) is parsed.
   33557                 :             :              Note that this replacement of `>' for `>>' is necessary
   33558                 :             :              even if we are parsing tentatively: in the tentative
   33559                 :             :              case, after calling
   33560                 :             :              cp_parser_enclosed_template_argument_list we will always
   33561                 :             :              throw away all of the template arguments and the first
   33562                 :             :              closing `>', either because the template argument list
   33563                 :             :              was erroneous or because we are replacing those tokens
   33564                 :             :              with a CPP_TEMPLATE_ID token.  The second `>' (which will
   33565                 :             :              not have been thrown away) is needed either to close an
   33566                 :             :              outer template argument list or to complete a new-style
   33567                 :             :              cast.  */
   33568                 :    11151790 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   33569                 :    11151790 :           token->type = CPP_GREATER;
   33570                 :             :         }
   33571                 :           8 :       else if (!saved_greater_than_is_operator_p)
   33572                 :             :         {
   33573                 :             :           /* If we're in a nested template argument list, the '>>' has
   33574                 :             :             to be a typo for '> >'. We emit the error message, but we
   33575                 :             :             continue parsing and we push a '>' as next token, so that
   33576                 :             :             the argument list will be parsed correctly.  Note that the
   33577                 :             :             global source location is still on the token before the
   33578                 :             :             '>>', so we need to say explicitly where we want it.  */
   33579                 :           6 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   33580                 :           6 :           gcc_rich_location richloc (token->location);
   33581                 :           6 :           richloc.add_fixit_replace ("> >");
   33582                 :           6 :           error_at (&richloc, "%<>>%> should be %<> >%> "
   33583                 :             :                     "within a nested template argument list");
   33584                 :             : 
   33585                 :           6 :           token->type = CPP_GREATER;
   33586                 :           6 :         }
   33587                 :             :       else
   33588                 :             :         {
   33589                 :             :           /* If this is not a nested template argument list, the '>>'
   33590                 :             :             is a typo for '>'. Emit an error message and continue.
   33591                 :             :             Same deal about the token location, but here we can get it
   33592                 :             :             right by consuming the '>>' before issuing the diagnostic.  */
   33593                 :           2 :           cp_token *token = cp_lexer_consume_token (parser->lexer);
   33594                 :           2 :           error_at (token->location,
   33595                 :             :                     "spurious %<>>%>, use %<>%> to terminate "
   33596                 :             :                     "a template argument list");
   33597                 :             :         }
   33598                 :             :     }
   33599                 :             :   /* Similarly for >>= and >=.  */
   33600                 :   168724694 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER_EQ)
   33601                 :   168724694 :            || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT_EQ))
   33602                 :             :     {
   33603                 :          16 :       cp_token *token = cp_lexer_consume_token (parser->lexer);
   33604                 :          16 :       gcc_rich_location richloc (token->location);
   33605                 :          16 :       enum cpp_ttype new_type;
   33606                 :          16 :       const char *replacement;
   33607                 :          16 :       if (token->type == CPP_GREATER_EQ)
   33608                 :             :         {
   33609                 :             :           replacement = "> =";
   33610                 :             :           new_type = CPP_EQ;
   33611                 :             :         }
   33612                 :           8 :       else if (!saved_greater_than_is_operator_p)
   33613                 :             :         {
   33614                 :           4 :           if (cxx_dialect != cxx98)
   33615                 :             :             replacement = ">> =";
   33616                 :             :           else
   33617                 :           1 :             replacement = "> > =";
   33618                 :             :           new_type = CPP_GREATER;
   33619                 :             :         }
   33620                 :             :       else
   33621                 :             :         {
   33622                 :             :           replacement = "> >=";
   33623                 :             :           new_type = CPP_GREATER_EQ;
   33624                 :             :         }
   33625                 :          16 :       richloc.add_fixit_replace (replacement);
   33626                 :          16 :       error_at (&richloc, "%qs should be %qs to terminate a template "
   33627                 :             :                 "argument list",
   33628                 :          16 :                 cpp_type2name (token->type, token->flags), replacement);
   33629                 :          16 :       token->type = new_type;
   33630                 :          16 :     }
   33631                 :             :   else
   33632                 :   168724678 :     cp_parser_require_end_of_template_parameter_list (parser);
   33633                 :             :   /* The `>' token might be a greater-than operator again now.  */
   33634                 :   179876492 :   parser->greater_than_is_operator_p
   33635                 :   179876492 :     = saved_greater_than_is_operator_p;
   33636                 :             :   /* Restore the SAVED_SCOPE.  */
   33637                 :   179876492 :   parser->scope = saved_scope;
   33638                 :   179876492 :   parser->qualifying_scope = saved_qualifying_scope;
   33639                 :   179876492 :   parser->object_scope = saved_object_scope;
   33640                 :             : 
   33641                 :   179876492 :   return arguments;
   33642                 :   179876492 : }
   33643                 :             : 
   33644                 :             : /* MEMBER_FUNCTION is a member function, or a friend.  If default
   33645                 :             :    arguments, or the body of the function have not yet been parsed,
   33646                 :             :    parse them now.  */
   33647                 :             : 
   33648                 :             : static void
   33649                 :    78213935 : cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
   33650                 :             : {
   33651                 :    78213935 :   auto_timevar tv (TV_PARSE_INMETH);
   33652                 :             : 
   33653                 :             :   /* If this member is a template, get the underlying
   33654                 :             :      FUNCTION_DECL.  */
   33655                 :    78213935 :   if (DECL_FUNCTION_TEMPLATE_P (member_function))
   33656                 :             :     member_function = DECL_TEMPLATE_RESULT (member_function);
   33657                 :             : 
   33658                 :             :   /* There should not be any class definitions in progress at this
   33659                 :             :      point; the bodies of members are only parsed outside of all class
   33660                 :             :      definitions.  */
   33661                 :    78213935 :   gcc_assert (parser->num_classes_being_defined == 0);
   33662                 :             :   /* While we're parsing the member functions we might encounter more
   33663                 :             :      classes.  We want to handle them right away, but we don't want
   33664                 :             :      them getting mixed up with functions that are currently in the
   33665                 :             :      queue.  */
   33666                 :    78213935 :   push_unparsed_function_queues (parser);
   33667                 :             : 
   33668                 :             :   /* Make sure that any template parameters are in scope.  */
   33669                 :    78213935 :   maybe_begin_member_template_processing (member_function);
   33670                 :             : 
   33671                 :             :   /* If the body of the function has not yet been parsed, parse it
   33672                 :             :      now.  Except if the tokens have been purged (PR c++/39751).  */
   33673                 :    78213935 :   if (DECL_PENDING_INLINE_P (member_function)
   33674                 :    78213935 :       && !DECL_PENDING_INLINE_INFO (member_function)->first->purged_p)
   33675                 :             :     {
   33676                 :    61631926 :       tree function_scope;
   33677                 :    61631926 :       cp_token_cache *tokens;
   33678                 :             : 
   33679                 :             :       /* The function is no longer pending; we are processing it.  */
   33680                 :    61631926 :       tokens = DECL_PENDING_INLINE_INFO (member_function);
   33681                 :    61631926 :       DECL_PENDING_INLINE_INFO (member_function) = NULL;
   33682                 :    61631926 :       DECL_PENDING_INLINE_P (member_function) = 0;
   33683                 :             : 
   33684                 :             :       /* If this is a local class, enter the scope of the containing
   33685                 :             :          function.  */
   33686                 :    61631926 :       function_scope = current_function_decl;
   33687                 :    61631926 :       if (function_scope)
   33688                 :      350594 :         push_function_context ();
   33689                 :             : 
   33690                 :             :       /* Push the body of the function onto the lexer stack.  */
   33691                 :    61631926 :       cp_parser_push_lexer_for_tokens (parser, tokens);
   33692                 :             : 
   33693                 :             :       /* Let the front end know that we going to be defining this
   33694                 :             :          function.  */
   33695                 :    61631926 :       start_preparsed_function (member_function, NULL_TREE,
   33696                 :             :                                 SF_PRE_PARSED | SF_INCLASS_INLINE);
   33697                 :             : 
   33698                 :             :       /* #pragma omp declare reduction needs special parsing.  */
   33699                 :    61631926 :       if (DECL_OMP_DECLARE_REDUCTION_P (member_function))
   33700                 :             :         {
   33701                 :         234 :           parser->lexer->in_pragma = true;
   33702                 :         234 :           cp_parser_omp_declare_reduction_exprs (member_function, parser);
   33703                 :         234 :           finish_function (/*inline_p=*/true);
   33704                 :         234 :           cp_check_omp_declare_reduction (member_function);
   33705                 :             :         }
   33706                 :             :       else
   33707                 :             :         /* Now, parse the body of the function.  */
   33708                 :    61631692 :         cp_parser_function_definition_after_declarator (parser,
   33709                 :             :                                                         /*inline_p=*/true);
   33710                 :             : 
   33711                 :             :       /* Leave the scope of the containing function.  */
   33712                 :    61631926 :       if (function_scope)
   33713                 :      350594 :         pop_function_context ();
   33714                 :    61631926 :       cp_parser_pop_lexer (parser);
   33715                 :             :     }
   33716                 :             : 
   33717                 :             :   /* Remove any template parameters from the symbol table.  */
   33718                 :    78213935 :   maybe_end_member_template_processing ();
   33719                 :             : 
   33720                 :             :   /* Restore the queue.  */
   33721                 :    78213935 :   pop_unparsed_function_queues (parser);
   33722                 :    78213935 : }
   33723                 :             : 
   33724                 :             : /* If DECL contains any default args, remember it on the unparsed
   33725                 :             :    functions queue.  */
   33726                 :             : 
   33727                 :             : static void
   33728                 :    84722053 : cp_parser_save_default_args (cp_parser* parser, tree decl)
   33729                 :             : {
   33730                 :    84722053 :   tree probe;
   33731                 :             : 
   33732                 :    84722053 :   for (probe = TYPE_ARG_TYPES (TREE_TYPE (decl));
   33733                 :   331543851 :        probe;
   33734                 :   246821798 :        probe = TREE_CHAIN (probe))
   33735                 :   251447691 :     if (TREE_PURPOSE (probe))
   33736                 :             :       {
   33737                 :     4625893 :         cp_default_arg_entry entry = {current_class_type, decl};
   33738                 :     4625893 :         vec_safe_push (unparsed_funs_with_default_args, entry);
   33739                 :     4625893 :         break;
   33740                 :             :       }
   33741                 :             : 
   33742                 :             :   /* Remember if there is a noexcept-specifier to post process.  */
   33743                 :    84722053 :   tree spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
   33744                 :   113551653 :   if (UNPARSED_NOEXCEPT_SPEC_P (spec))
   33745                 :     2329635 :     vec_safe_push (unparsed_noexcepts, decl);
   33746                 :             : 
   33747                 :             :   /* Contracts are deferred.  */
   33748                 :    91543310 :   for (tree attr = DECL_ATTRIBUTES (decl); attr; attr = TREE_CHAIN (attr))
   33749                 :     6821415 :     if (cxx_contract_attribute_p (attr))
   33750                 :             :       {
   33751                 :         158 :         vec_safe_push (unparsed_contracts, decl);
   33752                 :         158 :         break;
   33753                 :             :       }
   33754                 :    84722053 : }
   33755                 :             : 
   33756                 :             : /* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
   33757                 :             :    which is either a FIELD_DECL or PARM_DECL.  Parse it and return
   33758                 :             :    the result.  For a PARM_DECL, PARMTYPE is the corresponding type
   33759                 :             :    from the parameter-type-list.  */
   33760                 :             : 
   33761                 :             : static tree
   33762                 :     6358177 : cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
   33763                 :             :                                       tree default_arg, tree parmtype)
   33764                 :             : {
   33765                 :     6358177 :   cp_token_cache *tokens;
   33766                 :     6358177 :   tree parsed_arg;
   33767                 :             : 
   33768                 :     6358177 :   if (default_arg == error_mark_node)
   33769                 :             :     return error_mark_node;
   33770                 :             : 
   33771                 :             :   /* Push the saved tokens for the default argument onto the parser's
   33772                 :             :      lexer stack.  */
   33773                 :     6358168 :   tokens = DEFPARSE_TOKENS (default_arg);
   33774                 :     6358168 :   cp_parser_push_lexer_for_tokens (parser, tokens);
   33775                 :             : 
   33776                 :     6358168 :   start_lambda_scope (decl);
   33777                 :             : 
   33778                 :             :   /* Parse the default argument.  */
   33779                 :     6358168 :   parsed_arg = cp_parser_initializer (parser);
   33780                 :     6358168 :   if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg))
   33781                 :      783851 :     maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
   33782                 :             : 
   33783                 :     6358168 :   finish_lambda_scope ();
   33784                 :             : 
   33785                 :     6358168 :   if (parsed_arg == error_mark_node)
   33786                 :         143 :     cp_parser_skip_to_end_of_statement (parser);
   33787                 :             : 
   33788                 :     6358168 :   if (!processing_template_decl)
   33789                 :             :     {
   33790                 :             :       /* In a non-template class, check conversions now.  In a template,
   33791                 :             :          we'll wait and instantiate these as needed.  */
   33792                 :     1007800 :       if (TREE_CODE (decl) == PARM_DECL)
   33793                 :      667639 :         parsed_arg = check_default_argument (parmtype, parsed_arg,
   33794                 :             :                                              tf_warning_or_error);
   33795                 :      340161 :       else if (maybe_reject_flexarray_init (decl, parsed_arg))
   33796                 :          30 :         parsed_arg = error_mark_node;
   33797                 :             :       else
   33798                 :      340131 :         parsed_arg = digest_nsdmi_init (decl, parsed_arg, tf_warning_or_error);
   33799                 :             :     }
   33800                 :             : 
   33801                 :             :   /* If the token stream has not been completely used up, then
   33802                 :             :      there was extra junk after the end of the default
   33803                 :             :      argument.  */
   33804                 :     6358168 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
   33805                 :             :     {
   33806                 :           8 :       if (TREE_CODE (decl) == PARM_DECL)
   33807                 :           5 :         cp_parser_error (parser, "expected %<,%>");
   33808                 :             :       else
   33809                 :           3 :         cp_parser_error (parser, "expected %<;%>");
   33810                 :             :     }
   33811                 :             : 
   33812                 :             :   /* Revert to the main lexer.  */
   33813                 :     6358168 :   cp_parser_pop_lexer (parser);
   33814                 :             : 
   33815                 :     6358168 :   return parsed_arg;
   33816                 :             : }
   33817                 :             : 
   33818                 :             : /* FIELD is a non-static data member with an initializer which we saved for
   33819                 :             :    later; parse it now.  */
   33820                 :             : 
   33821                 :             : static void
   33822                 :      856478 : cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
   33823                 :             : {
   33824                 :      856478 :   tree def;
   33825                 :             : 
   33826                 :      856478 :   maybe_begin_member_template_processing (field);
   33827                 :             : 
   33828                 :      856478 :   push_unparsed_function_queues (parser);
   33829                 :      856478 :   def = cp_parser_late_parse_one_default_arg (parser, field,
   33830                 :      856478 :                                               DECL_INITIAL (field),
   33831                 :             :                                               NULL_TREE);
   33832                 :      856478 :   pop_unparsed_function_queues (parser);
   33833                 :             : 
   33834                 :      856478 :   maybe_end_member_template_processing ();
   33835                 :             : 
   33836                 :      856478 :   DECL_INITIAL (field) = def;
   33837                 :      856478 : }
   33838                 :             : 
   33839                 :             : /* FN is a FUNCTION_DECL which may contains a parameter with an
   33840                 :             :    unparsed DEFERRED_PARSE.  Parse the default args now.  This function
   33841                 :             :    assumes that the current scope is the scope in which the default
   33842                 :             :    argument should be processed.  */
   33843                 :             : 
   33844                 :             : static void
   33845                 :     4625893 : cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
   33846                 :             : {
   33847                 :     4625893 :   unsigned char saved_local_variables_forbidden_p;
   33848                 :             : 
   33849                 :             :   /* While we're parsing the default args, we might (due to the
   33850                 :             :      statement expression extension) encounter more classes.  We want
   33851                 :             :      to handle them right away, but we don't want them getting mixed
   33852                 :             :      up with default args that are currently in the queue.  */
   33853                 :     4625893 :   push_unparsed_function_queues (parser);
   33854                 :             : 
   33855                 :             :   /* Local variable names (and the `this' keyword) may not appear
   33856                 :             :      in a default argument.  */
   33857                 :     4625893 :   saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
   33858                 :     4625893 :   parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
   33859                 :             : 
   33860                 :     4625893 :   push_defarg_context (fn);
   33861                 :             : 
   33862                 :     4625893 :   begin_scope (sk_function_parms, fn);
   33863                 :             : 
   33864                 :             :   /* Gather the PARM_DECLs into a vec so we can keep track of them when
   33865                 :             :      pushdecl clears DECL_CHAIN.  */
   33866                 :     4625893 :   releasing_vec parms;
   33867                 :    20245043 :   for (tree parmdecl = DECL_ARGUMENTS (fn); parmdecl;
   33868                 :    15619150 :        parmdecl = DECL_CHAIN (parmdecl))
   33869                 :    15619150 :     vec_safe_push (parms, parmdecl);
   33870                 :             : 
   33871                 :     4625893 :   tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
   33872                 :     4625893 :   for (int i = 0;
   33873                 :    20245043 :        parm && parm != void_list_node;
   33874                 :    15619150 :        parm = TREE_CHAIN (parm),
   33875                 :             :          ++i)
   33876                 :             :     {
   33877                 :    15619150 :       tree default_arg = TREE_PURPOSE (parm);
   33878                 :    15619150 :       tree parsed_arg;
   33879                 :             : 
   33880                 :    15619150 :       tree parmdecl = parms[i];
   33881                 :    15619150 :       pushdecl (parmdecl);
   33882                 :             : 
   33883                 :    15619150 :       if (!default_arg)
   33884                 :    10117415 :         continue;
   33885                 :             : 
   33886                 :     5501735 :       if (TREE_CODE (default_arg) != DEFERRED_PARSE)
   33887                 :             :         /* This can happen for a friend declaration for a function
   33888                 :             :            already declared with default arguments.  */
   33889                 :          36 :         continue;
   33890                 :             : 
   33891                 :     5501699 :       parsed_arg
   33892                 :    11003398 :         = cp_parser_late_parse_one_default_arg (parser, parmdecl,
   33893                 :             :                                                 default_arg,
   33894                 :     5501699 :                                                 TREE_VALUE (parm));
   33895                 :     5501699 :       TREE_PURPOSE (parm) = parsed_arg;
   33896                 :             : 
   33897                 :             :       /* Update any instantiations we've already created.  */
   33898                 :     5501711 :       for (tree copy : DEFPARSE_INSTANTIATIONS (default_arg))
   33899                 :           4 :         TREE_PURPOSE (copy) = parsed_arg;
   33900                 :             :     }
   33901                 :             : 
   33902                 :     4625893 :   pop_bindings_and_leave_scope ();
   33903                 :             : 
   33904                 :             :   /* Restore DECL_CHAINs after clobbering by pushdecl.  */
   33905                 :     4625893 :   parm = NULL_TREE;
   33906                 :    20245043 :   for (int i = parms->length () - 1; i >= 0; --i)
   33907                 :             :     {
   33908                 :    15619150 :       DECL_CHAIN (parms[i]) = parm;
   33909                 :    15619150 :       parm = parms[i];
   33910                 :             :     }
   33911                 :             : 
   33912                 :     4625893 :   pop_defarg_context ();
   33913                 :             : 
   33914                 :             :   /* Make sure no default arg is missing.  */
   33915                 :     4625893 :   check_default_args (fn);
   33916                 :             : 
   33917                 :             :   /* Restore the state of local_variables_forbidden_p.  */
   33918                 :     4625893 :   parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
   33919                 :             : 
   33920                 :             :   /* Restore the queue.  */
   33921                 :     4625893 :   pop_unparsed_function_queues (parser);
   33922                 :     4625893 : }
   33923                 :             : 
   33924                 :             : /* Subroutine of cp_parser_sizeof_operand, for handling C++11
   33925                 :             : 
   33926                 :             :      sizeof ... ( identifier )
   33927                 :             : 
   33928                 :             :    where the 'sizeof' token has already been consumed.  */
   33929                 :             : 
   33930                 :             : static tree
   33931                 :     1027423 : cp_parser_sizeof_pack (cp_parser *parser)
   33932                 :             : {
   33933                 :             :   /* Consume the `...'.  */
   33934                 :     1027423 :   cp_lexer_consume_token (parser->lexer);
   33935                 :     1027423 :   maybe_warn_variadic_templates ();
   33936                 :             : 
   33937                 :     1027423 :   matching_parens parens;
   33938                 :     1027423 :   bool paren = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN);
   33939                 :     1027423 :   if (paren)
   33940                 :     1027417 :     parens.consume_open (parser);
   33941                 :             :   else
   33942                 :           6 :     permerror (cp_lexer_peek_token (parser->lexer)->location,
   33943                 :             :                "%<sizeof...%> argument must be surrounded by parentheses");
   33944                 :             : 
   33945                 :     1027423 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   33946                 :     1027423 :   tree name = cp_parser_identifier (parser);
   33947                 :     1027423 :   if (name == error_mark_node)
   33948                 :             :     return error_mark_node;
   33949                 :             :   /* The name is not qualified.  */
   33950                 :     1027423 :   parser->scope = NULL_TREE;
   33951                 :     1027423 :   parser->qualifying_scope = NULL_TREE;
   33952                 :     1027423 :   parser->object_scope = NULL_TREE;
   33953                 :     1027423 :   tree expr = cp_parser_lookup_name_simple (parser, name, token->location);
   33954                 :     1027423 :   if (expr == error_mark_node)
   33955                 :           0 :     cp_parser_name_lookup_error (parser, name, expr, NLE_NULL,
   33956                 :             :                                  token->location);
   33957                 :     1027423 :   if (TREE_CODE (expr) == TYPE_DECL || TREE_CODE (expr) == TEMPLATE_DECL)
   33958                 :      995908 :     expr = TREE_TYPE (expr);
   33959                 :       31515 :   else if (TREE_CODE (expr) == CONST_DECL)
   33960                 :       31454 :     expr = DECL_INITIAL (expr);
   33961                 :     1027423 :   expr = make_pack_expansion (expr);
   33962                 :     1027423 :   if (expr != error_mark_node)
   33963                 :     1027420 :     PACK_EXPANSION_SIZEOF_P (expr) = true;
   33964                 :             : 
   33965                 :     1027423 :   if (paren)
   33966                 :     1027417 :     parens.require_close (parser);
   33967                 :             : 
   33968                 :             :   return expr;
   33969                 :             : }
   33970                 :             : 
   33971                 :             : /* Parse the operand of `sizeof' (or a similar operator).  Returns
   33972                 :             :    either a TYPE or an expression, depending on the form of the
   33973                 :             :    input.  The KEYWORD indicates which kind of expression we have
   33974                 :             :    encountered.  */
   33975                 :             : 
   33976                 :             : static tree
   33977                 :     4282692 : cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
   33978                 :             : {
   33979                 :     4282692 :   tree expr = NULL_TREE;
   33980                 :     4282692 :   const char *saved_message;
   33981                 :     4282692 :   const char *saved_message_arg;
   33982                 :     4282692 :   bool saved_integral_constant_expression_p;
   33983                 :     4282692 :   bool saved_non_integral_constant_expression_p;
   33984                 :             : 
   33985                 :             :   /* If it's a `...', then we are computing the length of a parameter
   33986                 :             :      pack.  */
   33987                 :     4282692 :   if (keyword == RID_SIZEOF
   33988                 :     4282692 :       && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   33989                 :     1027423 :     return cp_parser_sizeof_pack (parser);
   33990                 :             : 
   33991                 :             :   /* Types cannot be defined in a `sizeof' expression.  Save away the
   33992                 :             :      old message.  */
   33993                 :     3255269 :   saved_message = parser->type_definition_forbidden_message;
   33994                 :     3255269 :   saved_message_arg = parser->type_definition_forbidden_message_arg;
   33995                 :     3255269 :   parser->type_definition_forbidden_message
   33996                 :     3255269 :     = G_("types may not be defined in %qs expressions");
   33997                 :     3255269 :   parser->type_definition_forbidden_message_arg
   33998                 :     3255269 :     = IDENTIFIER_POINTER (ridpointers[keyword]);
   33999                 :             : 
   34000                 :             :   /* The restrictions on constant-expressions do not apply inside
   34001                 :             :      sizeof expressions.  */
   34002                 :     3255269 :   saved_integral_constant_expression_p
   34003                 :     3255269 :     = parser->integral_constant_expression_p;
   34004                 :     3255269 :   saved_non_integral_constant_expression_p
   34005                 :     3255269 :     = parser->non_integral_constant_expression_p;
   34006                 :     3255269 :   parser->integral_constant_expression_p = false;
   34007                 :             : 
   34008                 :     3255269 :   auto cleanup = make_temp_override
   34009                 :     3255269 :     (parser->auto_is_implicit_function_template_parm_p, false);
   34010                 :             : 
   34011                 :             :   /* Do not actually evaluate the expression.  */
   34012                 :     3255269 :   ++cp_unevaluated_operand;
   34013                 :     3255269 :   ++c_inhibit_evaluation_warnings;
   34014                 :             :   /* If it's a `(', then we might be looking at the type-id
   34015                 :             :      construction.  */
   34016                 :     3255269 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   34017                 :             :     {
   34018                 :     3248735 :       tree type = NULL_TREE;
   34019                 :             : 
   34020                 :     3248735 :       tentative_firewall firewall (parser);
   34021                 :             : 
   34022                 :             :       /* We can't be sure yet whether we're looking at a type-id or an
   34023                 :             :          expression.  */
   34024                 :     3248735 :       cp_parser_parse_tentatively (parser);
   34025                 :             : 
   34026                 :     3248735 :       matching_parens parens;
   34027                 :     3248735 :       parens.consume_open (parser);
   34028                 :             : 
   34029                 :             :       /* Note: as a GNU Extension, compound literals are considered
   34030                 :             :          postfix-expressions as they are in C99, so they are valid
   34031                 :             :          arguments to sizeof.  See comment in cp_parser_cast_expression
   34032                 :             :          for details.  */
   34033                 :     3248735 :       if (cp_parser_compound_literal_p (parser))
   34034                 :     3248763 :         cp_parser_simulate_error (parser);
   34035                 :             :       else
   34036                 :             :         {
   34037                 :     3248707 :           bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
   34038                 :     3248707 :           parser->in_type_id_in_expr_p = true;
   34039                 :             :           /* Look for the type-id.  */
   34040                 :     3248707 :           type = cp_parser_type_id (parser);
   34041                 :             :           /* Look for the closing `)'.  */
   34042                 :     3248707 :           parens.require_close (parser);
   34043                 :     3248707 :           parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
   34044                 :             :         }
   34045                 :             : 
   34046                 :             :       /* If all went well, then we're done.  */
   34047                 :     3248735 :       if (cp_parser_parse_definitely (parser))
   34048                 :             :         expr = type;
   34049                 :             :       else
   34050                 :             :         {
   34051                 :             :           /* Commit to the tentative_firewall so we get syntax errors.  */
   34052                 :      566624 :           cp_parser_commit_to_tentative_parse (parser);
   34053                 :             : 
   34054                 :      566624 :           expr = cp_parser_unary_expression (parser);
   34055                 :             :         }
   34056                 :     3248735 :     }
   34057                 :             :   else
   34058                 :        6534 :     expr = cp_parser_unary_expression (parser);
   34059                 :             : 
   34060                 :             :   /* Go back to evaluating expressions.  */
   34061                 :     3255269 :   --cp_unevaluated_operand;
   34062                 :     3255269 :   --c_inhibit_evaluation_warnings;
   34063                 :             : 
   34064                 :             :   /* And restore the old one.  */
   34065                 :     3255269 :   parser->type_definition_forbidden_message = saved_message;
   34066                 :     3255269 :   parser->type_definition_forbidden_message_arg = saved_message_arg;
   34067                 :     3255269 :   parser->integral_constant_expression_p
   34068                 :     3255269 :     = saved_integral_constant_expression_p;
   34069                 :     3255269 :   parser->non_integral_constant_expression_p
   34070                 :     3255269 :     = saved_non_integral_constant_expression_p;
   34071                 :             : 
   34072                 :     3255269 :   return expr;
   34073                 :     3255269 : }
   34074                 :             : 
   34075                 :             : /* If the current declaration has no declarator, return true.  */
   34076                 :             : 
   34077                 :             : static bool
   34078                 :    56481714 : cp_parser_declares_only_class_p (cp_parser *parser)
   34079                 :             : {
   34080                 :             :   /* If the next token is a `;' or a `,' then there is no
   34081                 :             :      declarator.  */
   34082                 :    56481714 :   return (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
   34083                 :    56481714 :           || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
   34084                 :             : }
   34085                 :             : 
   34086                 :             : /* Update the DECL_SPECS to reflect the storage class indicated by
   34087                 :             :    KEYWORD.  */
   34088                 :             : 
   34089                 :             : static void
   34090                 :    46353733 : cp_parser_set_storage_class (cp_parser *parser,
   34091                 :             :                              cp_decl_specifier_seq *decl_specs,
   34092                 :             :                              enum rid keyword,
   34093                 :             :                              cp_token *token)
   34094                 :             : {
   34095                 :    46353733 :   cp_storage_class storage_class;
   34096                 :             : 
   34097                 :    46353733 :   switch (keyword)
   34098                 :             :     {
   34099                 :             :     case RID_AUTO:
   34100                 :             :       storage_class = sc_auto;
   34101                 :             :       break;
   34102                 :         652 :     case RID_REGISTER:
   34103                 :         652 :       storage_class = sc_register;
   34104                 :         652 :       break;
   34105                 :    18091340 :     case RID_STATIC:
   34106                 :    18091340 :       storage_class = sc_static;
   34107                 :    18091340 :       break;
   34108                 :    27983343 :     case RID_EXTERN:
   34109                 :    27983343 :       storage_class = sc_extern;
   34110                 :    27983343 :       break;
   34111                 :      278367 :     case RID_MUTABLE:
   34112                 :      278367 :       storage_class = sc_mutable;
   34113                 :      278367 :       break;
   34114                 :           0 :     default:
   34115                 :           0 :       gcc_unreachable ();
   34116                 :             :     }
   34117                 :             : 
   34118                 :    46353733 :   if (parser->in_unbraced_linkage_specification_p)
   34119                 :             :     {
   34120                 :          17 :       error_at (token->location, "invalid use of %qD in linkage specification",
   34121                 :          17 :                 ridpointers[keyword]);
   34122                 :          17 :       return;
   34123                 :             :     }
   34124                 :    46353716 :   else if (decl_specs->storage_class != sc_none)
   34125                 :             :     {
   34126                 :          27 :       if (decl_specs->conflicting_specifiers_p)
   34127                 :             :         return;
   34128                 :          27 :       gcc_rich_location richloc (token->location);
   34129                 :          27 :       richloc.add_location_if_nearby (decl_specs->locations[ds_storage_class]);
   34130                 :          27 :       if (decl_specs->storage_class == storage_class)
   34131                 :           8 :         error_at (&richloc, "duplicate %qD specifier", ridpointers[keyword]);
   34132                 :             :       else
   34133                 :          19 :         error_at (&richloc,
   34134                 :             :                   "%qD specifier conflicts with %qs",
   34135                 :          19 :                   ridpointers[keyword],
   34136                 :          19 :                   cp_storage_class_name[decl_specs->storage_class]);
   34137                 :          27 :       decl_specs->conflicting_specifiers_p = true;
   34138                 :          27 :       return;
   34139                 :          27 :     }
   34140                 :             : 
   34141                 :    46353689 :   if ((keyword == RID_EXTERN || keyword == RID_STATIC)
   34142                 :    46074656 :       && decl_spec_seq_has_spec_p (decl_specs, ds_thread)
   34143                 :    46353704 :       && decl_specs->gnu_thread_keyword_p)
   34144                 :             :     {
   34145                 :          12 :       pedwarn (decl_specs->locations[ds_thread], 0,
   34146                 :          12 :                 "%<__thread%> before %qD", ridpointers[keyword]);
   34147                 :             :     }
   34148                 :             : 
   34149                 :    46353689 :   decl_specs->storage_class = storage_class;
   34150                 :    46353689 :   set_and_check_decl_spec_loc (decl_specs, ds_storage_class, token);
   34151                 :             : 
   34152                 :             :   /* A storage class specifier cannot be applied alongside a typedef
   34153                 :             :      specifier. If there is a typedef specifier present then set
   34154                 :             :      conflicting_specifiers_p which will trigger an error later
   34155                 :             :      on in grokdeclarator. */
   34156                 :    46353689 :   if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
   34157                 :    46353689 :       && !decl_specs->conflicting_specifiers_p)
   34158                 :             :     {
   34159                 :          13 :       gcc_rich_location richloc (token->location);
   34160                 :          13 :       richloc.add_location_if_nearby (decl_specs->locations[ds_typedef]);
   34161                 :          13 :       error_at (&richloc,
   34162                 :             :                 "%qD specifier conflicts with %<typedef%>",
   34163                 :          13 :                 ridpointers[keyword]);
   34164                 :          13 :       decl_specs->conflicting_specifiers_p = true;
   34165                 :          13 :     }
   34166                 :             : }
   34167                 :             : 
   34168                 :             : /* Update the DECL_SPECS to reflect the TYPE_SPEC.  If TYPE_DEFINITION_P
   34169                 :             :    is true, the type is a class or enum definition.  */
   34170                 :             : 
   34171                 :             : static void
   34172                 :   890473451 : cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
   34173                 :             :                               tree type_spec,
   34174                 :             :                               cp_token *token,
   34175                 :             :                               bool type_definition_p)
   34176                 :             : {
   34177                 :   890473451 :   decl_specs->any_specifiers_p = true;
   34178                 :             : 
   34179                 :             :   /* If the user tries to redeclare bool, char8_t, char16_t, char32_t, or
   34180                 :             :      wchar_t (with, for example, in "typedef int wchar_t;") we remember that
   34181                 :             :      this is what happened.  In system headers, we ignore these
   34182                 :             :      declarations so that G++ can work with system headers that are not
   34183                 :             :      C++-safe.  */
   34184                 :   890473451 :   if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
   34185                 :    25186352 :       && !type_definition_p
   34186                 :    24717361 :       && TYPE_P (type_spec)
   34187                 :    10532822 :       && (type_spec == boolean_type_node
   34188                 :    10371537 :           || type_spec == char8_type_node
   34189                 :    10363155 :           || type_spec == char16_type_node
   34190                 :    10302910 :           || type_spec == char32_type_node
   34191                 :    10242665 :           || extended_float_type_p (type_spec)
   34192                 :    10213356 :           || type_spec == wchar_type_node)
   34193                 :   890862214 :       && (decl_specs->type
   34194                 :      388741 :           || decl_spec_seq_has_spec_p (decl_specs, ds_long)
   34195                 :      388737 :           || decl_spec_seq_has_spec_p (decl_specs, ds_short)
   34196                 :      388737 :           || decl_spec_seq_has_spec_p (decl_specs, ds_unsigned)
   34197                 :      388737 :           || decl_spec_seq_has_spec_p (decl_specs, ds_signed)))
   34198                 :             :     {
   34199                 :          26 :       decl_specs->redefined_builtin_type = type_spec;
   34200                 :          26 :       set_and_check_decl_spec_loc (decl_specs,
   34201                 :             :                                    ds_redefined_builtin_type_spec,
   34202                 :             :                                    token);
   34203                 :          26 :       if (!decl_specs->type)
   34204                 :             :         {
   34205                 :           4 :           decl_specs->type = type_spec;
   34206                 :           4 :           decl_specs->type_definition_p = false;
   34207                 :           4 :           set_and_check_decl_spec_loc (decl_specs,ds_type_spec, token);
   34208                 :             :         }
   34209                 :             :     }
   34210                 :   890473425 :   else if (decl_specs->type)
   34211                 :        2068 :     decl_specs->multiple_types_p = true;
   34212                 :             :   else
   34213                 :             :     {
   34214                 :   890471357 :       decl_specs->type = type_spec;
   34215                 :   890471357 :       decl_specs->type_definition_p = type_definition_p;
   34216                 :   890471357 :       decl_specs->redefined_builtin_type = NULL_TREE;
   34217                 :   890471357 :       set_and_check_decl_spec_loc (decl_specs, ds_type_spec, token);
   34218                 :             :     }
   34219                 :   890473451 : }
   34220                 :             : 
   34221                 :             : /* True iff TOKEN is the GNU keyword __thread.  */
   34222                 :             : 
   34223                 :             : static bool
   34224                 :       19136 : token_is__thread (cp_token *token)
   34225                 :             : {
   34226                 :       19136 :   gcc_assert (token->keyword == RID_THREAD);
   34227                 :       19136 :   return id_equal (token->u.value, "__thread");
   34228                 :             : }
   34229                 :             : 
   34230                 :             : /* Set the location for a declarator specifier and check if it is
   34231                 :             :    duplicated.
   34232                 :             : 
   34233                 :             :    DECL_SPECS is the sequence of declarator specifiers onto which to
   34234                 :             :    set the location.
   34235                 :             : 
   34236                 :             :    DS is the single declarator specifier to set which location  is to
   34237                 :             :    be set onto the existing sequence of declarators.
   34238                 :             : 
   34239                 :             :    LOCATION is the location for the declarator specifier to
   34240                 :             :    consider.  */
   34241                 :             : 
   34242                 :             : static void
   34243                 :  1196907287 : set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
   34244                 :             :                              cp_decl_spec ds, cp_token *token)
   34245                 :             : {
   34246                 :  1196907287 :   gcc_assert (ds < ds_last);
   34247                 :             : 
   34248                 :  1196907287 :   if (decl_specs == NULL)
   34249                 :             :     return;
   34250                 :             : 
   34251                 :  1196759417 :   location_t location = token->location;
   34252                 :             : 
   34253                 :  1196759417 :   if (decl_specs->locations[ds] == 0)
   34254                 :             :     {
   34255                 :  1193796547 :       decl_specs->locations[ds] = location;
   34256                 :  1193796547 :       if (ds == ds_thread)
   34257                 :       19123 :         decl_specs->gnu_thread_keyword_p = token_is__thread (token);
   34258                 :             :     }
   34259                 :             :   else
   34260                 :             :     {
   34261                 :     2962870 :       if (ds == ds_long)
   34262                 :             :         {
   34263                 :     2962718 :           if (decl_specs->locations[ds_long_long] != 0)
   34264                 :           4 :             error_at (location,
   34265                 :             :                       "%<long long long%> is too long for GCC");
   34266                 :             :           else
   34267                 :             :             {
   34268                 :     2962714 :               decl_specs->locations[ds_long_long] = location;
   34269                 :     2962714 :               pedwarn_cxx98 (location,
   34270                 :             :                              OPT_Wlong_long,
   34271                 :             :                              "ISO C++ 1998 does not support %<long long%>");
   34272                 :             :             }
   34273                 :             :         }
   34274                 :         152 :       else if (ds == ds_thread)
   34275                 :             :         {
   34276                 :          13 :           bool gnu = token_is__thread (token);
   34277                 :          13 :           gcc_rich_location richloc (location);
   34278                 :          13 :           if (gnu != decl_specs->gnu_thread_keyword_p)
   34279                 :             :             {
   34280                 :           6 :               richloc.add_range (decl_specs->locations[ds_thread]);
   34281                 :           6 :               error_at (&richloc,
   34282                 :             :                         "both %<__thread%> and %<thread_local%> specified");
   34283                 :             :             }
   34284                 :             :           else
   34285                 :             :             {
   34286                 :           7 :               richloc.add_fixit_remove ();
   34287                 :           7 :               error_at (&richloc, "duplicate %qD", token->u.value);
   34288                 :             :             }
   34289                 :          13 :         }
   34290                 :             :       else
   34291                 :             :         {
   34292                 :             :           /* These correspond to cp-tree.h:cp_decl_spec,
   34293                 :             :              changes here should also be reflected there.  */
   34294                 :         139 :           static const char *const decl_spec_names[] = {
   34295                 :             :             "signed",
   34296                 :             :             "unsigned",
   34297                 :             :             "short",
   34298                 :             :             "long",
   34299                 :             :             "const",
   34300                 :             :             "volatile",
   34301                 :             :             "restrict",
   34302                 :             :             "inline",
   34303                 :             :             "virtual",
   34304                 :             :             "explicit",
   34305                 :             :             "friend",
   34306                 :             :             "typedef",
   34307                 :             :             "using",
   34308                 :             :             "constexpr",
   34309                 :             :             "__complex",
   34310                 :             :             "constinit",
   34311                 :             :             "consteval",
   34312                 :             :             "this"
   34313                 :             :           };
   34314                 :         139 :           gcc_rich_location richloc (location);
   34315                 :         139 :           richloc.add_fixit_remove ();
   34316                 :         139 :           error_at (&richloc, "duplicate %qs", decl_spec_names[ds]);
   34317                 :         139 :         }
   34318                 :             :     }
   34319                 :             : }
   34320                 :             : 
   34321                 :             : /* Return true iff the declarator specifier DS is present in the
   34322                 :             :    sequence of declarator specifiers DECL_SPECS.  */
   34323                 :             : 
   34324                 :             : bool
   34325                 : 19692225714 : decl_spec_seq_has_spec_p (const cp_decl_specifier_seq * decl_specs,
   34326                 :             :                           cp_decl_spec ds)
   34327                 :             : {
   34328                 : 19692225714 :   gcc_assert (ds < ds_last);
   34329                 :             : 
   34330                 : 19692225714 :   if (decl_specs == NULL)
   34331                 :             :     return false;
   34332                 :             : 
   34333                 : 19692225714 :   return decl_specs->locations[ds] != 0;
   34334                 :             : }
   34335                 :             : 
   34336                 :             : /* DECL_SPECIFIERS is the representation of a decl-specifier-seq.
   34337                 :             :    Returns TRUE iff `friend' appears among the DECL_SPECIFIERS.  */
   34338                 :             : 
   34339                 :             : static bool
   34340                 :   327154532 : cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers)
   34341                 :             : {
   34342                 :   327154532 :   return decl_spec_seq_has_spec_p (decl_specifiers, ds_friend);
   34343                 :             : }
   34344                 :             : 
   34345                 :             : /* Issue an error message indicating that TOKEN_DESC was expected.
   34346                 :             :    If KEYWORD is true, it indicated this function is called by
   34347                 :             :    cp_parser_require_keword and the required token can only be
   34348                 :             :    a indicated keyword.
   34349                 :             : 
   34350                 :             :    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
   34351                 :             :    within any error as the location of an "opening" token matching
   34352                 :             :    the close token TYPE (e.g. the location of the '(' when TOKEN_DESC is
   34353                 :             :    RT_CLOSE_PAREN).  */
   34354                 :             : 
   34355                 :             : static void
   34356                 :        3135 : cp_parser_required_error (cp_parser *parser,
   34357                 :             :                           required_token token_desc,
   34358                 :             :                           bool keyword,
   34359                 :             :                           location_t matching_location)
   34360                 :             : {
   34361                 :        6270 :   if (cp_parser_simulate_error (parser))
   34362                 :           0 :     return;
   34363                 :             : 
   34364                 :        3135 :   const char *gmsgid = NULL;
   34365                 :        3135 :   switch (token_desc)
   34366                 :             :     {
   34367                 :           0 :       case RT_NEW:
   34368                 :           0 :         gmsgid = G_("expected %<new%>");
   34369                 :           0 :         break;
   34370                 :           0 :       case RT_DELETE:
   34371                 :           0 :         gmsgid = G_("expected %<delete%>");
   34372                 :           0 :         break;
   34373                 :           0 :       case RT_RETURN:
   34374                 :           0 :         gmsgid = G_("expected %<return%>");
   34375                 :           0 :         break;
   34376                 :           2 :       case RT_WHILE:
   34377                 :           2 :         gmsgid = G_("expected %<while%>");
   34378                 :           2 :         break;
   34379                 :           0 :       case RT_EXTERN:
   34380                 :           0 :         gmsgid = G_("expected %<extern%>");
   34381                 :           0 :         break;
   34382                 :           0 :       case RT_STATIC_ASSERT:
   34383                 :           0 :         gmsgid = G_("expected %<static_assert%>");
   34384                 :           0 :         break;
   34385                 :           0 :       case RT_DECLTYPE:
   34386                 :           0 :         gmsgid = G_("expected %<decltype%>");
   34387                 :           0 :         break;
   34388                 :           0 :       case RT_OPERATOR:
   34389                 :           0 :         gmsgid = G_("expected %<operator%>");
   34390                 :           0 :         break;
   34391                 :           0 :       case RT_CLASS:
   34392                 :           0 :         gmsgid = G_("expected %<class%>");
   34393                 :           0 :         break;
   34394                 :           0 :       case RT_TEMPLATE:
   34395                 :           0 :         gmsgid = G_("expected %<template%>");
   34396                 :           0 :         break;
   34397                 :           0 :       case RT_NAMESPACE:
   34398                 :           0 :         gmsgid = G_("expected %<namespace%>");
   34399                 :           0 :         break;
   34400                 :           0 :       case RT_USING:
   34401                 :           0 :         gmsgid = G_("expected %<using%>");
   34402                 :           0 :         break;
   34403                 :           0 :       case RT_ASM:
   34404                 :           0 :         gmsgid = G_("expected %<asm%>");
   34405                 :           0 :         break;
   34406                 :           0 :       case RT_TRY:
   34407                 :           0 :         gmsgid = G_("expected %<try%>");
   34408                 :           0 :         break;
   34409                 :           4 :       case RT_CATCH:
   34410                 :           4 :         gmsgid = G_("expected %<catch%>");
   34411                 :           4 :         break;
   34412                 :           0 :       case RT_THROW:
   34413                 :           0 :         gmsgid = G_("expected %<throw%>");
   34414                 :           0 :         break;
   34415                 :           0 :       case RT_AUTO:
   34416                 :           0 :         gmsgid = G_("expected %<auto%>");
   34417                 :           0 :         break;
   34418                 :           0 :       case RT_LABEL:
   34419                 :           0 :         gmsgid = G_("expected %<__label__%>");
   34420                 :           0 :         break;
   34421                 :           0 :       case RT_AT_TRY:
   34422                 :           0 :         gmsgid = G_("expected %<@try%>");
   34423                 :           0 :         break;
   34424                 :           0 :       case RT_AT_SYNCHRONIZED:
   34425                 :           0 :         gmsgid = G_("expected %<@synchronized%>");
   34426                 :           0 :         break;
   34427                 :           0 :       case RT_AT_THROW:
   34428                 :           0 :         gmsgid = G_("expected %<@throw%>");
   34429                 :           0 :         break;
   34430                 :           0 :       case RT_TRANSACTION_ATOMIC:
   34431                 :           0 :         gmsgid = G_("expected %<__transaction_atomic%>");
   34432                 :           0 :         break;
   34433                 :           0 :       case RT_TRANSACTION_RELAXED:
   34434                 :           0 :         gmsgid = G_("expected %<__transaction_relaxed%>");
   34435                 :           0 :         break;
   34436                 :           0 :       case RT_CO_YIELD:
   34437                 :           0 :         gmsgid = G_("expected %<co_yield%>");
   34438                 :           0 :         break;
   34439                 :             :       default:
   34440                 :             :         break;
   34441                 :             :     }
   34442                 :             : 
   34443                 :        3135 :   if (!gmsgid && !keyword)
   34444                 :             :     {
   34445                 :        3129 :       switch (token_desc)
   34446                 :             :         {
   34447                 :             :           case RT_SEMICOLON:
   34448                 :             :             gmsgid = G_("expected %<;%>");
   34449                 :             :             break;
   34450                 :         307 :           case RT_OPEN_PAREN:
   34451                 :         307 :             gmsgid = G_("expected %<(%>");
   34452                 :         307 :             break;
   34453                 :             :           case RT_CLOSE_BRACE:
   34454                 :             :             gmsgid = G_("expected %<}%>");
   34455                 :             :             break;
   34456                 :         189 :           case RT_OPEN_BRACE:
   34457                 :         189 :             gmsgid = G_("expected %<{%>");
   34458                 :         189 :             break;
   34459                 :         124 :           case RT_CLOSE_SQUARE:
   34460                 :         124 :             gmsgid = G_("expected %<]%>");
   34461                 :         124 :             break;
   34462                 :           0 :           case RT_OPEN_SQUARE:
   34463                 :           0 :             gmsgid = G_("expected %<[%>");
   34464                 :           0 :             break;
   34465                 :          26 :           case RT_COMMA:
   34466                 :          26 :             gmsgid = G_("expected %<,%>");
   34467                 :          26 :             break;
   34468                 :           0 :           case RT_SCOPE:
   34469                 :           0 :             gmsgid = G_("expected %<::%>");
   34470                 :           0 :             break;
   34471                 :           5 :           case RT_LESS:
   34472                 :           5 :             gmsgid = G_("expected %<<%>");
   34473                 :           5 :             break;
   34474                 :          96 :           case RT_GREATER:
   34475                 :          96 :             gmsgid = G_("expected %<>%>");
   34476                 :          96 :             break;
   34477                 :          18 :           case RT_EQ:
   34478                 :          18 :             gmsgid = G_("expected %<=%>");
   34479                 :          18 :             break;
   34480                 :           0 :           case RT_ELLIPSIS:
   34481                 :           0 :             gmsgid = G_("expected %<...%>");
   34482                 :           0 :             break;
   34483                 :           0 :           case RT_MULT:
   34484                 :           0 :             gmsgid = G_("expected %<*%>");
   34485                 :           0 :             break;
   34486                 :           0 :           case RT_COMPL:
   34487                 :           0 :             gmsgid = G_("expected %<~%>");
   34488                 :           0 :             break;
   34489                 :          75 :           case RT_COLON:
   34490                 :          75 :             gmsgid = G_("expected %<:%>");
   34491                 :          75 :             break;
   34492                 :          20 :           case RT_COLON_SCOPE:
   34493                 :          20 :             gmsgid = G_("expected %<:%> or %<::%>");
   34494                 :          20 :             break;
   34495                 :        1274 :           case RT_CLOSE_PAREN:
   34496                 :        1274 :             gmsgid = G_("expected %<)%>");
   34497                 :        1274 :             break;
   34498                 :          12 :           case RT_COMMA_CLOSE_PAREN:
   34499                 :          12 :             gmsgid = G_("expected %<,%> or %<)%>");
   34500                 :          12 :             break;
   34501                 :         165 :           case RT_PRAGMA_EOL:
   34502                 :         165 :             gmsgid = G_("expected end of line");
   34503                 :         165 :             break;
   34504                 :         286 :           case RT_NAME:
   34505                 :         286 :             gmsgid = G_("expected identifier");
   34506                 :         286 :             break;
   34507                 :           0 :           case RT_SELECT:
   34508                 :           0 :             gmsgid = G_("expected selection-statement");
   34509                 :           0 :             break;
   34510                 :           0 :           case RT_ITERATION:
   34511                 :           0 :             gmsgid = G_("expected iteration-statement");
   34512                 :           0 :             break;
   34513                 :           0 :           case RT_JUMP:
   34514                 :           0 :             gmsgid = G_("expected jump-statement");
   34515                 :           0 :             break;
   34516                 :           0 :           case RT_CLASS_KEY:
   34517                 :           0 :             gmsgid = G_("expected class-key");
   34518                 :           0 :             break;
   34519                 :           0 :           case RT_CLASS_TYPENAME_TEMPLATE:
   34520                 :           0 :             gmsgid = G_("expected %<class%>, %<typename%>, or %<template%>");
   34521                 :           0 :             break;
   34522                 :           0 :           default:
   34523                 :           0 :             gcc_unreachable ();
   34524                 :             :         }
   34525                 :             :     }
   34526                 :             : 
   34527                 :        2926 :   if (gmsgid)
   34528                 :        3135 :     cp_parser_error_1 (parser, gmsgid, token_desc, matching_location);
   34529                 :             : }
   34530                 :             : 
   34531                 :             : 
   34532                 :             : /* If the next token is of the indicated TYPE, consume it.  Otherwise,
   34533                 :             :    issue an error message indicating that TOKEN_DESC was expected.
   34534                 :             : 
   34535                 :             :    Returns the token consumed, if the token had the appropriate type.
   34536                 :             :    Otherwise, returns NULL.
   34537                 :             : 
   34538                 :             :    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
   34539                 :             :    within any error as the location of an "opening" token matching
   34540                 :             :    the close token TYPE (e.g. the location of the '(' when TOKEN_DESC is
   34541                 :             :    RT_CLOSE_PAREN).  */
   34542                 :             : 
   34543                 :             : static cp_token *
   34544                 :  9123296781 : cp_parser_require (cp_parser* parser,
   34545                 :             :                    enum cpp_ttype type,
   34546                 :             :                    required_token token_desc,
   34547                 :             :                    location_t matching_location)
   34548                 :             : {
   34549                 :  9123296781 :   if (cp_lexer_next_token_is (parser->lexer, type))
   34550                 :  7550788344 :     return cp_lexer_consume_token (parser->lexer);
   34551                 :             :   else
   34552                 :             :     {
   34553                 :             :       /* Output the MESSAGE -- unless we're parsing tentatively.  */
   34554                 :  1572505308 :       if (!cp_parser_simulate_error (parser))
   34555                 :        3129 :         cp_parser_required_error (parser, token_desc, /*keyword=*/false,
   34556                 :             :                                   matching_location);
   34557                 :  1572508437 :       return NULL;
   34558                 :             :     }
   34559                 :             : }
   34560                 :             : 
   34561                 :             : /* Skip an entire parameter list from start to finish.  The next token must
   34562                 :             :    be the initial "<" of the parameter list.  Returns true on success and
   34563                 :             :    false otherwise.  */
   34564                 :             : 
   34565                 :             : static bool
   34566                 :      107863 : cp_parser_skip_entire_template_parameter_list (cp_parser* parser)
   34567                 :             : {
   34568                 :             :   /* Consume the "<" because cp_parser_skip_to_end_of_template_parameter_list
   34569                 :             :      requires it.  */
   34570                 :      107863 :   cp_lexer_consume_token (parser->lexer);
   34571                 :      107863 :   return cp_parser_skip_to_end_of_template_parameter_list (parser);
   34572                 :             : }
   34573                 :             : 
   34574                 :             : /* Ensure we are at the end of a template parameter list.  If we are, return.
   34575                 :             :    If we are not, something has gone wrong, in which case issue an error and
   34576                 :             :    skip to end of the parameter list.  */
   34577                 :             : 
   34578                 :             : static void
   34579                 :   243447403 : cp_parser_require_end_of_template_parameter_list (cp_parser* parser)
   34580                 :             : {
   34581                 :             :   /* Are we ready, yet?  If not, issue error message.  */
   34582                 :   243447403 :   if (cp_parser_require (parser, CPP_GREATER, RT_GREATER))
   34583                 :             :     return;
   34584                 :             : 
   34585                 :         292 :   cp_parser_skip_to_end_of_template_parameter_list (parser);
   34586                 :             : }
   34587                 :             : 
   34588                 :             : /* You should only call this function from inside a template parameter list
   34589                 :             :    (i.e. the current token should at least be the initial "<" of the
   34590                 :             :    parameter list).  If you are skipping the entire list, it may be better to
   34591                 :             :    use cp_parser_skip_entire_template_parameter_list.
   34592                 :             : 
   34593                 :             :    Tokens are skipped until the final ">" is found, or if we see
   34594                 :             :    '{', '}', ';', or if we find an unbalanced ')' or ']'.
   34595                 :             : 
   34596                 :             :    Returns true if we successfully reached the end, and false if
   34597                 :             :    something unexpected happened (e.g. end of file).  */
   34598                 :             : 
   34599                 :             : static bool
   34600                 :      108155 : cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
   34601                 :             : {
   34602                 :             :   /* Current level of '< ... >'.  */
   34603                 :      108155 :   unsigned level = 0;
   34604                 :             :   /* Ignore '<' and '>' nested inside '( ... )' or '[ ... ]'.  */
   34605                 :      108155 :   unsigned nesting_depth = 0;
   34606                 :             : 
   34607                 :             :   /* Skip tokens until the desired token is found.  */
   34608                 :      387141 :   while (true)
   34609                 :             :     {
   34610                 :             :       /* Peek at the next token.  */
   34611                 :      247648 :       switch (cp_lexer_peek_token (parser->lexer)->type)
   34612                 :             :         {
   34613                 :          68 :         case CPP_LESS:
   34614                 :          68 :           if (!nesting_depth)
   34615                 :          40 :             ++level;
   34616                 :             :           break;
   34617                 :             : 
   34618                 :           2 :         case CPP_RSHIFT:
   34619                 :           2 :           if (cxx_dialect == cxx98)
   34620                 :             :             /* C++0x views the `>>' operator as two `>' tokens, but
   34621                 :             :                C++98 does not. */
   34622                 :             :             break;
   34623                 :           0 :           else if (!nesting_depth && level-- == 0)
   34624                 :             :             {
   34625                 :             :               /* We've hit a `>>' where the first `>' closes the
   34626                 :             :                  template argument list, and the second `>' is
   34627                 :             :                  spurious.  Just consume the `>>' and stop; we've
   34628                 :             :                  already produced at least one error.  */
   34629                 :           0 :               cp_lexer_consume_token (parser->lexer);
   34630                 :           0 :               return false;
   34631                 :             :             }
   34632                 :             :           /* Fall through for C++0x, so we handle the second `>' in
   34633                 :             :              the `>>'.  */
   34634                 :      103544 :           gcc_fallthrough ();
   34635                 :             : 
   34636                 :      103544 :         case CPP_GREATER:
   34637                 :      103544 :           if (!nesting_depth && level-- == 0)
   34638                 :             :             {
   34639                 :             :               /* We've reached the token we want, consume it and stop.  */
   34640                 :      103508 :               cp_lexer_consume_token (parser->lexer);
   34641                 :      103508 :               return true;
   34642                 :             :             }
   34643                 :             :           break;
   34644                 :             : 
   34645                 :         156 :         case CPP_OPEN_PAREN:
   34646                 :         156 :         case CPP_OPEN_SQUARE:
   34647                 :         156 :           ++nesting_depth;
   34648                 :         156 :           break;
   34649                 :             : 
   34650                 :        3265 :         case CPP_CLOSE_PAREN:
   34651                 :        3265 :         case CPP_CLOSE_SQUARE:
   34652                 :        3265 :           if (nesting_depth-- == 0)
   34653                 :             :             return false;
   34654                 :             :           break;
   34655                 :             : 
   34656                 :             :         case CPP_EOF:
   34657                 :             :         case CPP_PRAGMA_EOL:
   34658                 :             :         case CPP_SEMICOLON:
   34659                 :             :         case CPP_OPEN_BRACE:
   34660                 :             :         case CPP_CLOSE_BRACE:
   34661                 :             :           /* The '>' was probably forgotten, don't look further.  */
   34662                 :             :           return false;
   34663                 :             : 
   34664                 :             :         default:
   34665                 :             :           break;
   34666                 :             :         }
   34667                 :             : 
   34668                 :             :       /* Consume this token.  */
   34669                 :      139493 :       cp_lexer_consume_token (parser->lexer);
   34670                 :             :     }
   34671                 :             : }
   34672                 :             : 
   34673                 :             : /* If the next token is the indicated keyword, consume it.  Otherwise,
   34674                 :             :    issue an error message indicating that TOKEN_DESC was expected.
   34675                 :             : 
   34676                 :             :    Returns the token consumed, if the token had the appropriate type.
   34677                 :             :    Otherwise, returns NULL.  */
   34678                 :             : 
   34679                 :             : static cp_token *
   34680                 :   113450985 : cp_parser_require_keyword (cp_parser* parser,
   34681                 :             :                            enum rid keyword,
   34682                 :             :                            required_token token_desc)
   34683                 :             : {
   34684                 :   113450985 :   cp_token *token = cp_parser_require (parser, CPP_KEYWORD, token_desc);
   34685                 :             : 
   34686                 :   113450985 :   if (token && token->keyword != keyword)
   34687                 :             :     {
   34688                 :           0 :       cp_parser_required_error (parser, token_desc, /*keyword=*/true,
   34689                 :             :                                 UNKNOWN_LOCATION);
   34690                 :           0 :       return NULL;
   34691                 :             :     }
   34692                 :             : 
   34693                 :             :   return token;
   34694                 :             : }
   34695                 :             : 
   34696                 :             : /* Returns TRUE iff TOKEN is a token that can begin the body of a
   34697                 :             :    function-definition.  */
   34698                 :             : 
   34699                 :             : static bool
   34700                 :   192427907 : cp_parser_token_starts_function_definition_p (cp_token* token)
   34701                 :             : {
   34702                 :   192427907 :   return (/* An ordinary function-body begins with an `{'.  */
   34703                 :   192427907 :           token->type == CPP_OPEN_BRACE
   34704                 :             :           /* A ctor-initializer begins with a `:'.  */
   34705                 :   107118231 :           || token->type == CPP_COLON
   34706                 :             :           /* A function-try-block begins with `try'.  */
   34707                 :    94406949 :           || token->keyword == RID_TRY
   34708                 :             :           /* A function-transaction-block begins with `__transaction_atomic'
   34709                 :             :              or `__transaction_relaxed'.  */
   34710                 :    94406641 :           || token->keyword == RID_TRANSACTION_ATOMIC
   34711                 :    94406617 :           || token->keyword == RID_TRANSACTION_RELAXED
   34712                 :             :           /* The named return value extension begins with `return'.  */
   34713                 :   286834524 :           || token->keyword == RID_RETURN);
   34714                 :             : }
   34715                 :             : 
   34716                 :             : /* Returns TRUE iff the next token is the ":" or "{" beginning a class
   34717                 :             :    definition.  */
   34718                 :             : 
   34719                 :             : static bool
   34720                 :    38011265 : cp_parser_next_token_starts_class_definition_p (cp_parser *parser)
   34721                 :             : {
   34722                 :    38011265 :   cp_token *token;
   34723                 :             : 
   34724                 :    38011265 :   token = cp_lexer_peek_token (parser->lexer);
   34725                 :    38011265 :   return (token->type == CPP_OPEN_BRACE
   34726                 :    38011265 :           || (token->type == CPP_COLON
   34727                 :     9881020 :               && !parser->colon_doesnt_start_class_def_p));
   34728                 :             : }
   34729                 :             : 
   34730                 :             : /* Returns TRUE iff the next token is the "," or ">" (or `>>', in
   34731                 :             :    C++0x) ending a template-argument.  */
   34732                 :             : 
   34733                 :             : static bool
   34734                 :   332333580 : cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
   34735                 :             : {
   34736                 :   332333580 :   cp_token *token;
   34737                 :             : 
   34738                 :   332333580 :   token = cp_lexer_peek_token (parser->lexer);
   34739                 :   332333580 :   return (token->type == CPP_COMMA
   34740                 :             :           || token->type == CPP_GREATER
   34741                 :             :           || token->type == CPP_ELLIPSIS
   34742                 :    50349597 :           || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)
   34743                 :             :           /* For better diagnostics, treat >>= like that too, that
   34744                 :             :              shouldn't appear non-nested in template arguments.  */
   34745                 :    40554572 :           || token->type == CPP_RSHIFT_EQ);
   34746                 :             : }
   34747                 :             : 
   34748                 :             : /* Returns TRUE iff the n-th token is a "<", or the n-th is a "[" and the
   34749                 :             :    (n+1)-th is a ":" (which is a possible digraph typo for "< ::").  */
   34750                 :             : 
   34751                 :             : static bool
   34752                 :  7505359400 : cp_parser_nth_token_starts_template_argument_list_p (cp_parser * parser,
   34753                 :             :                                                      size_t n)
   34754                 :             : {
   34755                 :  7505359400 :   cp_token *token;
   34756                 :             : 
   34757                 :  7505359400 :   token = cp_lexer_peek_nth_token (parser->lexer, n);
   34758                 :  7505359400 :   if (token->type == CPP_LESS)
   34759                 :             :     return true;
   34760                 :             :   /* Check for the sequence `<::' in the original code. It would be lexed as
   34761                 :             :      `[:', where `[' is a digraph, and there is no whitespace before
   34762                 :             :      `:'.  */
   34763                 :  6659535710 :   if (token->type == CPP_OPEN_SQUARE && token->flags & DIGRAPH)
   34764                 :             :     {
   34765                 :           6 :       cp_token *token2;
   34766                 :           6 :       token2 = cp_lexer_peek_nth_token (parser->lexer, n+1);
   34767                 :           6 :       if (token2->type == CPP_COLON && !(token2->flags & PREV_WHITE))
   34768                 :           3 :         return true;
   34769                 :             :     }
   34770                 :             :   return false;
   34771                 :             : }
   34772                 :             : 
   34773                 :             : /* Returns the kind of tag indicated by TOKEN, if it is a class-key,
   34774                 :             :    or none_type otherwise.  */
   34775                 :             : 
   34776                 :             : static enum tag_types
   34777                 :    46764553 : cp_parser_token_is_class_key (cp_token* token)
   34778                 :             : {
   34779                 :    46764553 :   switch (token->keyword)
   34780                 :             :     {
   34781                 :             :     case RID_CLASS:
   34782                 :             :       return class_type;
   34783                 :    35420268 :     case RID_STRUCT:
   34784                 :    35420268 :       return record_type;
   34785                 :      524575 :     case RID_UNION:
   34786                 :      524575 :       return union_type;
   34787                 :             : 
   34788                 :           0 :     default:
   34789                 :           0 :       return none_type;
   34790                 :             :     }
   34791                 :             : }
   34792                 :             : 
   34793                 :             : /* Returns the kind of tag indicated by TOKEN, if it is a type-parameter-key,
   34794                 :             :    or none_type otherwise or if the token is null.  */
   34795                 :             : 
   34796                 :             : static enum tag_types
   34797                 :      296580 : cp_parser_token_is_type_parameter_key (cp_token* token)
   34798                 :             : {
   34799                 :      296580 :   if (!token)
   34800                 :             :     return none_type;
   34801                 :             : 
   34802                 :      296580 :   switch (token->keyword)
   34803                 :             :     {
   34804                 :             :     case RID_CLASS:
   34805                 :             :       return class_type;
   34806                 :           0 :     case RID_TYPENAME:
   34807                 :           0 :       return typename_type;
   34808                 :             : 
   34809                 :             :     default:
   34810                 :             :       return none_type;
   34811                 :             :     }
   34812                 :             : }
   34813                 :             : 
   34814                 :             : /* Diagnose redundant enum-keys.  */
   34815                 :             : 
   34816                 :             : static void
   34817                 :       26309 : cp_parser_maybe_warn_enum_key (cp_parser *parser, location_t key_loc,
   34818                 :             :                                tree type, rid scoped_key)
   34819                 :             : {
   34820                 :       26309 :   if (!warn_redundant_tags)
   34821                 :       26173 :     return;
   34822                 :             : 
   34823                 :         208 :   tree type_decl = TYPE_MAIN_DECL (type);
   34824                 :         208 :   tree name = DECL_NAME (type_decl);
   34825                 :             :   /* Look up the NAME to see if it unambiguously refers to the TYPE.  */
   34826                 :         208 :   push_deferring_access_checks (dk_no_check);
   34827                 :         208 :   tree decl = cp_parser_lookup_name_simple (parser, name, input_location);
   34828                 :         208 :   pop_deferring_access_checks ();
   34829                 :             : 
   34830                 :             :   /* The enum-key is redundant for uses of the TYPE that are not
   34831                 :             :      declarations and for which name lookup returns just the type
   34832                 :             :      itself.  */
   34833                 :         208 :   if (decl != type_decl)
   34834                 :             :     return;
   34835                 :             : 
   34836                 :         168 :   if (scoped_key != RID_CLASS
   34837                 :         168 :       && scoped_key != RID_STRUCT
   34838                 :         105 :       && current_lang_name != lang_name_cplusplus
   34839                 :          44 :       && current_namespace == global_namespace)
   34840                 :             :     {
   34841                 :             :       /* Avoid issuing the diagnostic for apparently redundant (unscoped)
   34842                 :             :          enum tag in shared C/C++ code in files (such as headers) included
   34843                 :             :          in the main source file.  */
   34844                 :          36 :       const line_map_ordinary *map = NULL;
   34845                 :          36 :       linemap_resolve_location (line_table, key_loc,
   34846                 :             :                                 LRK_MACRO_DEFINITION_LOCATION,
   34847                 :             :                                 &map);
   34848                 :          36 :       if (!MAIN_FILE_P (map))
   34849                 :          32 :         return;
   34850                 :             :     }
   34851                 :             : 
   34852                 :         136 :   gcc_rich_location richloc (key_loc);
   34853                 :         136 :   richloc.add_fixit_remove (key_loc);
   34854                 :         242 :   warning_at (&richloc, OPT_Wredundant_tags,
   34855                 :             :               "redundant enum-key %<enum%s%> in reference to %q#T",
   34856                 :             :               (scoped_key == RID_CLASS ? " class"
   34857                 :         106 :                : scoped_key == RID_STRUCT ? " struct" : ""), type);
   34858                 :         136 : }
   34859                 :             : 
   34860                 :             : /* Describes the set of declarations of a struct, class, or class template
   34861                 :             :    or its specializations.  Used for -Wmismatched-tags.  */
   34862                 :             : 
   34863                 :             : class class_decl_loc_t
   34864                 :             : {
   34865                 :             :  public:
   34866                 :             : 
   34867                 :         858 :   class_decl_loc_t ()
   34868                 :         858 :     : locvec (), idxdef (), def_class_key ()
   34869                 :             :   {
   34870                 :         858 :     locvec.create (4);
   34871                 :         858 :   }
   34872                 :             : 
   34873                 :             :   /* Constructs an object for a single declaration of a class with
   34874                 :             :      CLASS_KEY at the current location in the current function (or
   34875                 :             :      at another scope).  KEY_REDUNDANT is true if the class-key may
   34876                 :             :      be omitted in the current context without an ambiguity with
   34877                 :             :      another symbol with the same name.
   34878                 :             :      DEF_P is true for a class declaration that is a definition.
   34879                 :             :      CURLOC is the associated location.  */
   34880                 :         858 :   class_decl_loc_t (tag_types class_key, bool key_redundant, bool def_p,
   34881                 :             :                     location_t curloc = input_location)
   34882                 :         858 :     : locvec (), idxdef (def_p ? 0 : UINT_MAX), def_class_key (class_key)
   34883                 :             :   {
   34884                 :         858 :     locvec.create (4);
   34885                 :         858 :     class_key_loc_t ckl (current_function_decl, curloc, class_key,
   34886                 :         858 :                          key_redundant);
   34887                 :        1716 :     locvec.quick_push (ckl);
   34888                 :         858 :   }
   34889                 :             : 
   34890                 :             :   /* Copy, assign, and destroy the object.  Necessary because LOCVEC
   34891                 :             :      isn't safely copyable and assignable and doesn't release storage
   34892                 :             :      on its own.  */
   34893                 :         552 :   class_decl_loc_t (const class_decl_loc_t &rhs)
   34894                 :         552 :     : locvec (rhs.locvec.copy ()), idxdef (rhs.idxdef),
   34895                 :         552 :       def_class_key (rhs.def_class_key)
   34896                 :             :   { }
   34897                 :             : 
   34898                 :         858 :   class_decl_loc_t& operator= (const class_decl_loc_t &rhs)
   34899                 :             :   {
   34900                 :         858 :     if (this == &rhs)
   34901                 :             :       return *this;
   34902                 :         858 :     locvec.release ();
   34903                 :         858 :     locvec = rhs.locvec.copy ();
   34904                 :         858 :     idxdef = rhs.idxdef;
   34905                 :         858 :     def_class_key = rhs.def_class_key;
   34906                 :         858 :     return *this;
   34907                 :             :   }
   34908                 :             : 
   34909                 :        2268 :   ~class_decl_loc_t ()
   34910                 :             :   {
   34911                 :        1410 :     locvec.release ();
   34912                 :         858 :   }
   34913                 :             : 
   34914                 :             :   /* Issues -Wmismatched-tags for a single class.  */
   34915                 :             :   void diag_mismatched_tags (tree);
   34916                 :             : 
   34917                 :             :   /* Issues -Wmismatched-tags for all classes.  */
   34918                 :             :   static void diag_mismatched_tags ();
   34919                 :             : 
   34920                 :             :   /* Adds TYPE_DECL to the collection of class decls and diagnoses
   34921                 :             :      redundant tags (if -Wredundant-tags is enabled).  */
   34922                 :             :   static void add (cp_parser *, location_t, tag_types, tree, bool, bool);
   34923                 :             : 
   34924                 :             :   /* Either adds this decl to the collection of class decls
   34925                 :             :      or diagnoses it, whichever is appropriate.  */
   34926                 :             :   void add_or_diag_mismatched_tag (tree, tag_types, bool, bool);
   34927                 :             : 
   34928                 :             : private:
   34929                 :             : 
   34930                 :         379 :   tree function (unsigned i) const
   34931                 :             :   {
   34932                 :         379 :     return locvec[i].func;
   34933                 :             :   }
   34934                 :             : 
   34935                 :         676 :   location_t location (unsigned i) const
   34936                 :             :   {
   34937                 :         297 :     return locvec[i].loc;
   34938                 :             :   }
   34939                 :             : 
   34940                 :         379 :   bool key_redundant (unsigned i) const
   34941                 :             :   {
   34942                 :         379 :     return locvec[i].key_redundant;
   34943                 :             :   }
   34944                 :             : 
   34945                 :        1416 :   tag_types class_key (unsigned i) const
   34946                 :             :   {
   34947                 :        2832 :     return locvec[i].class_key;
   34948                 :             :   }
   34949                 :             : 
   34950                 :             :   /* True if a definition for the class has been seen.  */
   34951                 :         416 :   bool def_p () const
   34952                 :             :   {
   34953                 :        1248 :     return idxdef < locvec.length ();
   34954                 :             :   }
   34955                 :             : 
   34956                 :             :   /* The location of a single mention of a class type with the given
   34957                 :             :      class-key.  */
   34958                 :             :   struct class_key_loc_t
   34959                 :             :   {
   34960                 :        1648 :     class_key_loc_t (tree func, location_t loc, tag_types key, bool redundant)
   34961                 :         858 :       : func (func), loc (loc), class_key (key), key_redundant (redundant)
   34962                 :             :     { }
   34963                 :             : 
   34964                 :             :     /* The function the type is mentioned in.  */
   34965                 :             :     tree func;
   34966                 :             :     /* The exact location.  */
   34967                 :             :     location_t loc;
   34968                 :             :     /* The class-key used in the mention of the type.  */
   34969                 :             :     tag_types class_key;
   34970                 :             :     /* True when the class-key could be omitted at this location
   34971                 :             :        without an ambiguity with another symbol of the same name.  */
   34972                 :             :     bool key_redundant;
   34973                 :             :   };
   34974                 :             :   /* Avoid using auto_vec here since it's not safe to copy due to pr90904.  */
   34975                 :             :   vec <class_key_loc_t> locvec;
   34976                 :             :   /* LOCVEC index of the definition or UINT_MAX if none exists.  */
   34977                 :             :   unsigned idxdef;
   34978                 :             :   /* The class-key the class was last declared with or none_type when
   34979                 :             :      it has been declared with a mismatched key.  */
   34980                 :             :   tag_types def_class_key;
   34981                 :             : 
   34982                 :             :   /* A mapping between a TYPE_DECL for a class and the class_decl_loc_t
   34983                 :             :      description above.  */
   34984                 :             :   typedef hash_map<tree_decl_hash, class_decl_loc_t> class_to_loc_map_t;
   34985                 :             :   static class_to_loc_map_t class2loc;
   34986                 :             : };
   34987                 :             : 
   34988                 :             : class_decl_loc_t::class_to_loc_map_t class_decl_loc_t::class2loc;
   34989                 :             : 
   34990                 :             : /* Issue an error message if the CLASS_KEY does not match the TYPE.
   34991                 :             :    DEF_P is expected to be set for a definition of class TYPE.  DECL_P
   34992                 :             :    is set for a declaration of class TYPE and clear for a reference to
   34993                 :             :    it that is not a declaration of it.  */
   34994                 :             : 
   34995                 :             : static void
   34996                 :    35242822 : cp_parser_check_class_key (cp_parser *parser, location_t key_loc,
   34997                 :             :                            tag_types class_key, tree type, bool def_p,
   34998                 :             :                            bool decl_p)
   34999                 :             : {
   35000                 :    35242822 :   if (type == error_mark_node)
   35001                 :             :     return;
   35002                 :             : 
   35003                 :    35242556 :   bool seen_as_union = TREE_CODE (type) == UNION_TYPE;
   35004                 :    35242556 :   if (seen_as_union != (class_key == union_type))
   35005                 :             :     {
   35006                 :          32 :       if (permerror (input_location, "%qs tag used in naming %q#T",
   35007                 :             :                      class_key == union_type ? "union"
   35008                 :           8 :                      : class_key == record_type ? "struct" : "class",
   35009                 :             :                      type))
   35010                 :          24 :         inform (DECL_SOURCE_LOCATION (TYPE_NAME (type)),
   35011                 :             :                 "%q#T was previously declared here", type);
   35012                 :          24 :       return;
   35013                 :             :     }
   35014                 :             : 
   35015                 :    35242532 :   if (!warn_mismatched_tags && !warn_redundant_tags)
   35016                 :             :     return;
   35017                 :             : 
   35018                 :             :   /* Only consider the true class-keys below and ignore typename_type,
   35019                 :             :      etc. that are not C++ class-keys.  */
   35020                 :        1996 :   if (class_key != class_type
   35021                 :             :       && class_key != record_type
   35022                 :        1996 :       && class_key != union_type)
   35023                 :             :     return;
   35024                 :             : 
   35025                 :        1968 :   class_decl_loc_t::add (parser, key_loc, class_key, type, def_p, decl_p);
   35026                 :             : }
   35027                 :             : 
   35028                 :             : /* Returns the template or specialization of one to which the RECORD_TYPE
   35029                 :             :    TYPE corresponds.  */
   35030                 :             : 
   35031                 :             : static tree
   35032                 :          90 : specialization_of (tree type)
   35033                 :             : {
   35034                 :          90 :   tree ret = type;
   35035                 :             : 
   35036                 :             :   /* Determine the template or its partial specialization to which TYPE
   35037                 :             :      corresponds.  */
   35038                 :          90 :   if (tree ti = most_specialized_partial_spec (type, tf_none))
   35039                 :          47 :     if (ti != error_mark_node)
   35040                 :          47 :       ret = TREE_TYPE (TI_TEMPLATE (ti));
   35041                 :             : 
   35042                 :          90 :   if (ret == type)
   35043                 :          43 :     ret = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (type);
   35044                 :             : 
   35045                 :          90 :   return TYPE_MAIN_DECL (ret);
   35046                 :             : }
   35047                 :             : 
   35048                 :             : 
   35049                 :             : /* Adds the class TYPE to the collection of class decls and diagnoses
   35050                 :             :    redundant tags (if -Wredundant-tags is enabled).
   35051                 :             :    DEF_P is expected to be set for a definition of class TYPE.  DECL_P
   35052                 :             :    is set for a (likely, based on syntactic context) declaration of class
   35053                 :             :    TYPE and clear for a reference to it that is not a declaration of it.  */
   35054                 :             : 
   35055                 :             : void
   35056                 :        1968 : class_decl_loc_t::add (cp_parser *parser, location_t key_loc,
   35057                 :             :                        tag_types class_key, tree type, bool def_p, bool decl_p)
   35058                 :             : {
   35059                 :        1968 :   tree type_decl = TYPE_MAIN_DECL (type);
   35060                 :        1968 :   tree name = DECL_NAME (type_decl);
   35061                 :             :   /* Look up the NAME to see if it unambiguously refers to the TYPE
   35062                 :             :      and set KEY_REDUNDANT if so.  */
   35063                 :        1968 :   push_deferring_access_checks (dk_no_check);
   35064                 :        1968 :   tree decl = cp_parser_lookup_name_simple (parser, name, input_location);
   35065                 :        1968 :   pop_deferring_access_checks ();
   35066                 :             : 
   35067                 :             :   /* The class-key is redundant for uses of the CLASS_TYPE that are
   35068                 :             :      neither definitions of it nor declarations, and for which name
   35069                 :             :      lookup returns just the type itself.  */
   35070                 :        1968 :   bool key_redundant = (!def_p && !decl_p
   35071                 :        1968 :                         && (decl == type_decl
   35072                 :         448 :                             || TREE_CODE (decl) == TEMPLATE_DECL
   35073                 :          51 :                             || (CLASS_TYPE_P (type)
   35074                 :          48 :                                 && TYPE_BEING_DEFINED (type))));
   35075                 :             : 
   35076                 :        1968 :   if (key_redundant
   35077                 :        1968 :       && class_key != class_type
   35078                 :         549 :       && current_lang_name != lang_name_cplusplus
   35079                 :          76 :       && current_namespace == global_namespace)
   35080                 :             :     {
   35081                 :             :       /* Avoid issuing the diagnostic for apparently redundant struct
   35082                 :             :          and union class-keys in shared C/C++ code in files (such as
   35083                 :             :          headers) included in the main source file.  */
   35084                 :          60 :       const line_map_ordinary *map = NULL;
   35085                 :          60 :       linemap_resolve_location (line_table, key_loc,
   35086                 :             :                                 LRK_MACRO_DEFINITION_LOCATION,
   35087                 :             :                                 &map);
   35088                 :          60 :       if (!MAIN_FILE_P (map))
   35089                 :          52 :         key_redundant = false;
   35090                 :             :     }
   35091                 :             : 
   35092                 :             :   /* Set if a declaration of TYPE has previously been seen or if it must
   35093                 :             :      exist in a precompiled header.  */
   35094                 :        1968 :   bool exist;
   35095                 :        1968 :   class_decl_loc_t *rdl = &class2loc.get_or_insert (type_decl, &exist);
   35096                 :        1968 :   if (!exist)
   35097                 :             :     {
   35098                 :         858 :       tree type = TREE_TYPE (type_decl);
   35099                 :         858 :       if (def_p || !COMPLETE_TYPE_P (type))
   35100                 :             :         {
   35101                 :             :           /* TYPE_DECL is the first declaration or definition of the type
   35102                 :             :              (outside precompiled headers -- see below).  Just create
   35103                 :             :              a new entry for it and return unless it's a declaration
   35104                 :             :              involving a template that may need to be diagnosed by
   35105                 :             :              -Wredundant-tags.  */
   35106                 :         852 :           *rdl = class_decl_loc_t (class_key, false, def_p);
   35107                 :         852 :           if (TREE_CODE (decl) != TEMPLATE_DECL)
   35108                 :        1178 :             return;
   35109                 :             :         }
   35110                 :             :       else
   35111                 :             :         {
   35112                 :             :           /* TYPE was previously defined in some unknown precompiled header.
   35113                 :             :              Simply add a record of its definition at an unknown location and
   35114                 :             :              proceed below to add a reference to it at the current location.
   35115                 :             :              (Declarations in precompiled headers that are not definitions
   35116                 :             :              are ignored.)  */
   35117                 :           6 :           tag_types def_key
   35118                 :           6 :             = CLASSTYPE_DECLARED_CLASS (type) ? class_type : record_type;
   35119                 :           6 :           location_t def_loc = DECL_SOURCE_LOCATION (type_decl);
   35120                 :           6 :           *rdl = class_decl_loc_t (def_key, false, true, def_loc);
   35121                 :           6 :           exist = true;
   35122                 :             :         }
   35123                 :             :     }
   35124                 :             : 
   35125                 :             :   /* A prior declaration of TYPE_DECL has been seen.  */
   35126                 :             : 
   35127                 :        1575 :   if (key_redundant)
   35128                 :             :     {
   35129                 :         830 :       gcc_rich_location richloc (key_loc);
   35130                 :         830 :       richloc.add_fixit_remove (key_loc);
   35131                 :        1588 :       warning_at (&richloc, OPT_Wredundant_tags,
   35132                 :             :                   "redundant class-key %qs in reference to %q#T",
   35133                 :             :                   class_key == union_type ? "union"
   35134                 :         758 :                   : class_key == record_type ? "struct" : "class",
   35135                 :             :                   type);
   35136                 :         830 :     }
   35137                 :             : 
   35138                 :        1575 :   if (!exist)
   35139                 :             :     /* Do nothing if this is the first declaration of the type.  */
   35140                 :             :     return;
   35141                 :             : 
   35142                 :        1116 :   if (rdl->idxdef != UINT_MAX && rdl->def_class_key == class_key)
   35143                 :             :     /* Do nothing if the class-key in this declaration matches
   35144                 :             :        the definition.  */
   35145                 :             :     return;
   35146                 :             : 
   35147                 :         790 :   rdl->add_or_diag_mismatched_tag (type_decl, class_key, key_redundant,
   35148                 :             :                                    def_p);
   35149                 :             : }
   35150                 :             : 
   35151                 :             : /* Either adds this DECL corresponding to the TYPE_DECL to the collection
   35152                 :             :    of class decls or diagnoses it, whichever is appropriate.  */
   35153                 :             : 
   35154                 :             : void
   35155                 :         790 : class_decl_loc_t::add_or_diag_mismatched_tag (tree type_decl,
   35156                 :             :                                               tag_types class_key,
   35157                 :             :                                               bool redundant,
   35158                 :             :                                               bool def_p)
   35159                 :             : {
   35160                 :             :   /* Reset the CLASS_KEY associated with this type on mismatch.
   35161                 :             :      This is an optimization that lets the diagnostic code skip
   35162                 :             :      over classes that use the same class-key in all declarations.  */
   35163                 :         790 :   if (def_class_key != class_key)
   35164                 :         531 :     def_class_key = none_type;
   35165                 :             : 
   35166                 :             :   /* Set IDXDEF to the index of the vector corresponding to
   35167                 :             :      the definition.  */
   35168                 :         790 :   if (def_p)
   35169                 :         104 :     idxdef = locvec.length ();
   35170                 :             : 
   35171                 :             :   /* Append a record of this declaration to the vector.  */
   35172                 :         790 :   class_key_loc_t ckl (current_function_decl, input_location, class_key,
   35173                 :         790 :                        redundant);
   35174                 :         790 :   locvec.safe_push (ckl);
   35175                 :             : 
   35176                 :         790 :   if (idxdef == UINT_MAX)
   35177                 :         635 :     return;
   35178                 :             : 
   35179                 :             :   /* As a space optimization diagnose declarations of a class
   35180                 :             :      whose definition has been seen and purge the LOCVEC of
   35181                 :             :      all entries except the definition.  */
   35182                 :         155 :   diag_mismatched_tags (type_decl);
   35183                 :         155 :   if (idxdef)
   35184                 :             :     {
   35185                 :          52 :       class_decl_loc_t::class_key_loc_t ent = locvec[idxdef];
   35186                 :          52 :       locvec.release ();
   35187                 :          52 :       locvec.reserve (2);
   35188                 :          52 :       locvec.safe_push (ent);
   35189                 :          52 :       idxdef = 0;
   35190                 :             :     }
   35191                 :             :   else
   35192                 :             :     /* Pop the entry pushed above for this declaration.  */
   35193                 :         103 :     locvec.pop ();
   35194                 :             : }
   35195                 :             : 
   35196                 :             : /* Issues -Wmismatched-tags for a single class.  */
   35197                 :             : 
   35198                 :             : void
   35199                 :         775 : class_decl_loc_t::diag_mismatched_tags (tree type_decl)
   35200                 :             : {
   35201                 :         775 :   if (!warn_mismatched_tags)
   35202                 :         470 :     return;
   35203                 :             : 
   35204                 :             :   /* Number of uses of the class.  */
   35205                 :         771 :   const unsigned ndecls = locvec.length ();
   35206                 :             : 
   35207                 :             :   /* The class (or template) declaration guiding the decisions about
   35208                 :             :      the diagnostic.  For ordinary classes it's the same as THIS.  For
   35209                 :             :      uses of instantiations of templates other than their declarations
   35210                 :             :      it points to the record for the declaration of the corresponding
   35211                 :             :      primary template or partial specialization.  */
   35212                 :         771 :   class_decl_loc_t *cdlguide = this;
   35213                 :             : 
   35214                 :         771 :   tree type = TREE_TYPE (type_decl);
   35215                 :         771 :   if (CLASS_TYPE_P (type) && CLASSTYPE_IMPLICIT_INSTANTIATION (type))
   35216                 :             :     {
   35217                 :             :       /* For implicit instantiations of a primary template look up
   35218                 :             :          the primary or partial specialization and use it as
   35219                 :             :          the expected class-key rather than using the class-key of
   35220                 :             :          the first reference to the instantiation.  The primary must
   35221                 :             :          be (and inevitably is) at index zero.  */
   35222                 :          90 :       tree spec = specialization_of (type);
   35223                 :          90 :       cdlguide = class2loc.get (spec);
   35224                 :             :       /* It's possible that we didn't find SPEC.  Consider:
   35225                 :             : 
   35226                 :             :            template<typename T> struct A {
   35227                 :             :              template<typename U> struct W { };
   35228                 :             :            };
   35229                 :             :            struct A<int>::W<int> w; // #1
   35230                 :             : 
   35231                 :             :          where while parsing A and #1 we've stashed
   35232                 :             :            A<T>
   35233                 :             :            A<T>::W<U>
   35234                 :             :            A<int>::W<int>
   35235                 :             :          into CLASS2LOC.  If TYPE is A<int>::W<int>, specialization_of
   35236                 :             :          will yield A<int>::W<U> which may be in CLASS2LOC if we had
   35237                 :             :          an A<int> class specialization, but otherwise won't be in it.
   35238                 :             :          So try to look up A<T>::W<U>.  */
   35239                 :          90 :       if (!cdlguide)
   35240                 :             :         {
   35241                 :           4 :           spec = DECL_TEMPLATE_RESULT (most_general_template (spec));
   35242                 :           4 :           cdlguide = class2loc.get (spec);
   35243                 :             :         }
   35244                 :             :       /* Now we really should have found something.  */
   35245                 :           4 :       gcc_assert (cdlguide != NULL);
   35246                 :             :     }
   35247                 :             :   /* Skip declarations that consistently use the same class-key.  */
   35248                 :         681 :   else if (def_class_key != none_type)
   35249                 :             :     return;
   35250                 :             : 
   35251                 :             :   /* Set if a definition for the class has been seen.  */
   35252                 :         416 :   const bool def_p = cdlguide->def_p ();
   35253                 :             : 
   35254                 :             :   /* The index of the declaration whose class-key this declaration
   35255                 :             :      is expected to match.  It's either the class-key of the class
   35256                 :             :      definition if one exists or the first declaration otherwise.  */
   35257                 :         416 :   const unsigned idxguide = def_p ? cdlguide->idxdef : 0;
   35258                 :             : 
   35259                 :             :   /* The class-key the class is expected to be declared with: it's
   35260                 :             :      either the key used in its definition or the first declaration
   35261                 :             :      if no definition has been provided.
   35262                 :             :      For implicit instantiations of a primary template it's
   35263                 :             :      the class-key used to declare the primary with.  The primary
   35264                 :             :      must be at index zero.  */
   35265                 :         416 :   const tag_types xpect_key = cdlguide->class_key (idxguide);
   35266                 :             : 
   35267                 :         416 :   unsigned idx = 0;
   35268                 :             :   /* Advance IDX to the first declaration that either is not
   35269                 :             :      a definition or that doesn't match the first declaration
   35270                 :             :      if no definition is provided.  */
   35271                 :         755 :   while (class_key (idx) == xpect_key)
   35272                 :         450 :     if (++idx == ndecls)
   35273                 :             :       return;
   35274                 :             : 
   35275                 :             :   /* Save the current function before changing it below.  */
   35276                 :         305 :   tree save_func = current_function_decl;
   35277                 :             :   /* Set the function declaration to print in diagnostic context.  */
   35278                 :         305 :   current_function_decl = function (idx);
   35279                 :             : 
   35280                 :         305 :   const char *xmatchkstr = xpect_key == record_type ? "class" : "struct";
   35281                 :         171 :   const char *xpectkstr = xpect_key == record_type ? "struct" : "class";
   35282                 :             : 
   35283                 :         305 :   location_t loc = location (idx);
   35284                 :         305 :   bool key_redundant_p = key_redundant (idx);
   35285                 :         305 :   auto_diagnostic_group d;
   35286                 :             :   /* Issue a warning for the first mismatched declaration.
   35287                 :             :      Avoid using "%#qT" since the class-key for the same type will
   35288                 :             :      be the same regardless of which one was used in the declaraion.  */
   35289                 :         305 :   if (warning_at (loc, OPT_Wmismatched_tags,
   35290                 :             :                   "%qT declared with a mismatched class-key %qs",
   35291                 :             :                   type_decl, xmatchkstr))
   35292                 :             :     {
   35293                 :             :       /* Suggest how to avoid the warning for each instance since
   35294                 :             :          the guidance may be different depending on context.  */
   35295                 :         475 :       inform (loc,
   35296                 :             :               (key_redundant_p
   35297                 :             :                ? G_("remove the class-key or replace it with %qs")
   35298                 :             :                : G_("replace the class-key with %qs")),
   35299                 :             :               xpectkstr);
   35300                 :             : 
   35301                 :             :       /* Also point to the first declaration or definition that guided
   35302                 :             :          the decision to issue the warning above.  */
   35303                 :         594 :       inform (cdlguide->location (idxguide),
   35304                 :             :               (def_p
   35305                 :             :                ? G_("%qT defined as %qs here")
   35306                 :             :                : G_("%qT first declared as %qs here")),
   35307                 :             :               type_decl, xpectkstr);
   35308                 :             :     }
   35309                 :             : 
   35310                 :             :   /* Issue warnings for the remaining inconsistent declarations.  */
   35311                 :         550 :   for (unsigned i = idx + 1; i != ndecls; ++i)
   35312                 :             :     {
   35313                 :         245 :       tag_types clskey = class_key (i);
   35314                 :             :       /* Skip over the declarations that match either the definition
   35315                 :             :          if one was provided or the first declaration.  */
   35316                 :         245 :       if (clskey == xpect_key)
   35317                 :         171 :         continue;
   35318                 :             : 
   35319                 :          74 :       loc = location (i);
   35320                 :          74 :       key_redundant_p = key_redundant (i);
   35321                 :             :       /* Set the function declaration to print in diagnostic context.  */
   35322                 :          74 :       current_function_decl = function (i);
   35323                 :          74 :       if (warning_at (loc, OPT_Wmismatched_tags,
   35324                 :             :                       "%qT declared with a mismatched class-key %qs",
   35325                 :             :                       type_decl, xmatchkstr))
   35326                 :             :         /* Suggest how to avoid the warning for each instance since
   35327                 :             :            the guidance may be different depending on context.  */
   35328                 :          82 :         inform (loc,
   35329                 :             :                 (key_redundant_p
   35330                 :             :                  ? G_("remove the class-key or replace it with %qs")
   35331                 :             :                  : G_("replace the class-key with %qs")),
   35332                 :             :                 xpectkstr);
   35333                 :             :     }
   35334                 :             : 
   35335                 :             :   /* Restore the current function in case it was replaced above.  */
   35336                 :         305 :   current_function_decl = save_func;
   35337                 :         305 : }
   35338                 :             : 
   35339                 :             : /* Issues -Wmismatched-tags for all classes.  Called at the end
   35340                 :             :    of processing a translation unit, after declarations of all class
   35341                 :             :    types and their uses have been recorded.  */
   35342                 :             : 
   35343                 :             : void
   35344                 :       99762 : class_decl_loc_t::diag_mismatched_tags ()
   35345                 :             : {
   35346                 :             :   /* CLASS2LOC should be empty if both -Wmismatched-tags and
   35347                 :             :      -Wredundant-tags are disabled.  */
   35348                 :       99762 :   gcc_assert (warn_mismatched_tags
   35349                 :             :               || warn_redundant_tags
   35350                 :             :               || class2loc.is_empty ());
   35351                 :             : 
   35352                 :             :   /* Save the current function before changing on return.  It should
   35353                 :             :      be null at this point.  */
   35354                 :       99762 :   temp_override<tree> cleanup (current_function_decl);
   35355                 :             : 
   35356                 :       99762 :   if (warn_mismatched_tags)
   35357                 :             :     {
   35358                 :             :       /* Iterate over the collected class/struct/template declarations.  */
   35359                 :          47 :       typedef class_to_loc_map_t::iterator iter_t;
   35360                 :        1334 :       for (iter_t it = class2loc.begin (); it != class2loc.end (); ++it)
   35361                 :             :         {
   35362                 :         620 :           tree type_decl = (*it).first;
   35363                 :         620 :           class_decl_loc_t &recloc = (*it).second;
   35364                 :         620 :           recloc.diag_mismatched_tags (type_decl);
   35365                 :             :         }
   35366                 :             :     }
   35367                 :             : 
   35368                 :       99762 :   class2loc.empty ();
   35369                 :       99762 : }
   35370                 :             : 
   35371                 :             : /* Issue an error message if DECL is redeclared with different
   35372                 :             :    access than its original declaration [class.access.spec/3].
   35373                 :             :    This applies to nested classes, nested class templates and
   35374                 :             :    enumerations [class.mem/1].  */
   35375                 :             : 
   35376                 :             : static void
   35377                 :     2974767 : cp_parser_check_access_in_redeclaration (tree decl, location_t location)
   35378                 :             : {
   35379                 :     2974767 :   if (!decl
   35380                 :     2974767 :       || (!(CLASS_TYPE_P (TREE_TYPE (decl))
   35381                 :     2155713 :             && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
   35382                 :     1308288 :           && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE))
   35383                 :             :     return;
   35384                 :             : 
   35385                 :     2485533 :   if ((TREE_PRIVATE (decl)
   35386                 :     2485533 :        != (current_access_specifier == access_private_node))
   35387                 :     2485519 :       || (TREE_PROTECTED (decl)
   35388                 :     2485519 :           != (current_access_specifier == access_protected_node)))
   35389                 :          14 :     error_at (location, "%qD redeclared with different access", decl);
   35390                 :             : }
   35391                 :             : 
   35392                 :             : /* Look for the `template' keyword, as a syntactic disambiguator.
   35393                 :             :    Return TRUE iff it is present, in which case it will be
   35394                 :             :    consumed.  */
   35395                 :             : 
   35396                 :             : static bool
   35397                 :   440041054 : cp_parser_optional_template_keyword (cp_parser *parser)
   35398                 :             : {
   35399                 :   440041054 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
   35400                 :             :     {
   35401                 :             :       /* In C++98 the `template' keyword can only be used within templates;
   35402                 :             :          outside templates the parser can always figure out what is a
   35403                 :             :          template and what is not.  In C++11,  per the resolution of DR 468,
   35404                 :             :          `template' is allowed in cases where it is not strictly necessary.  */
   35405                 :     1856947 :       if (!processing_template_decl
   35406                 :         144 :           && pedantic && cxx_dialect == cxx98)
   35407                 :             :         {
   35408                 :           6 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   35409                 :           6 :           pedwarn (token->location, OPT_Wpedantic,
   35410                 :             :                    "in C++98 %<template%> (as a disambiguator) is only "
   35411                 :             :                    "allowed within templates");
   35412                 :             :           /* If this part of the token stream is rescanned, the same
   35413                 :             :              error message would be generated.  So, we purge the token
   35414                 :             :              from the stream.  */
   35415                 :           6 :           cp_lexer_purge_token (parser->lexer);
   35416                 :           6 :           return false;
   35417                 :             :         }
   35418                 :             :       else
   35419                 :             :         {
   35420                 :             :           /* Consume the `template' keyword.  */
   35421                 :     1856941 :           cp_lexer_consume_token (parser->lexer);
   35422                 :     1856941 :           return true;
   35423                 :             :         }
   35424                 :             :     }
   35425                 :             :   return false;
   35426                 :             : }
   35427                 :             : 
   35428                 :             : /* The next token is a CPP_NESTED_NAME_SPECIFIER.  Consume the token,
   35429                 :             :    set PARSER->SCOPE, and perform other related actions.  */
   35430                 :             : 
   35431                 :             : static void
   35432                 :   134547564 : cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
   35433                 :             : {
   35434                 :   134547564 :   struct tree_check *check_value;
   35435                 :             : 
   35436                 :             :   /* Get the stored value.  */
   35437                 :   134547564 :   check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
   35438                 :             :   /* Set the scope from the stored value.  */
   35439                 :   134547564 :   parser->scope = saved_checks_value (check_value);
   35440                 :   134547564 :   parser->qualifying_scope = check_value->qualifying_scope;
   35441                 :   134547564 :   parser->object_scope = parser->context->object_type;
   35442                 :   134547564 :   parser->context->object_type = NULL_TREE;
   35443                 :   134547564 : }
   35444                 :             : 
   35445                 :             : /* Consume tokens up through a non-nested END token.  Returns TRUE if we
   35446                 :             :    encounter the end of a block before what we were looking for.  */
   35447                 :             : 
   35448                 :             : static bool
   35449                 :   297139083 : cp_parser_cache_group (cp_parser *parser,
   35450                 :             :                        enum cpp_ttype end,
   35451                 :             :                        unsigned depth)
   35452                 :             : {
   35453                 :  1285833634 :   while (true)
   35454                 :             :     {
   35455                 :  1285833634 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   35456                 :             : 
   35457                 :             :       /* Abort a parenthesized expression if we encounter a semicolon.  */
   35458                 :  1285833634 :       if ((end == CPP_CLOSE_PAREN || depth == 0)
   35459                 :   670302335 :           && token->type == CPP_SEMICOLON)
   35460                 :             :         return true;
   35461                 :             :       /* If we've reached the end of the file, stop.  */
   35462                 :  1284975853 :       if (token->type == CPP_EOF
   35463                 :  1284975838 :           || (end != CPP_PRAGMA_EOL
   35464                 :  1284958613 :               && token->type == CPP_PRAGMA_EOL))
   35465                 :             :         return true;
   35466                 :  1284975838 :       if (token->type == CPP_CLOSE_BRACE && depth == 0)
   35467                 :             :         /* We've hit the end of an enclosing block, so there's been some
   35468                 :             :            kind of syntax error.  */
   35469                 :             :         return true;
   35470                 :             : 
   35471                 :             :       /* Consume the token.  */
   35472                 :  1284975824 :       cp_lexer_consume_token (parser->lexer);
   35473                 :             :       /* See if it starts a new group.  */
   35474                 :  1284975824 :       if (token->type == CPP_OPEN_BRACE)
   35475                 :             :         {
   35476                 :    70715184 :           cp_parser_cache_group (parser, CPP_CLOSE_BRACE, depth + 1);
   35477                 :             :           /* In theory this should probably check end == '}', but
   35478                 :             :              cp_parser_save_member_function_body needs it to exit
   35479                 :             :              after either '}' or ')' when called with ')'.  */
   35480                 :    70715184 :           if (depth == 0)
   35481                 :             :             return false;
   35482                 :             :         }
   35483                 :  1214260640 :       else if (token->type == CPP_OPEN_PAREN)
   35484                 :             :         {
   35485                 :   144720029 :           cp_parser_cache_group (parser, CPP_CLOSE_PAREN, depth + 1);
   35486                 :   144720029 :           if (depth == 0 && end == CPP_CLOSE_PAREN)
   35487                 :             :             return false;
   35488                 :             :         }
   35489                 :  1069540611 :       else if (token->type == CPP_PRAGMA)
   35490                 :        7288 :         cp_parser_cache_group (parser, CPP_PRAGMA_EOL, depth + 1);
   35491                 :  1069533323 :       else if (token->type == end)
   35492                 :             :         return false;
   35493                 :             :     }
   35494                 :             : }
   35495                 :             : 
   35496                 :             : /* Like above, for caching a default argument or NSDMI.  Both of these are
   35497                 :             :    terminated by a non-nested comma, but it can be unclear whether or not a
   35498                 :             :    comma is nested in a template argument list unless we do more parsing.
   35499                 :             :    In order to handle this ambiguity, when we encounter a ',' after a '<'
   35500                 :             :    we try to parse what follows as a parameter-declaration-list (in the
   35501                 :             :    case of a default argument) or a member-declarator (in the case of an
   35502                 :             :    NSDMI).  If that succeeds, then we stop caching.  */
   35503                 :             : 
   35504                 :             : static tree
   35505                 :     6358318 : cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
   35506                 :             : {
   35507                 :     6358318 :   unsigned depth = 0;
   35508                 :     6358318 :   int maybe_template_id = 0;
   35509                 :     6358318 :   cp_token *first_token;
   35510                 :     6358318 :   cp_token *token;
   35511                 :     6358318 :   tree default_argument;
   35512                 :             : 
   35513                 :             :   /* Add tokens until we have processed the entire default
   35514                 :             :      argument.  We add the range [first_token, token).  */
   35515                 :     6358318 :   first_token = cp_lexer_peek_token (parser->lexer);
   35516                 :     6358318 :   if (first_token->type == CPP_OPEN_BRACE)
   35517                 :             :     {
   35518                 :             :       /* For list-initialization, this is straightforward.  */
   35519                 :      117692 :       cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
   35520                 :      117692 :       token = cp_lexer_peek_token (parser->lexer);
   35521                 :             :     }
   35522                 :    50112092 :   else while (true)
   35523                 :             :     {
   35524                 :    28176359 :       bool done = false;
   35525                 :             : 
   35526                 :             :       /* Peek at the next token.  */
   35527                 :    28176359 :       token = cp_lexer_peek_token (parser->lexer);
   35528                 :             :       /* What we do depends on what token we have.  */
   35529                 :    28176359 :       switch (token->type)
   35530                 :             :         {
   35531                 :             :           /* In valid code, a default argument must be
   35532                 :             :              immediately followed by a `,' `)', or `...'.  */
   35533                 :     2014219 :         case CPP_COMMA:
   35534                 :     2014219 :           if (depth == 0 && maybe_template_id)
   35535                 :             :             {
   35536                 :             :               /* If we've seen a '<', we might be in a
   35537                 :             :                  template-argument-list.  Until Core issue 325 is
   35538                 :             :                  resolved, we don't know how this situation ought
   35539                 :             :                  to be handled, so try to DTRT.  We check whether
   35540                 :             :                  what comes after the comma is a valid parameter
   35541                 :             :                  declaration list.  If it is, then the comma ends
   35542                 :             :                  the default argument; otherwise the default
   35543                 :             :                  argument continues.  */
   35544                 :        1117 :               bool error = false;
   35545                 :        1117 :               cp_token *peek;
   35546                 :             : 
   35547                 :             :               /* Set ITALP so cp_parser_parameter_declaration_list
   35548                 :             :                  doesn't decide to commit to this parse.  */
   35549                 :        1117 :               bool saved_italp = parser->in_template_argument_list_p;
   35550                 :        1117 :               parser->in_template_argument_list_p = true;
   35551                 :             : 
   35552                 :        1117 :               cp_parser_parse_tentatively (parser);
   35553                 :             : 
   35554                 :        1117 :               if (nsdmi)
   35555                 :             :                 {
   35556                 :             :                   /* Parse declarators until we reach a non-comma or
   35557                 :             :                      somthing that cannot be an initializer.
   35558                 :             :                      Just checking whether we're looking at a single
   35559                 :             :                      declarator is insufficient.  Consider:
   35560                 :             :                        int var = tuple<T,U>::x;
   35561                 :             :                      The template parameter 'U' looks exactly like a
   35562                 :             :                      declarator.  */
   35563                 :        1091 :                   do
   35564                 :             :                     {
   35565                 :        1091 :                       int ctor_dtor_or_conv_p;
   35566                 :        1091 :                       cp_lexer_consume_token (parser->lexer);
   35567                 :        1091 :                       cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
   35568                 :             :                                             CP_PARSER_FLAGS_NONE,
   35569                 :             :                                             &ctor_dtor_or_conv_p,
   35570                 :             :                                             /*parenthesized_p=*/NULL,
   35571                 :             :                                             /*member_p=*/true,
   35572                 :             :                                             /*friend_p=*/false,
   35573                 :             :                                             /*static_p=*/false);
   35574                 :        1091 :                       peek = cp_lexer_peek_token (parser->lexer);
   35575                 :           6 :                       if (cp_parser_error_occurred (parser))
   35576                 :             :                         break;
   35577                 :             :                     }
   35578                 :        1085 :                   while (peek->type == CPP_COMMA);
   35579                 :             :                   /* If we met an '=' or ';' then the original comma
   35580                 :             :                      was the end of the NSDMI.  Otherwise assume
   35581                 :             :                      we're still in the NSDMI.  */
   35582                 :        1091 :                   error = (peek->type != CPP_EQ
   35583                 :        1091 :                            && peek->type != CPP_SEMICOLON);
   35584                 :             :                 }
   35585                 :             :               else
   35586                 :             :                 {
   35587                 :          26 :                   cp_lexer_consume_token (parser->lexer);
   35588                 :          26 :                   begin_scope (sk_function_parms, NULL_TREE);
   35589                 :          26 :                   tree t = cp_parser_parameter_declaration_list
   35590                 :          26 :                             (parser, CP_PARSER_FLAGS_NONE,
   35591                 :             :                              /*pending_decls*/nullptr);
   35592                 :          26 :                   if (t == error_mark_node)
   35593                 :           0 :                     error = true;
   35594                 :          26 :                   pop_bindings_and_leave_scope ();
   35595                 :             :                 }
   35596                 :        1089 :               if (!cp_parser_error_occurred (parser) && !error)
   35597                 :        1117 :                 done = true;
   35598                 :        1117 :               cp_parser_abort_tentative_parse (parser);
   35599                 :             : 
   35600                 :        1117 :               parser->in_template_argument_list_p = saved_italp;
   35601                 :        1117 :               break;
   35602                 :             :             }
   35603                 :             :           /* FALLTHRU */
   35604                 :    10006640 :         case CPP_CLOSE_PAREN:
   35605                 :    10006640 :         case CPP_ELLIPSIS:
   35606                 :             :           /* If we run into a non-nested `;', `}', or `]',
   35607                 :             :              then the code is invalid -- but the default
   35608                 :             :              argument is certainly over.  */
   35609                 :    10006640 :         case CPP_SEMICOLON:
   35610                 :    10006640 :         case CPP_CLOSE_BRACE:
   35611                 :    10006640 :         case CPP_CLOSE_SQUARE:
   35612                 :    10006640 :           if (depth == 0
   35613                 :             :               /* Handle correctly int n = sizeof ... ( p );  */
   35614                 :     6240621 :               && token->type != CPP_ELLIPSIS)
   35615                 :             :             done = true;
   35616                 :             :           /* Update DEPTH, if necessary.  */
   35617                 :     3766025 :           else if (token->type == CPP_CLOSE_PAREN
   35618                 :             :                    || token->type == CPP_CLOSE_BRACE
   35619                 :             :                    || token->type == CPP_CLOSE_SQUARE)
   35620                 :     2628630 :             --depth;
   35621                 :             :           break;
   35622                 :             : 
   35623                 :     2628630 :         case CPP_OPEN_PAREN:
   35624                 :     2628630 :         case CPP_OPEN_SQUARE:
   35625                 :     2628630 :         case CPP_OPEN_BRACE:
   35626                 :     2628630 :           ++depth;
   35627                 :     2628630 :           break;
   35628                 :             : 
   35629                 :      102943 :         case CPP_LESS:
   35630                 :      102943 :           if (depth == 0)
   35631                 :             :             /* This might be the comparison operator, or it might
   35632                 :             :                start a template argument list.  */
   35633                 :      102907 :             ++maybe_template_id;
   35634                 :             :           break;
   35635                 :             : 
   35636                 :        1938 :         case CPP_RSHIFT:
   35637                 :        1938 :           if (cxx_dialect == cxx98)
   35638                 :             :             break;
   35639                 :             :           /* Fall through for C++0x, which treats the `>>'
   35640                 :             :              operator like two `>' tokens in certain
   35641                 :             :              cases.  */
   35642                 :      101000 :           gcc_fallthrough ();
   35643                 :             : 
   35644                 :      101000 :         case CPP_GREATER:
   35645                 :      101000 :           if (depth == 0)
   35646                 :             :             {
   35647                 :             :               /* This might be an operator, or it might close a
   35648                 :             :                  template argument list.  But if a previous '<'
   35649                 :             :                  started a template argument list, this will have
   35650                 :             :                  closed it, so we can't be in one anymore.  */
   35651                 :      100959 :               maybe_template_id -= 1 + (token->type == CPP_RSHIFT);
   35652                 :      100959 :               if (maybe_template_id < 0)
   35653                 :             :                 maybe_template_id = 0;
   35654                 :             :             }
   35655                 :             :           break;
   35656                 :             : 
   35657                 :             :           /* If we run out of tokens, issue an error message.  */
   35658                 :           4 :         case CPP_EOF:
   35659                 :           4 :         case CPP_PRAGMA_EOL:
   35660                 :           4 :           error_at (token->location, "file ends in default argument");
   35661                 :           4 :           return error_mark_node;
   35662                 :             : 
   35663                 :             :         case CPP_NAME:
   35664                 :             :         case CPP_SCOPE:
   35665                 :             :           /* In these cases, we should look for template-ids.
   35666                 :             :              For example, if the default argument is
   35667                 :             :              `X<int, double>()', we need to do name lookup to
   35668                 :             :              figure out whether or not `X' is a template; if
   35669                 :             :              so, the `,' does not end the default argument.
   35670                 :             : 
   35671                 :             :              That is not yet done.  */
   35672                 :             :           break;
   35673                 :             : 
   35674                 :             :         default:
   35675                 :             :           break;
   35676                 :             :         }
   35677                 :             : 
   35678                 :             :       /* If we've reached the end, stop.  */
   35679                 :    28176355 :       if (done)
   35680                 :             :         break;
   35681                 :             : 
   35682                 :             :       /* Add the token to the token block.  */
   35683                 :    21935733 :       token = cp_lexer_consume_token (parser->lexer);
   35684                 :    21935733 :     }
   35685                 :             : 
   35686                 :             :   /* Create a DEFERRED_PARSE to represent the unparsed default
   35687                 :             :      argument.  */
   35688                 :     6358314 :   default_argument = make_node (DEFERRED_PARSE);
   35689                 :     6358314 :   DEFPARSE_TOKENS (default_argument)
   35690                 :     6358314 :     = cp_token_cache_new (first_token, token);
   35691                 :     6358314 :   DEFPARSE_INSTANTIATIONS (default_argument) = NULL;
   35692                 :             : 
   35693                 :     6358314 :   return default_argument;
   35694                 :             : }
   35695                 :             : 
   35696                 :             : /* A location to use for diagnostics about an unparsed DEFERRED_PARSE.  */
   35697                 :             : 
   35698                 :             : location_t
   35699                 :          24 : defparse_location (tree default_argument)
   35700                 :             : {
   35701                 :          24 :   cp_token_cache *tokens = DEFPARSE_TOKENS (default_argument);
   35702                 :          24 :   location_t start = tokens->first->location;
   35703                 :          24 :   location_t end = tokens->last->location;
   35704                 :          24 :   return make_location (start, start, end);
   35705                 :             : }
   35706                 :             : 
   35707                 :             : /* Begin parsing tentatively.  We always save tokens while parsing
   35708                 :             :    tentatively so that if the tentative parsing fails we can restore the
   35709                 :             :    tokens.  */
   35710                 :             : 
   35711                 :             : static void
   35712                 : 13090145649 : cp_parser_parse_tentatively (cp_parser* parser)
   35713                 :             : {
   35714                 :             :   /* Enter a new parsing context.  */
   35715                 : 13090145649 :   parser->context = cp_parser_context_new (parser->context);
   35716                 :             :   /* Begin saving tokens.  */
   35717                 : 13090145649 :   cp_lexer_save_tokens (parser->lexer);
   35718                 :             :   /* In order to avoid repetitive access control error messages,
   35719                 :             :      access checks are queued up until we are no longer parsing
   35720                 :             :      tentatively.  */
   35721                 : 13090145649 :   push_deferring_access_checks (dk_deferred);
   35722                 : 13090145649 : }
   35723                 :             : 
   35724                 :             : /* Commit to the currently active tentative parse.  */
   35725                 :             : 
   35726                 :             : static void
   35727                 :   342414869 : cp_parser_commit_to_tentative_parse (cp_parser* parser)
   35728                 :             : {
   35729                 :   342414869 :   cp_parser_context *context;
   35730                 :   342414869 :   cp_lexer *lexer;
   35731                 :             : 
   35732                 :             :   /* Mark all of the levels as committed.  */
   35733                 :   342414869 :   lexer = parser->lexer;
   35734                 :   498338635 :   for (context = parser->context; context->next; context = context->next)
   35735                 :             :     {
   35736                 :   262558132 :       if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
   35737                 :             :         break;
   35738                 :   155923766 :       context->status = CP_PARSER_STATUS_KIND_COMMITTED;
   35739                 :   311847532 :       while (!cp_lexer_saving_tokens (lexer))
   35740                 :           0 :         lexer = lexer->next;
   35741                 :   155923766 :       cp_lexer_commit_tokens (lexer);
   35742                 :             :     }
   35743                 :   342414869 : }
   35744                 :             : 
   35745                 :             : /* Commit to the topmost currently active tentative parse.
   35746                 :             : 
   35747                 :             :    Note that this function shouldn't be called when there are
   35748                 :             :    irreversible side-effects while in a tentative state.  For
   35749                 :             :    example, we shouldn't create a permanent entry in the symbol
   35750                 :             :    table, or issue an error message that might not apply if the
   35751                 :             :    tentative parse is aborted.  */
   35752                 :             : 
   35753                 :             : static void
   35754                 :   200075148 : cp_parser_commit_to_topmost_tentative_parse (cp_parser* parser)
   35755                 :             : {
   35756                 :   200075148 :   cp_parser_context *context = parser->context;
   35757                 :   200075148 :   cp_lexer *lexer = parser->lexer;
   35758                 :             : 
   35759                 :   200075148 :   if (context)
   35760                 :             :     {
   35761                 :   200075148 :       if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
   35762                 :             :         return;
   35763                 :   200075128 :       context->status = CP_PARSER_STATUS_KIND_COMMITTED;
   35764                 :             : 
   35765                 :   400150256 :       while (!cp_lexer_saving_tokens (lexer))
   35766                 :           0 :         lexer = lexer->next;
   35767                 :   200075128 :       cp_lexer_commit_tokens (lexer);
   35768                 :             :     }
   35769                 :             : }
   35770                 :             : 
   35771                 :             : /* Abort the currently active tentative parse.  All consumed tokens
   35772                 :             :    will be rolled back, and no diagnostics will be issued.  */
   35773                 :             : 
   35774                 :             : static void
   35775                 :   261425583 : cp_parser_abort_tentative_parse (cp_parser* parser)
   35776                 :             : {
   35777                 :   261425583 :   gcc_assert (parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED
   35778                 :             :               || errorcount > 0);
   35779                 :   522851166 :   cp_parser_simulate_error (parser);
   35780                 :             :   /* Now, pretend that we want to see if the construct was
   35781                 :             :      successfully parsed.  */
   35782                 :   261425583 :   cp_parser_parse_definitely (parser);
   35783                 :   261425583 : }
   35784                 :             : 
   35785                 :             : /* Stop parsing tentatively.  If a parse error has occurred, restore the
   35786                 :             :    token stream.  Otherwise, commit to the tokens we have consumed.
   35787                 :             :    Returns true if no error occurred; false otherwise.  */
   35788                 :             : 
   35789                 :             : static bool
   35790                 : 13090145602 : cp_parser_parse_definitely (cp_parser* parser)
   35791                 :             : {
   35792                 : 13090145602 :   bool error_occurred;
   35793                 : 13090145602 :   cp_parser_context *context;
   35794                 :             : 
   35795                 :             :   /* Remember whether or not an error occurred, since we are about to
   35796                 :             :      destroy that information.  */
   35797                 : 26180291204 :   error_occurred = cp_parser_error_occurred (parser);
   35798                 :             :   /* Remove the topmost context from the stack.  */
   35799                 : 13090145602 :   context = parser->context;
   35800                 : 13090145602 :   parser->context = context->next;
   35801                 :             :   /* If no parse errors occurred, commit to the tentative parse.  */
   35802                 : 13090145602 :   if (!error_occurred)
   35803                 :             :     {
   35804                 :             :       /* Commit to the tokens read tentatively, unless that was
   35805                 :             :          already done.  */
   35806                 :  3518210395 :       if (context->status != CP_PARSER_STATUS_KIND_COMMITTED)
   35807                 :  3162211528 :         cp_lexer_commit_tokens (parser->lexer);
   35808                 :             : 
   35809                 :  3518210395 :       pop_to_parent_deferring_access_checks ();
   35810                 :             :     }
   35811                 :             :   /* Otherwise, if errors occurred, roll back our state so that things
   35812                 :             :      are just as they were before we began the tentative parse.  */
   35813                 :             :   else
   35814                 :             :     {
   35815                 :  9571935207 :       cp_lexer_rollback_tokens (parser->lexer);
   35816                 :  9571935207 :       pop_deferring_access_checks ();
   35817                 :             :     }
   35818                 :             :   /* Add the context to the front of the free list.  */
   35819                 : 13090145602 :   context->next = cp_parser_context_free_list;
   35820                 : 13090145602 :   cp_parser_context_free_list = context;
   35821                 :             : 
   35822                 : 13090145602 :   return !error_occurred;
   35823                 :             : }
   35824                 :             : 
   35825                 :             : /* Returns true if we are parsing tentatively and are not committed to
   35826                 :             :    this tentative parse.  */
   35827                 :             : 
   35828                 :             : static bool
   35829                 : 17306260829 : cp_parser_uncommitted_to_tentative_parse_p (cp_parser* parser)
   35830                 :             : {
   35831                 :     7183980 :   return (cp_parser_parsing_tentatively (parser)
   35832                 : 17306260799 :           && parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED);
   35833                 :             : }
   35834                 :             : 
   35835                 :             : /* Returns nonzero iff an error has occurred during the most recent
   35836                 :             :    tentative parse.  */
   35837                 :             : 
   35838                 :             : static bool
   35839                 : 17720965026 : cp_parser_error_occurred (cp_parser* parser)
   35840                 :             : {
   35841                 : 17720965026 :   return (cp_parser_parsing_tentatively (parser)
   35842                 : 17720965026 :           && parser->context->status == CP_PARSER_STATUS_KIND_ERROR);
   35843                 :             : }
   35844                 :             : 
   35845                 :             : /* Returns nonzero if GNU extensions are allowed.  */
   35846                 :             : 
   35847                 :             : static bool
   35848                 :  3110517462 : cp_parser_allow_gnu_extensions_p (cp_parser* parser)
   35849                 :             : {
   35850                 :  3110517462 :   return parser->allow_gnu_extensions_p;
   35851                 :             : }
   35852                 :             : 
   35853                 :             : /* Objective-C++ Productions */
   35854                 :             : 
   35855                 :             : 
   35856                 :             : /* Parse an Objective-C expression, which feeds into a primary-expression
   35857                 :             :    above.
   35858                 :             : 
   35859                 :             :    objc-expression:
   35860                 :             :      objc-message-expression
   35861                 :             :      objc-string-literal
   35862                 :             :      objc-encode-expression
   35863                 :             :      objc-protocol-expression
   35864                 :             :      objc-selector-expression
   35865                 :             : 
   35866                 :             :   Returns a tree representation of the expression.  */
   35867                 :             : 
   35868                 :             : static cp_expr
   35869                 :           0 : cp_parser_objc_expression (cp_parser* parser)
   35870                 :             : {
   35871                 :             :   /* Try to figure out what kind of declaration is present.  */
   35872                 :           0 :   cp_token *kwd = cp_lexer_peek_token (parser->lexer);
   35873                 :             : 
   35874                 :           0 :   switch (kwd->type)
   35875                 :             :     {
   35876                 :           0 :     case CPP_OPEN_SQUARE:
   35877                 :           0 :       return cp_parser_objc_message_expression (parser);
   35878                 :             : 
   35879                 :           0 :     case CPP_OBJC_STRING:
   35880                 :           0 :       kwd = cp_lexer_consume_token (parser->lexer);
   35881                 :           0 :       return objc_build_string_object (kwd->u.value);
   35882                 :             : 
   35883                 :           0 :     case CPP_KEYWORD:
   35884                 :           0 :       switch (kwd->keyword)
   35885                 :             :         {
   35886                 :           0 :         case RID_AT_ENCODE:
   35887                 :           0 :           return cp_parser_objc_encode_expression (parser);
   35888                 :             : 
   35889                 :           0 :         case RID_AT_PROTOCOL:
   35890                 :           0 :           return cp_parser_objc_protocol_expression (parser);
   35891                 :             : 
   35892                 :           0 :         case RID_AT_SELECTOR:
   35893                 :           0 :           return cp_parser_objc_selector_expression (parser);
   35894                 :             : 
   35895                 :             :         default:
   35896                 :             :           break;
   35897                 :             :         }
   35898                 :             :       /* FALLTHRU */
   35899                 :           0 :     default:
   35900                 :           0 :       error_at (kwd->location,
   35901                 :             :                 "misplaced %<@%D%> Objective-C++ construct",
   35902                 :             :                 kwd->u.value);
   35903                 :           0 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   35904                 :             :     }
   35905                 :             : 
   35906                 :           0 :   return error_mark_node;
   35907                 :             : }
   35908                 :             : 
   35909                 :             : /* Parse an Objective-C message expression.
   35910                 :             : 
   35911                 :             :    objc-message-expression:
   35912                 :             :      [ objc-message-receiver objc-message-args ]
   35913                 :             : 
   35914                 :             :    Returns a representation of an Objective-C message.  */
   35915                 :             : 
   35916                 :             : static tree
   35917                 :           0 : cp_parser_objc_message_expression (cp_parser* parser)
   35918                 :             : {
   35919                 :           0 :   tree receiver, messageargs;
   35920                 :             : 
   35921                 :           0 :   parser->objective_c_message_context_p = true;
   35922                 :           0 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   35923                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '['.  */
   35924                 :           0 :   receiver = cp_parser_objc_message_receiver (parser);
   35925                 :           0 :   messageargs = cp_parser_objc_message_args (parser);
   35926                 :           0 :   location_t end_loc = cp_lexer_peek_token (parser->lexer)->location;
   35927                 :           0 :   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
   35928                 :             : 
   35929                 :           0 :   tree result = objc_build_message_expr (receiver, messageargs);
   35930                 :             : 
   35931                 :             :   /* Construct a location e.g.
   35932                 :             :        [self func1:5]
   35933                 :             :        ^~~~~~~~~~~~~~
   35934                 :             :      ranging from the '[' to the ']', with the caret at the start.  */
   35935                 :           0 :   location_t combined_loc = make_location (start_loc, start_loc, end_loc);
   35936                 :           0 :   protected_set_expr_location (result, combined_loc);
   35937                 :             : 
   35938                 :           0 :   parser->objective_c_message_context_p = false;
   35939                 :           0 :   return result;
   35940                 :             : }
   35941                 :             : 
   35942                 :             : /* Parse an objc-message-receiver.
   35943                 :             : 
   35944                 :             :    objc-message-receiver:
   35945                 :             :      expression
   35946                 :             :      simple-type-specifier
   35947                 :             : 
   35948                 :             :   Returns a representation of the type or expression.  */
   35949                 :             : 
   35950                 :             : static tree
   35951                 :           0 : cp_parser_objc_message_receiver (cp_parser* parser)
   35952                 :             : {
   35953                 :           0 :   tree rcv;
   35954                 :             : 
   35955                 :             :   /* An Objective-C message receiver may be either (1) a type
   35956                 :             :      or (2) an expression.  */
   35957                 :           0 :   cp_parser_parse_tentatively (parser);
   35958                 :           0 :   rcv = cp_parser_expression (parser);
   35959                 :             : 
   35960                 :             :   /* If that worked out, fine.  */
   35961                 :           0 :   if (cp_parser_parse_definitely (parser))
   35962                 :             :     return rcv;
   35963                 :             : 
   35964                 :           0 :   cp_parser_parse_tentatively (parser);
   35965                 :           0 :   rcv = cp_parser_simple_type_specifier (parser,
   35966                 :             :                                          /*decl_specs=*/NULL,
   35967                 :             :                                          CP_PARSER_FLAGS_NONE);
   35968                 :             : 
   35969                 :           0 :   if (cp_parser_parse_definitely (parser))
   35970                 :           0 :     return objc_get_class_reference (rcv);
   35971                 :             : 
   35972                 :           0 :   cp_parser_error (parser, "objective-c++ message receiver expected");
   35973                 :           0 :   return error_mark_node;
   35974                 :             : }
   35975                 :             : 
   35976                 :             : /* Parse the arguments and selectors comprising an Objective-C message.
   35977                 :             : 
   35978                 :             :    objc-message-args:
   35979                 :             :      objc-selector
   35980                 :             :      objc-selector-args
   35981                 :             :      objc-selector-args , objc-comma-args
   35982                 :             : 
   35983                 :             :    objc-selector-args:
   35984                 :             :      objc-selector [opt] : assignment-expression
   35985                 :             :      objc-selector-args objc-selector [opt] : assignment-expression
   35986                 :             : 
   35987                 :             :    objc-comma-args:
   35988                 :             :      assignment-expression
   35989                 :             :      objc-comma-args , assignment-expression
   35990                 :             : 
   35991                 :             :    Returns a TREE_LIST, with TREE_PURPOSE containing a list of
   35992                 :             :    selector arguments and TREE_VALUE containing a list of comma
   35993                 :             :    arguments.  */
   35994                 :             : 
   35995                 :             : static tree
   35996                 :           0 : cp_parser_objc_message_args (cp_parser* parser)
   35997                 :             : {
   35998                 :           0 :   tree sel_args = NULL_TREE, addl_args = NULL_TREE;
   35999                 :           0 :   bool maybe_unary_selector_p = true;
   36000                 :           0 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   36001                 :             : 
   36002                 :           0 :   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
   36003                 :             :     {
   36004                 :           0 :       tree selector = NULL_TREE, arg;
   36005                 :             : 
   36006                 :           0 :       if (token->type != CPP_COLON)
   36007                 :           0 :         selector = cp_parser_objc_selector (parser);
   36008                 :             : 
   36009                 :             :       /* Detect if we have a unary selector.  */
   36010                 :           0 :       if (maybe_unary_selector_p
   36011                 :           0 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
   36012                 :           0 :         return build_tree_list (selector, NULL_TREE);
   36013                 :             : 
   36014                 :           0 :       maybe_unary_selector_p = false;
   36015                 :           0 :       cp_parser_require (parser, CPP_COLON, RT_COLON);
   36016                 :           0 :       arg = cp_parser_assignment_expression (parser);
   36017                 :             : 
   36018                 :           0 :       sel_args
   36019                 :           0 :         = chainon (sel_args,
   36020                 :             :                    build_tree_list (selector, arg));
   36021                 :             : 
   36022                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36023                 :             :     }
   36024                 :             : 
   36025                 :             :   /* Handle non-selector arguments, if any. */
   36026                 :           0 :   while (token->type == CPP_COMMA)
   36027                 :             :     {
   36028                 :           0 :       tree arg;
   36029                 :             : 
   36030                 :           0 :       cp_lexer_consume_token (parser->lexer);
   36031                 :           0 :       arg = cp_parser_assignment_expression (parser);
   36032                 :             : 
   36033                 :           0 :       addl_args
   36034                 :           0 :         = chainon (addl_args,
   36035                 :             :                    build_tree_list (NULL_TREE, arg));
   36036                 :             : 
   36037                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36038                 :             :     }
   36039                 :             : 
   36040                 :           0 :   if (sel_args == NULL_TREE && addl_args == NULL_TREE)
   36041                 :             :     {
   36042                 :           0 :       cp_parser_error (parser, "objective-c++ message argument(s) are expected");
   36043                 :           0 :       return build_tree_list (error_mark_node, error_mark_node);
   36044                 :             :     }
   36045                 :             : 
   36046                 :           0 :   return build_tree_list (sel_args, addl_args);
   36047                 :             : }
   36048                 :             : 
   36049                 :             : /* Parse an Objective-C encode expression.
   36050                 :             : 
   36051                 :             :    objc-encode-expression:
   36052                 :             :      @encode objc-typename
   36053                 :             : 
   36054                 :             :    Returns an encoded representation of the type argument.  */
   36055                 :             : 
   36056                 :             : static cp_expr
   36057                 :           0 : cp_parser_objc_encode_expression (cp_parser* parser)
   36058                 :             : {
   36059                 :           0 :   tree type;
   36060                 :           0 :   cp_token *token;
   36061                 :           0 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   36062                 :             : 
   36063                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@encode'.  */
   36064                 :           0 :   matching_parens parens;
   36065                 :           0 :   parens.require_open (parser);
   36066                 :           0 :   token = cp_lexer_peek_token (parser->lexer);
   36067                 :           0 :   type = complete_type (cp_parser_type_id (parser));
   36068                 :           0 :   parens.require_close (parser);
   36069                 :             : 
   36070                 :           0 :   if (!type)
   36071                 :             :     {
   36072                 :           0 :       error_at (token->location,
   36073                 :             :                 "%<@encode%> must specify a type as an argument");
   36074                 :           0 :       return error_mark_node;
   36075                 :             :     }
   36076                 :             : 
   36077                 :             :   /* This happens if we find @encode(T) (where T is a template
   36078                 :             :      typename or something dependent on a template typename) when
   36079                 :             :      parsing a template.  In that case, we can't compile it
   36080                 :             :      immediately, but we rather create an AT_ENCODE_EXPR which will
   36081                 :             :      need to be instantiated when the template is used.
   36082                 :             :   */
   36083                 :           0 :   if (dependent_type_p (type))
   36084                 :             :     {
   36085                 :           0 :       tree value = build_min (AT_ENCODE_EXPR, size_type_node, type);
   36086                 :           0 :       TREE_READONLY (value) = 1;
   36087                 :           0 :       return value;
   36088                 :             :     }
   36089                 :             : 
   36090                 :             : 
   36091                 :             :   /* Build a location of the form:
   36092                 :             :        @encode(int)
   36093                 :             :        ^~~~~~~~~~~~
   36094                 :             :      with caret==start at the @ token, finishing at the close paren.  */
   36095                 :           0 :   location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
   36096                 :             : 
   36097                 :           0 :   return cp_expr (objc_build_encode_expr (type), combined_loc);
   36098                 :             : }
   36099                 :             : 
   36100                 :             : /* Parse an Objective-C @defs expression.  */
   36101                 :             : 
   36102                 :             : static tree
   36103                 :           0 : cp_parser_objc_defs_expression (cp_parser *parser)
   36104                 :             : {
   36105                 :           0 :   tree name;
   36106                 :             : 
   36107                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@defs'.  */
   36108                 :           0 :   matching_parens parens;
   36109                 :           0 :   parens.require_open (parser);
   36110                 :           0 :   name = cp_parser_identifier (parser);
   36111                 :           0 :   parens.require_close (parser);
   36112                 :             : 
   36113                 :           0 :   return objc_get_class_ivars (name);
   36114                 :             : }
   36115                 :             : 
   36116                 :             : /* Parse an Objective-C protocol expression.
   36117                 :             : 
   36118                 :             :   objc-protocol-expression:
   36119                 :             :     @protocol ( identifier )
   36120                 :             : 
   36121                 :             :   Returns a representation of the protocol expression.  */
   36122                 :             : 
   36123                 :             : static tree
   36124                 :           0 : cp_parser_objc_protocol_expression (cp_parser* parser)
   36125                 :             : {
   36126                 :           0 :   tree proto;
   36127                 :           0 :   location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
   36128                 :             : 
   36129                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@protocol'.  */
   36130                 :           0 :   matching_parens parens;
   36131                 :           0 :   parens.require_open (parser);
   36132                 :           0 :   proto = cp_parser_identifier (parser);
   36133                 :           0 :   parens.require_close (parser);
   36134                 :             : 
   36135                 :             :   /* Build a location of the form:
   36136                 :             :        @protocol(prot)
   36137                 :             :        ^~~~~~~~~~~~~~~
   36138                 :             :      with caret==start at the @ token, finishing at the close paren.  */
   36139                 :           0 :   location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
   36140                 :           0 :   tree result = objc_build_protocol_expr (proto);
   36141                 :           0 :   protected_set_expr_location (result, combined_loc);
   36142                 :           0 :   return result;
   36143                 :             : }
   36144                 :             : 
   36145                 :             : /* Parse an Objective-C selector expression.
   36146                 :             : 
   36147                 :             :    objc-selector-expression:
   36148                 :             :      @selector ( objc-method-signature )
   36149                 :             : 
   36150                 :             :    objc-method-signature:
   36151                 :             :      objc-selector
   36152                 :             :      objc-selector-seq
   36153                 :             : 
   36154                 :             :    objc-selector-seq:
   36155                 :             :      objc-selector :
   36156                 :             :      objc-selector-seq objc-selector :
   36157                 :             : 
   36158                 :             :   Returns a representation of the method selector.  */
   36159                 :             : 
   36160                 :             : static tree
   36161                 :           0 : cp_parser_objc_selector_expression (cp_parser* parser)
   36162                 :             : {
   36163                 :           0 :   tree sel_seq = NULL_TREE;
   36164                 :           0 :   bool maybe_unary_selector_p = true;
   36165                 :           0 :   cp_token *token;
   36166                 :           0 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   36167                 :             : 
   36168                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@selector'.  */
   36169                 :           0 :   matching_parens parens;
   36170                 :           0 :   parens.require_open (parser);
   36171                 :           0 :   token = cp_lexer_peek_token (parser->lexer);
   36172                 :             : 
   36173                 :           0 :   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON
   36174                 :           0 :          || token->type == CPP_SCOPE)
   36175                 :             :     {
   36176                 :           0 :       tree selector = NULL_TREE;
   36177                 :             : 
   36178                 :           0 :       if (token->type != CPP_COLON
   36179                 :             :           || token->type == CPP_SCOPE)
   36180                 :           0 :         selector = cp_parser_objc_selector (parser);
   36181                 :             : 
   36182                 :           0 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)
   36183                 :           0 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
   36184                 :             :         {
   36185                 :             :           /* Detect if we have a unary selector.  */
   36186                 :           0 :           if (maybe_unary_selector_p)
   36187                 :             :             {
   36188                 :           0 :               sel_seq = selector;
   36189                 :           0 :               goto finish_selector;
   36190                 :             :             }
   36191                 :             :           else
   36192                 :             :             {
   36193                 :           0 :               cp_parser_error (parser, "expected %<:%>");
   36194                 :             :             }
   36195                 :             :         }
   36196                 :           0 :       maybe_unary_selector_p = false;
   36197                 :           0 :       token = cp_lexer_consume_token (parser->lexer);
   36198                 :             : 
   36199                 :           0 :       if (token->type == CPP_SCOPE)
   36200                 :             :         {
   36201                 :           0 :           sel_seq
   36202                 :           0 :             = chainon (sel_seq,
   36203                 :             :                        build_tree_list (selector, NULL_TREE));
   36204                 :           0 :           sel_seq
   36205                 :           0 :             = chainon (sel_seq,
   36206                 :             :                        build_tree_list (NULL_TREE, NULL_TREE));
   36207                 :             :         }
   36208                 :             :       else
   36209                 :           0 :         sel_seq
   36210                 :           0 :           = chainon (sel_seq,
   36211                 :             :                      build_tree_list (selector, NULL_TREE));
   36212                 :             : 
   36213                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36214                 :             :     }
   36215                 :             : 
   36216                 :           0 :  finish_selector:
   36217                 :           0 :   parens.require_close (parser);
   36218                 :             : 
   36219                 :             : 
   36220                 :             :   /* Build a location of the form:
   36221                 :             :        @selector(func)
   36222                 :             :        ^~~~~~~~~~~~~~~
   36223                 :             :      with caret==start at the @ token, finishing at the close paren.  */
   36224                 :           0 :   location_t combined_loc = make_location (loc, loc, parser->lexer);
   36225                 :           0 :   tree result = objc_build_selector_expr (combined_loc, sel_seq);
   36226                 :             :   /* TODO: objc_build_selector_expr doesn't always honor the location.  */
   36227                 :           0 :   protected_set_expr_location (result, combined_loc);
   36228                 :           0 :   return result;
   36229                 :             : }
   36230                 :             : 
   36231                 :             : /* Parse a list of identifiers.
   36232                 :             : 
   36233                 :             :    objc-identifier-list:
   36234                 :             :      identifier
   36235                 :             :      objc-identifier-list , identifier
   36236                 :             : 
   36237                 :             :    Returns a TREE_LIST of identifier nodes.  */
   36238                 :             : 
   36239                 :             : static tree
   36240                 :           0 : cp_parser_objc_identifier_list (cp_parser* parser)
   36241                 :             : {
   36242                 :           0 :   tree identifier;
   36243                 :           0 :   tree list;
   36244                 :           0 :   cp_token *sep;
   36245                 :             : 
   36246                 :           0 :   identifier = cp_parser_identifier (parser);
   36247                 :           0 :   if (identifier == error_mark_node)
   36248                 :             :     return error_mark_node;
   36249                 :             : 
   36250                 :           0 :   list = build_tree_list (NULL_TREE, identifier);
   36251                 :           0 :   sep = cp_lexer_peek_token (parser->lexer);
   36252                 :             : 
   36253                 :           0 :   while (sep->type == CPP_COMMA)
   36254                 :             :     {
   36255                 :           0 :       cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
   36256                 :           0 :       identifier = cp_parser_identifier (parser);
   36257                 :           0 :       if (identifier == error_mark_node)
   36258                 :           0 :         return list;
   36259                 :             : 
   36260                 :           0 :       list = chainon (list, build_tree_list (NULL_TREE,
   36261                 :             :                                              identifier));
   36262                 :           0 :       sep = cp_lexer_peek_token (parser->lexer);
   36263                 :             :     }
   36264                 :             : 
   36265                 :             :   return list;
   36266                 :             : }
   36267                 :             : 
   36268                 :             : /* Parse an Objective-C alias declaration.
   36269                 :             : 
   36270                 :             :    objc-alias-declaration:
   36271                 :             :      @compatibility_alias identifier identifier ;
   36272                 :             : 
   36273                 :             :    This function registers the alias mapping with the Objective-C front end.
   36274                 :             :    It returns nothing.  */
   36275                 :             : 
   36276                 :             : static void
   36277                 :           0 : cp_parser_objc_alias_declaration (cp_parser* parser)
   36278                 :             : {
   36279                 :           0 :   tree alias, orig;
   36280                 :             : 
   36281                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@compatibility_alias'.  */
   36282                 :           0 :   alias = cp_parser_identifier (parser);
   36283                 :           0 :   orig = cp_parser_identifier (parser);
   36284                 :           0 :   objc_declare_alias (alias, orig);
   36285                 :           0 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   36286                 :           0 : }
   36287                 :             : 
   36288                 :             : /* Parse an Objective-C class forward-declaration.
   36289                 :             : 
   36290                 :             :    objc-class-declaration:
   36291                 :             :      @class objc-identifier-list ;
   36292                 :             : 
   36293                 :             :    The function registers the forward declarations with the Objective-C
   36294                 :             :    front end.  It returns nothing.  */
   36295                 :             : 
   36296                 :             : static void
   36297                 :           0 : cp_parser_objc_class_declaration (cp_parser* parser)
   36298                 :             : {
   36299                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@class'.  */
   36300                 :           0 :   while (true)
   36301                 :             :     {
   36302                 :           0 :       tree id;
   36303                 :             : 
   36304                 :           0 :       id = cp_parser_identifier (parser);
   36305                 :           0 :       if (id == error_mark_node)
   36306                 :             :         break;
   36307                 :             : 
   36308                 :           0 :       objc_declare_class (id);
   36309                 :             : 
   36310                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   36311                 :           0 :         cp_lexer_consume_token (parser->lexer);
   36312                 :             :       else
   36313                 :             :         break;
   36314                 :           0 :     }
   36315                 :           0 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   36316                 :           0 : }
   36317                 :             : 
   36318                 :             : /* Parse a list of Objective-C protocol references.
   36319                 :             : 
   36320                 :             :    objc-protocol-refs-opt:
   36321                 :             :      objc-protocol-refs [opt]
   36322                 :             : 
   36323                 :             :    objc-protocol-refs:
   36324                 :             :      < objc-identifier-list >
   36325                 :             : 
   36326                 :             :    Returns a TREE_LIST of identifiers, if any.  */
   36327                 :             : 
   36328                 :             : static tree
   36329                 :           0 : cp_parser_objc_protocol_refs_opt (cp_parser* parser)
   36330                 :             : {
   36331                 :           0 :   tree protorefs = NULL_TREE;
   36332                 :             : 
   36333                 :           0 :   if(cp_lexer_next_token_is (parser->lexer, CPP_LESS))
   36334                 :             :     {
   36335                 :           0 :       cp_lexer_consume_token (parser->lexer);  /* Eat '<'.  */
   36336                 :           0 :       protorefs = cp_parser_objc_identifier_list (parser);
   36337                 :           0 :       cp_parser_require (parser, CPP_GREATER, RT_GREATER);
   36338                 :             :     }
   36339                 :             : 
   36340                 :           0 :   return protorefs;
   36341                 :             : }
   36342                 :             : 
   36343                 :             : /* Parse a Objective-C visibility specification.  */
   36344                 :             : 
   36345                 :             : static void
   36346                 :           0 : cp_parser_objc_visibility_spec (cp_parser* parser)
   36347                 :             : {
   36348                 :           0 :   cp_token *vis = cp_lexer_peek_token (parser->lexer);
   36349                 :             : 
   36350                 :           0 :   switch (vis->keyword)
   36351                 :             :     {
   36352                 :           0 :     case RID_AT_PRIVATE:
   36353                 :           0 :       objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
   36354                 :           0 :       break;
   36355                 :           0 :     case RID_AT_PROTECTED:
   36356                 :           0 :       objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
   36357                 :           0 :       break;
   36358                 :           0 :     case RID_AT_PUBLIC:
   36359                 :           0 :       objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
   36360                 :           0 :       break;
   36361                 :           0 :     case RID_AT_PACKAGE:
   36362                 :           0 :       objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
   36363                 :           0 :       break;
   36364                 :             :     default:
   36365                 :             :       return;
   36366                 :             :     }
   36367                 :             : 
   36368                 :             :   /* Eat '@private'/'@protected'/'@public'.  */
   36369                 :           0 :   cp_lexer_consume_token (parser->lexer);
   36370                 :             : }
   36371                 :             : 
   36372                 :             : /* Parse an Objective-C method type.  Return 'true' if it is a class
   36373                 :             :    (+) method, and 'false' if it is an instance (-) method.  */
   36374                 :             : 
   36375                 :             : static inline bool
   36376                 :           0 : cp_parser_objc_method_type (cp_parser* parser)
   36377                 :             : {
   36378                 :           0 :   if (cp_lexer_consume_token (parser->lexer)->type == CPP_PLUS)
   36379                 :             :     return true;
   36380                 :             :   else
   36381                 :           0 :     return false;
   36382                 :             : }
   36383                 :             : 
   36384                 :             : /* Parse an Objective-C protocol qualifier.  */
   36385                 :             : 
   36386                 :             : static tree
   36387                 :           0 : cp_parser_objc_protocol_qualifiers (cp_parser* parser)
   36388                 :             : {
   36389                 :           0 :   tree quals = NULL_TREE, node;
   36390                 :           0 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   36391                 :             : 
   36392                 :           0 :   node = token->u.value;
   36393                 :             : 
   36394                 :           0 :   while (node && identifier_p (node)
   36395                 :           0 :          && (node == ridpointers [(int) RID_IN]
   36396                 :           0 :              || node == ridpointers [(int) RID_OUT]
   36397                 :           0 :              || node == ridpointers [(int) RID_INOUT]
   36398                 :           0 :              || node == ridpointers [(int) RID_BYCOPY]
   36399                 :           0 :              || node == ridpointers [(int) RID_BYREF]
   36400                 :           0 :              || node == ridpointers [(int) RID_ONEWAY]))
   36401                 :             :     {
   36402                 :           0 :       quals = tree_cons (NULL_TREE, node, quals);
   36403                 :           0 :       cp_lexer_consume_token (parser->lexer);
   36404                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36405                 :           0 :       node = token->u.value;
   36406                 :             :     }
   36407                 :             : 
   36408                 :           0 :   return quals;
   36409                 :             : }
   36410                 :             : 
   36411                 :             : /* Parse an Objective-C typename.  */
   36412                 :             : 
   36413                 :             : static tree
   36414                 :           0 : cp_parser_objc_typename (cp_parser* parser)
   36415                 :             : {
   36416                 :           0 :   tree type_name = NULL_TREE;
   36417                 :             : 
   36418                 :           0 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   36419                 :             :     {
   36420                 :           0 :       tree proto_quals, cp_type = NULL_TREE;
   36421                 :             : 
   36422                 :           0 :       matching_parens parens;
   36423                 :           0 :       parens.consume_open (parser); /* Eat '('.  */
   36424                 :           0 :       proto_quals = cp_parser_objc_protocol_qualifiers (parser);
   36425                 :             : 
   36426                 :             :       /* An ObjC type name may consist of just protocol qualifiers, in which
   36427                 :             :          case the type shall default to 'id'.  */
   36428                 :           0 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
   36429                 :             :         {
   36430                 :           0 :           cp_type = cp_parser_type_id (parser);
   36431                 :             : 
   36432                 :             :           /* If the type could not be parsed, an error has already
   36433                 :             :              been produced.  For error recovery, behave as if it had
   36434                 :             :              not been specified, which will use the default type
   36435                 :             :              'id'.  */
   36436                 :           0 :           if (cp_type == error_mark_node)
   36437                 :             :             {
   36438                 :           0 :               cp_type = NULL_TREE;
   36439                 :             :               /* We need to skip to the closing parenthesis as
   36440                 :             :                  cp_parser_type_id() does not seem to do it for
   36441                 :             :                  us.  */
   36442                 :           0 :               cp_parser_skip_to_closing_parenthesis (parser,
   36443                 :             :                                                      /*recovering=*/true,
   36444                 :             :                                                      /*or_comma=*/false,
   36445                 :             :                                                      /*consume_paren=*/false);
   36446                 :             :             }
   36447                 :             :         }
   36448                 :             : 
   36449                 :           0 :       parens.require_close (parser);
   36450                 :           0 :       type_name = build_tree_list (proto_quals, cp_type);
   36451                 :             :     }
   36452                 :             : 
   36453                 :           0 :   return type_name;
   36454                 :             : }
   36455                 :             : 
   36456                 :             : /* Check to see if TYPE refers to an Objective-C selector name.  */
   36457                 :             : 
   36458                 :             : static bool
   36459                 :           0 : cp_parser_objc_selector_p (enum cpp_ttype type)
   36460                 :             : {
   36461                 :           0 :   return (type == CPP_NAME || type == CPP_KEYWORD
   36462                 :             :           || type == CPP_AND_AND || type == CPP_AND_EQ || type == CPP_AND
   36463                 :             :           || type == CPP_OR || type == CPP_COMPL || type == CPP_NOT
   36464                 :             :           || type == CPP_NOT_EQ || type == CPP_OR_OR || type == CPP_OR_EQ
   36465                 :           0 :           || type == CPP_XOR || type == CPP_XOR_EQ);
   36466                 :             : }
   36467                 :             : 
   36468                 :             : /* Parse an Objective-C selector.  */
   36469                 :             : 
   36470                 :             : static tree
   36471                 :           0 : cp_parser_objc_selector (cp_parser* parser)
   36472                 :             : {
   36473                 :           0 :   cp_token *token = cp_lexer_consume_token (parser->lexer);
   36474                 :             : 
   36475                 :           0 :   if (!cp_parser_objc_selector_p (token->type))
   36476                 :             :     {
   36477                 :           0 :       error_at (token->location, "invalid Objective-C++ selector name");
   36478                 :           0 :       return error_mark_node;
   36479                 :             :     }
   36480                 :             : 
   36481                 :             :   /* C++ operator names are allowed to appear in ObjC selectors.  */
   36482                 :           0 :   switch (token->type)
   36483                 :             :     {
   36484                 :           0 :     case CPP_AND_AND: return get_identifier ("and");
   36485                 :           0 :     case CPP_AND_EQ: return get_identifier ("and_eq");
   36486                 :           0 :     case CPP_AND: return get_identifier ("bitand");
   36487                 :           0 :     case CPP_OR: return get_identifier ("bitor");
   36488                 :           0 :     case CPP_COMPL: return get_identifier ("compl");
   36489                 :           0 :     case CPP_NOT: return get_identifier ("not");
   36490                 :           0 :     case CPP_NOT_EQ: return get_identifier ("not_eq");
   36491                 :           0 :     case CPP_OR_OR: return get_identifier ("or");
   36492                 :           0 :     case CPP_OR_EQ: return get_identifier ("or_eq");
   36493                 :           0 :     case CPP_XOR: return get_identifier ("xor");
   36494                 :           0 :     case CPP_XOR_EQ: return get_identifier ("xor_eq");
   36495                 :           0 :     default: return token->u.value;
   36496                 :             :     }
   36497                 :             : }
   36498                 :             : 
   36499                 :             : /* Parse an Objective-C params list.  */
   36500                 :             : 
   36501                 :             : static tree
   36502                 :           0 : cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
   36503                 :             : {
   36504                 :           0 :   tree params = NULL_TREE;
   36505                 :           0 :   bool maybe_unary_selector_p = true;
   36506                 :           0 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   36507                 :             : 
   36508                 :           0 :   while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
   36509                 :             :     {
   36510                 :           0 :       tree selector = NULL_TREE, type_name, identifier;
   36511                 :           0 :       tree parm_attr = NULL_TREE;
   36512                 :             : 
   36513                 :           0 :       if (token->keyword == RID_ATTRIBUTE)
   36514                 :             :         break;
   36515                 :             : 
   36516                 :           0 :       if (token->type != CPP_COLON)
   36517                 :           0 :         selector = cp_parser_objc_selector (parser);
   36518                 :             : 
   36519                 :             :       /* Detect if we have a unary selector.  */
   36520                 :           0 :       if (maybe_unary_selector_p
   36521                 :           0 :           && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
   36522                 :             :         {
   36523                 :             :           params = selector; /* Might be followed by attributes.  */
   36524                 :             :           break;
   36525                 :             :         }
   36526                 :             : 
   36527                 :           0 :       maybe_unary_selector_p = false;
   36528                 :           0 :       if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   36529                 :             :         {
   36530                 :             :           /* Something went quite wrong.  There should be a colon
   36531                 :             :              here, but there is not.  Stop parsing parameters.  */
   36532                 :             :           break;
   36533                 :             :         }
   36534                 :           0 :       type_name = cp_parser_objc_typename (parser);
   36535                 :             :       /* New ObjC allows attributes on parameters too.  */
   36536                 :           0 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
   36537                 :           0 :         parm_attr = cp_parser_attributes_opt (parser);
   36538                 :           0 :       identifier = cp_parser_identifier (parser);
   36539                 :             : 
   36540                 :           0 :       params
   36541                 :           0 :         = chainon (params,
   36542                 :             :                    objc_build_keyword_decl (selector,
   36543                 :             :                                             type_name,
   36544                 :             :                                             identifier,
   36545                 :             :                                             parm_attr));
   36546                 :             : 
   36547                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36548                 :             :     }
   36549                 :             : 
   36550                 :           0 :   if (params == NULL_TREE)
   36551                 :             :     {
   36552                 :           0 :       cp_parser_error (parser, "objective-c++ method declaration is expected");
   36553                 :           0 :       return error_mark_node;
   36554                 :             :     }
   36555                 :             : 
   36556                 :             :   /* We allow tail attributes for the method.  */
   36557                 :           0 :   if (token->keyword == RID_ATTRIBUTE)
   36558                 :             :     {
   36559                 :           0 :       *attributes = cp_parser_attributes_opt (parser);
   36560                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
   36561                 :           0 :           || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   36562                 :             :         return params;
   36563                 :           0 :       cp_parser_error (parser,
   36564                 :             :                        "method attributes must be specified at the end");
   36565                 :           0 :       return error_mark_node;
   36566                 :             :     }
   36567                 :             : 
   36568                 :             :   if (params == NULL_TREE)
   36569                 :             :     {
   36570                 :             :       cp_parser_error (parser, "objective-c++ method declaration is expected");
   36571                 :             :       return error_mark_node;
   36572                 :             :     }
   36573                 :             :   return params;
   36574                 :             : }
   36575                 :             : 
   36576                 :             : /* Parse the non-keyword Objective-C params.  */
   36577                 :             : 
   36578                 :             : static tree
   36579                 :           0 : cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp,
   36580                 :             :                                        tree* attributes)
   36581                 :             : {
   36582                 :           0 :   tree params = make_node (TREE_LIST);
   36583                 :           0 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   36584                 :           0 :   *ellipsisp = false;  /* Initially, assume no ellipsis.  */
   36585                 :             : 
   36586                 :           0 :   while (token->type == CPP_COMMA)
   36587                 :             :     {
   36588                 :           0 :       cp_parameter_declarator *parmdecl;
   36589                 :           0 :       tree parm;
   36590                 :             : 
   36591                 :           0 :       cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
   36592                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36593                 :             : 
   36594                 :           0 :       if (token->type == CPP_ELLIPSIS)
   36595                 :             :         {
   36596                 :           0 :           cp_lexer_consume_token (parser->lexer);  /* Eat '...'.  */
   36597                 :           0 :           *ellipsisp = true;
   36598                 :           0 :           token = cp_lexer_peek_token (parser->lexer);
   36599                 :           0 :           break;
   36600                 :             :         }
   36601                 :             : 
   36602                 :             :       /* TODO: parse attributes for tail parameters.  */
   36603                 :           0 :       parmdecl = cp_parser_parameter_declaration (parser, CP_PARSER_FLAGS_NONE,
   36604                 :             :                                                   false, NULL);
   36605                 :           0 :       parm = grokdeclarator (parmdecl->declarator,
   36606                 :             :                              &parmdecl->decl_specifiers,
   36607                 :             :                              PARM, /*initialized=*/0,
   36608                 :             :                              /*attrlist=*/NULL);
   36609                 :             : 
   36610                 :           0 :       chainon (params, build_tree_list (NULL_TREE, parm));
   36611                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36612                 :             :     }
   36613                 :             : 
   36614                 :             :   /* We allow tail attributes for the method.  */
   36615                 :           0 :   if (token->keyword == RID_ATTRIBUTE)
   36616                 :             :     {
   36617                 :           0 :       if (*attributes == NULL_TREE)
   36618                 :             :         {
   36619                 :           0 :           *attributes = cp_parser_attributes_opt (parser);
   36620                 :           0 :           if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
   36621                 :           0 :               || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   36622                 :             :             return params;
   36623                 :             :         }
   36624                 :             :       else
   36625                 :             :         /* We have an error, but parse the attributes, so that we can
   36626                 :             :            carry on.  */
   36627                 :           0 :         *attributes = cp_parser_attributes_opt (parser);
   36628                 :             : 
   36629                 :           0 :       cp_parser_error (parser,
   36630                 :             :                        "method attributes must be specified at the end");
   36631                 :           0 :       return error_mark_node;
   36632                 :             :     }
   36633                 :             : 
   36634                 :             :   return params;
   36635                 :             : }
   36636                 :             : 
   36637                 :             : /* Parse a linkage specification, a pragma, an extra semicolon or a block.  */
   36638                 :             : 
   36639                 :             : static void
   36640                 :           0 : cp_parser_objc_interstitial_code (cp_parser* parser)
   36641                 :             : {
   36642                 :           0 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   36643                 :             : 
   36644                 :             :   /* If the next token is `extern' and the following token is a string
   36645                 :             :      literal, then we have a linkage specification.  */
   36646                 :           0 :   if (token->keyword == RID_EXTERN
   36647                 :           0 :       && cp_parser_is_pure_string_literal
   36648                 :           0 :          (cp_lexer_peek_nth_token (parser->lexer, 2)))
   36649                 :           0 :     cp_parser_linkage_specification (parser, NULL_TREE);
   36650                 :             :   /* Handle #pragma, if any.  */
   36651                 :           0 :   else if (token->type == CPP_PRAGMA)
   36652                 :           0 :     cp_parser_pragma (parser, pragma_objc_icode, NULL);
   36653                 :             :   /* Allow stray semicolons.  */
   36654                 :           0 :   else if (token->type == CPP_SEMICOLON)
   36655                 :           0 :     cp_lexer_consume_token (parser->lexer);
   36656                 :             :   /* Mark methods as optional or required, when building protocols.  */
   36657                 :           0 :   else if (token->keyword == RID_AT_OPTIONAL)
   36658                 :             :     {
   36659                 :           0 :       cp_lexer_consume_token (parser->lexer);
   36660                 :           0 :       objc_set_method_opt (true);
   36661                 :             :     }
   36662                 :           0 :   else if (token->keyword == RID_AT_REQUIRED)
   36663                 :             :     {
   36664                 :           0 :       cp_lexer_consume_token (parser->lexer);
   36665                 :           0 :       objc_set_method_opt (false);
   36666                 :             :     }
   36667                 :           0 :   else if (token->keyword == RID_NAMESPACE)
   36668                 :           0 :     cp_parser_namespace_definition (parser);
   36669                 :             :   /* Other stray characters must generate errors.  */
   36670                 :           0 :   else if (token->type == CPP_OPEN_BRACE || token->type == CPP_CLOSE_BRACE)
   36671                 :             :     {
   36672                 :           0 :       cp_lexer_consume_token (parser->lexer);
   36673                 :           0 :       error ("stray %qs between Objective-C++ methods",
   36674                 :           0 :              token->type == CPP_OPEN_BRACE ? "{" : "}");
   36675                 :             :     }
   36676                 :             :   /* Finally, try to parse a block-declaration, or a function-definition.  */
   36677                 :             :   else
   36678                 :           0 :     cp_parser_block_declaration (parser, /*statement_p=*/false);
   36679                 :           0 : }
   36680                 :             : 
   36681                 :             : /* Parse a method signature.  */
   36682                 :             : 
   36683                 :             : static tree
   36684                 :           0 : cp_parser_objc_method_signature (cp_parser* parser, tree* attributes)
   36685                 :             : {
   36686                 :           0 :   tree rettype, kwdparms, optparms;
   36687                 :           0 :   bool ellipsis = false;
   36688                 :           0 :   bool is_class_method;
   36689                 :             : 
   36690                 :           0 :   is_class_method = cp_parser_objc_method_type (parser);
   36691                 :           0 :   rettype = cp_parser_objc_typename (parser);
   36692                 :           0 :   *attributes = NULL_TREE;
   36693                 :           0 :   kwdparms = cp_parser_objc_method_keyword_params (parser, attributes);
   36694                 :           0 :   if (kwdparms == error_mark_node)
   36695                 :             :     return error_mark_node;
   36696                 :           0 :   optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis, attributes);
   36697                 :           0 :   if (optparms == error_mark_node)
   36698                 :             :     return error_mark_node;
   36699                 :             : 
   36700                 :           0 :   return objc_build_method_signature (is_class_method, rettype, kwdparms, optparms, ellipsis);
   36701                 :             : }
   36702                 :             : 
   36703                 :             : static bool
   36704                 :           0 : cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
   36705                 :             : {
   36706                 :           0 :   tree tattr;
   36707                 :           0 :   cp_lexer_save_tokens (parser->lexer);
   36708                 :           0 :   tattr = cp_parser_attributes_opt (parser);
   36709                 :           0 :   gcc_assert (tattr) ;
   36710                 :             : 
   36711                 :             :   /* If the attributes are followed by a method introducer, this is not allowed.
   36712                 :             :      Dump the attributes and flag the situation.  */
   36713                 :           0 :   if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS)
   36714                 :           0 :       || cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
   36715                 :             :     return true;
   36716                 :             : 
   36717                 :             :   /* Otherwise, the attributes introduce some interstitial code, possibly so
   36718                 :             :      rewind to allow that check.  */
   36719                 :           0 :   cp_lexer_rollback_tokens (parser->lexer);
   36720                 :           0 :   return false;
   36721                 :             : }
   36722                 :             : 
   36723                 :             : /* Parse an Objective-C method prototype list.  */
   36724                 :             : 
   36725                 :             : static void
   36726                 :           0 : cp_parser_objc_method_prototype_list (cp_parser* parser)
   36727                 :             : {
   36728                 :           0 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   36729                 :             : 
   36730                 :           0 :   while (token->keyword != RID_AT_END && token->type != CPP_EOF)
   36731                 :             :     {
   36732                 :           0 :       if (token->type == CPP_PLUS || token->type == CPP_MINUS)
   36733                 :             :         {
   36734                 :           0 :           tree attributes, sig;
   36735                 :           0 :           bool is_class_method;
   36736                 :           0 :           if (token->type == CPP_PLUS)
   36737                 :             :             is_class_method = true;
   36738                 :             :           else
   36739                 :           0 :             is_class_method = false;
   36740                 :           0 :           sig = cp_parser_objc_method_signature (parser, &attributes);
   36741                 :           0 :           if (sig == error_mark_node)
   36742                 :             :             {
   36743                 :           0 :               cp_parser_skip_to_end_of_block_or_statement (parser);
   36744                 :           0 :               token = cp_lexer_peek_token (parser->lexer);
   36745                 :           0 :               continue;
   36746                 :             :             }
   36747                 :           0 :           objc_add_method_declaration (is_class_method, sig, attributes);
   36748                 :           0 :           cp_parser_consume_semicolon_at_end_of_statement (parser);
   36749                 :             :         }
   36750                 :           0 :       else if (token->keyword == RID_AT_PROPERTY)
   36751                 :           0 :         cp_parser_objc_at_property_declaration (parser);
   36752                 :           0 :       else if (token->keyword == RID_ATTRIBUTE
   36753                 :           0 :                && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
   36754                 :           0 :         warning_at (cp_lexer_peek_token (parser->lexer)->location,
   36755                 :             :                     OPT_Wattributes,
   36756                 :             :                     "prefix attributes are ignored for methods");
   36757                 :             :       else
   36758                 :             :         /* Allow for interspersed non-ObjC++ code.  */
   36759                 :           0 :         cp_parser_objc_interstitial_code (parser);
   36760                 :             : 
   36761                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36762                 :             :     }
   36763                 :             : 
   36764                 :           0 :   if (token->type != CPP_EOF)
   36765                 :           0 :     cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
   36766                 :             :   else
   36767                 :           0 :     cp_parser_error (parser, "expected %<@end%>");
   36768                 :             : 
   36769                 :           0 :   objc_finish_interface ();
   36770                 :           0 : }
   36771                 :             : 
   36772                 :             : /* Parse an Objective-C method definition list.  */
   36773                 :             : 
   36774                 :             : static void
   36775                 :           0 : cp_parser_objc_method_definition_list (cp_parser* parser)
   36776                 :             : {
   36777                 :           0 :   for (;;)
   36778                 :             :     {
   36779                 :           0 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   36780                 :             : 
   36781                 :           0 :       if (token->keyword == RID_AT_END)
   36782                 :             :         {
   36783                 :           0 :           cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
   36784                 :           0 :           break;
   36785                 :             :         }
   36786                 :           0 :       else if (token->type == CPP_EOF)
   36787                 :             :         {
   36788                 :           0 :           cp_parser_error (parser, "expected %<@end%>");
   36789                 :           0 :           break;
   36790                 :             :         }
   36791                 :           0 :       else if (token->type == CPP_PLUS || token->type == CPP_MINUS)
   36792                 :             :         {
   36793                 :           0 :           bool is_class_method = token->type == CPP_PLUS;
   36794                 :             : 
   36795                 :           0 :           push_deferring_access_checks (dk_deferred);
   36796                 :           0 :           tree attribute;
   36797                 :           0 :           tree sig = cp_parser_objc_method_signature (parser, &attribute);
   36798                 :           0 :           if (sig == error_mark_node)
   36799                 :           0 :             cp_parser_skip_to_end_of_block_or_statement (parser);
   36800                 :             :           else
   36801                 :             :             {
   36802                 :           0 :               objc_start_method_definition (is_class_method, sig,
   36803                 :             :                                             attribute, NULL_TREE);
   36804                 :             : 
   36805                 :             :               /* For historical reasons, we accept an optional semicolon.  */
   36806                 :           0 :               if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   36807                 :           0 :                 cp_lexer_consume_token (parser->lexer);
   36808                 :             : 
   36809                 :           0 :               perform_deferred_access_checks (tf_warning_or_error);
   36810                 :           0 :               stop_deferring_access_checks ();
   36811                 :           0 :               tree meth
   36812                 :           0 :                 = cp_parser_function_definition_after_declarator (parser, false);
   36813                 :           0 :               pop_deferring_access_checks ();
   36814                 :           0 :               objc_finish_method_definition (meth);
   36815                 :             :             }
   36816                 :             :         }
   36817                 :             :       /* The following case will be removed once @synthesize is
   36818                 :             :          completely implemented.  */
   36819                 :           0 :       else if (token->keyword == RID_AT_PROPERTY)
   36820                 :           0 :         cp_parser_objc_at_property_declaration (parser);
   36821                 :           0 :       else if (token->keyword == RID_AT_SYNTHESIZE)
   36822                 :           0 :         cp_parser_objc_at_synthesize_declaration (parser);
   36823                 :           0 :       else if (token->keyword == RID_AT_DYNAMIC)
   36824                 :           0 :         cp_parser_objc_at_dynamic_declaration (parser);
   36825                 :           0 :       else if (token->keyword == RID_ATTRIBUTE
   36826                 :           0 :                && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
   36827                 :           0 :         warning_at (token->location, OPT_Wattributes,
   36828                 :             :                     "prefix attributes are ignored for methods");
   36829                 :             :       else
   36830                 :             :         /* Allow for interspersed non-ObjC++ code.  */
   36831                 :           0 :         cp_parser_objc_interstitial_code (parser);
   36832                 :             :     }
   36833                 :             : 
   36834                 :           0 :   objc_finish_implementation ();
   36835                 :           0 : }
   36836                 :             : 
   36837                 :             : /* Parse Objective-C ivars.  */
   36838                 :             : 
   36839                 :             : static void
   36840                 :           0 : cp_parser_objc_class_ivars (cp_parser* parser)
   36841                 :             : {
   36842                 :           0 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   36843                 :             : 
   36844                 :           0 :   if (token->type != CPP_OPEN_BRACE)
   36845                 :             :     return;     /* No ivars specified.  */
   36846                 :             : 
   36847                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '{'.  */
   36848                 :           0 :   token = cp_lexer_peek_token (parser->lexer);
   36849                 :             : 
   36850                 :           0 :   while (token->type != CPP_CLOSE_BRACE
   36851                 :           0 :         && token->keyword != RID_AT_END && token->type != CPP_EOF)
   36852                 :             :     {
   36853                 :           0 :       cp_decl_specifier_seq declspecs;
   36854                 :           0 :       int decl_class_or_enum_p;
   36855                 :           0 :       tree prefix_attributes;
   36856                 :             : 
   36857                 :           0 :       cp_parser_objc_visibility_spec (parser);
   36858                 :             : 
   36859                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   36860                 :             :         break;
   36861                 :             : 
   36862                 :           0 :       cp_parser_decl_specifier_seq (parser,
   36863                 :             :                                     CP_PARSER_FLAGS_OPTIONAL,
   36864                 :             :                                     &declspecs,
   36865                 :             :                                     &decl_class_or_enum_p);
   36866                 :             : 
   36867                 :             :       /* auto, register, static, extern, mutable.  */
   36868                 :           0 :       if (declspecs.storage_class != sc_none)
   36869                 :             :         {
   36870                 :           0 :           cp_parser_error (parser, "invalid type for instance variable");
   36871                 :           0 :           declspecs.storage_class = sc_none;
   36872                 :             :         }
   36873                 :             : 
   36874                 :             :       /* thread_local.  */
   36875                 :           0 :       if (decl_spec_seq_has_spec_p (&declspecs, ds_thread))
   36876                 :             :         {
   36877                 :           0 :           cp_parser_error (parser, "invalid type for instance variable");
   36878                 :           0 :           declspecs.locations[ds_thread] = 0;
   36879                 :             :         }
   36880                 :             : 
   36881                 :             :       /* typedef.  */
   36882                 :           0 :       if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
   36883                 :             :         {
   36884                 :           0 :           cp_parser_error (parser, "invalid type for instance variable");
   36885                 :           0 :           declspecs.locations[ds_typedef] = 0;
   36886                 :             :         }
   36887                 :             : 
   36888                 :           0 :       prefix_attributes = declspecs.attributes;
   36889                 :           0 :       declspecs.attributes = NULL_TREE;
   36890                 :             : 
   36891                 :             :       /* Keep going until we hit the `;' at the end of the
   36892                 :             :          declaration.  */
   36893                 :           0 :       while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   36894                 :             :         {
   36895                 :           0 :           tree width = NULL_TREE, attributes, first_attribute, decl;
   36896                 :           0 :           cp_declarator *declarator = NULL;
   36897                 :           0 :           int ctor_dtor_or_conv_p;
   36898                 :             : 
   36899                 :             :           /* Check for a (possibly unnamed) bitfield declaration.  */
   36900                 :           0 :           token = cp_lexer_peek_token (parser->lexer);
   36901                 :           0 :           if (token->type == CPP_COLON)
   36902                 :           0 :             goto eat_colon;
   36903                 :             : 
   36904                 :           0 :           if (token->type == CPP_NAME
   36905                 :           0 :               && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
   36906                 :             :                   == CPP_COLON))
   36907                 :             :             {
   36908                 :             :               /* Get the name of the bitfield.  */
   36909                 :           0 :               declarator = make_id_declarator (NULL_TREE,
   36910                 :           0 :                                                cp_parser_identifier (parser),
   36911                 :             :                                                sfk_none, token->location);
   36912                 :             : 
   36913                 :           0 :              eat_colon:
   36914                 :           0 :               cp_lexer_consume_token (parser->lexer);  /* Eat ':'.  */
   36915                 :             :               /* Get the width of the bitfield.  */
   36916                 :           0 :               width
   36917                 :           0 :                 = cp_parser_constant_expression (parser);
   36918                 :             :             }
   36919                 :             :           else
   36920                 :             :             {
   36921                 :             :               /* Parse the declarator.  */
   36922                 :           0 :               declarator
   36923                 :           0 :                 = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
   36924                 :             :                                         CP_PARSER_FLAGS_NONE,
   36925                 :             :                                         &ctor_dtor_or_conv_p,
   36926                 :             :                                         /*parenthesized_p=*/NULL,
   36927                 :             :                                         /*member_p=*/false,
   36928                 :             :                                         /*friend_p=*/false,
   36929                 :             :                                         /*static_p=*/false);
   36930                 :             :             }
   36931                 :             : 
   36932                 :             :           /* Look for attributes that apply to the ivar.  */
   36933                 :           0 :           attributes = cp_parser_attributes_opt (parser);
   36934                 :             :           /* Remember which attributes are prefix attributes and
   36935                 :             :              which are not.  */
   36936                 :           0 :           first_attribute = attributes;
   36937                 :             :           /* Combine the attributes.  */
   36938                 :           0 :           attributes = attr_chainon (prefix_attributes, attributes);
   36939                 :             : 
   36940                 :           0 :           if (width)
   36941                 :             :             /* Create the bitfield declaration.  */
   36942                 :           0 :             decl = grokbitfield (declarator, &declspecs,
   36943                 :             :                                  width, NULL_TREE, attributes);
   36944                 :             :           else
   36945                 :           0 :             decl = grokfield (declarator, &declspecs,
   36946                 :             :                               NULL_TREE, /*init_const_expr_p=*/false,
   36947                 :             :                               NULL_TREE, attributes);
   36948                 :             : 
   36949                 :             :           /* Add the instance variable.  */
   36950                 :           0 :           if (decl != error_mark_node && decl != NULL_TREE)
   36951                 :           0 :             objc_add_instance_variable (decl);
   36952                 :             : 
   36953                 :             :           /* Reset PREFIX_ATTRIBUTES.  */
   36954                 :           0 :           if (attributes != error_mark_node)
   36955                 :             :             {
   36956                 :           0 :               while (attributes && TREE_CHAIN (attributes) != first_attribute)
   36957                 :           0 :                 attributes = TREE_CHAIN (attributes);
   36958                 :           0 :               if (attributes)
   36959                 :           0 :                 TREE_CHAIN (attributes) = NULL_TREE;
   36960                 :             :             }
   36961                 :             : 
   36962                 :           0 :           token = cp_lexer_peek_token (parser->lexer);
   36963                 :             : 
   36964                 :           0 :           if (token->type == CPP_COMMA)
   36965                 :             :             {
   36966                 :           0 :               cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
   36967                 :           0 :               continue;
   36968                 :             :             }
   36969                 :           0 :           break;
   36970                 :             :         }
   36971                 :             : 
   36972                 :           0 :       cp_parser_consume_semicolon_at_end_of_statement (parser);
   36973                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   36974                 :             :     }
   36975                 :             : 
   36976                 :           0 :   if (token->keyword == RID_AT_END)
   36977                 :           0 :     cp_parser_error (parser, "expected %<}%>");
   36978                 :             : 
   36979                 :             :   /* Do not consume the RID_AT_END, so it will be read again as terminating
   36980                 :             :      the @interface of @implementation.  */
   36981                 :           0 :   if (token->keyword != RID_AT_END && token->type != CPP_EOF)
   36982                 :           0 :     cp_lexer_consume_token (parser->lexer);  /* Eat '}'.  */
   36983                 :             : 
   36984                 :             :   /* For historical reasons, we accept an optional semicolon.  */
   36985                 :           0 :   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   36986                 :           0 :     cp_lexer_consume_token (parser->lexer);
   36987                 :             : }
   36988                 :             : 
   36989                 :             : /* Parse an Objective-C protocol declaration.  */
   36990                 :             : 
   36991                 :             : static void
   36992                 :           0 : cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
   36993                 :             : {
   36994                 :           0 :   tree proto, protorefs;
   36995                 :           0 :   cp_token *tok;
   36996                 :             : 
   36997                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@protocol'.  */
   36998                 :           0 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
   36999                 :             :     {
   37000                 :           0 :       tok = cp_lexer_peek_token (parser->lexer);
   37001                 :           0 :       error_at (tok->location, "identifier expected after %<@protocol%>");
   37002                 :           0 :       cp_parser_consume_semicolon_at_end_of_statement (parser);
   37003                 :           0 :       return;
   37004                 :             :     }
   37005                 :             : 
   37006                 :             :   /* See if we have a forward declaration or a definition.  */
   37007                 :           0 :   tok = cp_lexer_peek_nth_token (parser->lexer, 2);
   37008                 :             : 
   37009                 :             :   /* Try a forward declaration first.  */
   37010                 :           0 :   if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON)
   37011                 :             :     {
   37012                 :           0 :       while (true)
   37013                 :             :         {
   37014                 :           0 :           tree id;
   37015                 :             : 
   37016                 :           0 :           id = cp_parser_identifier (parser);
   37017                 :           0 :           if (id == error_mark_node)
   37018                 :             :             break;
   37019                 :             : 
   37020                 :           0 :           objc_declare_protocol (id, attributes);
   37021                 :             : 
   37022                 :           0 :           if(cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   37023                 :           0 :             cp_lexer_consume_token (parser->lexer);
   37024                 :             :           else
   37025                 :             :             break;
   37026                 :           0 :         }
   37027                 :           0 :       cp_parser_consume_semicolon_at_end_of_statement (parser);
   37028                 :           0 :     }
   37029                 :             : 
   37030                 :             :   /* Ok, we got a full-fledged definition (or at least should).  */
   37031                 :             :   else
   37032                 :             :     {
   37033                 :           0 :       proto = cp_parser_identifier (parser);
   37034                 :           0 :       protorefs = cp_parser_objc_protocol_refs_opt (parser);
   37035                 :           0 :       objc_start_protocol (proto, protorefs, attributes);
   37036                 :           0 :       cp_parser_objc_method_prototype_list (parser);
   37037                 :             :     }
   37038                 :             : }
   37039                 :             : 
   37040                 :             : /* Parse an Objective-C superclass or category.  */
   37041                 :             : 
   37042                 :             : static void
   37043                 :           0 : cp_parser_objc_superclass_or_category (cp_parser *parser,
   37044                 :             :                                        bool iface_p,
   37045                 :             :                                        tree *super,
   37046                 :             :                                        tree *categ, bool *is_class_extension)
   37047                 :             : {
   37048                 :           0 :   cp_token *next = cp_lexer_peek_token (parser->lexer);
   37049                 :             : 
   37050                 :           0 :   *super = *categ = NULL_TREE;
   37051                 :           0 :   *is_class_extension = false;
   37052                 :           0 :   if (next->type == CPP_COLON)
   37053                 :             :     {
   37054                 :           0 :       cp_lexer_consume_token (parser->lexer);  /* Eat ':'.  */
   37055                 :           0 :       *super = cp_parser_identifier (parser);
   37056                 :             :     }
   37057                 :           0 :   else if (next->type == CPP_OPEN_PAREN)
   37058                 :             :     {
   37059                 :           0 :       matching_parens parens;
   37060                 :           0 :       parens.consume_open (parser);  /* Eat '('.  */
   37061                 :             : 
   37062                 :             :       /* If there is no category name, and this is an @interface, we
   37063                 :             :          have a class extension.  */
   37064                 :           0 :       if (iface_p && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
   37065                 :             :         {
   37066                 :           0 :           *categ = NULL_TREE;
   37067                 :           0 :           *is_class_extension = true;
   37068                 :             :         }
   37069                 :             :       else
   37070                 :           0 :         *categ = cp_parser_identifier (parser);
   37071                 :             : 
   37072                 :           0 :       parens.require_close (parser);
   37073                 :             :     }
   37074                 :           0 : }
   37075                 :             : 
   37076                 :             : /* Parse an Objective-C class interface.  */
   37077                 :             : 
   37078                 :             : static void
   37079                 :           0 : cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
   37080                 :             : {
   37081                 :           0 :   tree name, super, categ, protos;
   37082                 :           0 :   bool is_class_extension;
   37083                 :             : 
   37084                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@interface'.  */
   37085                 :           0 :   location_t nam_loc = cp_lexer_peek_token (parser->lexer)->location;
   37086                 :           0 :   name = cp_parser_identifier (parser);
   37087                 :           0 :   if (name == error_mark_node)
   37088                 :             :     {
   37089                 :             :       /* It's hard to recover because even if valid @interface stuff
   37090                 :             :          is to follow, we can't compile it (or validate it) if we
   37091                 :             :          don't even know which class it refers to.  Let's assume this
   37092                 :             :          was a stray '@interface' token in the stream and skip it.
   37093                 :             :       */
   37094                 :           0 :       return;
   37095                 :             :     }
   37096                 :           0 :   cp_parser_objc_superclass_or_category (parser, true, &super, &categ,
   37097                 :             :                                          &is_class_extension);
   37098                 :           0 :   protos = cp_parser_objc_protocol_refs_opt (parser);
   37099                 :             : 
   37100                 :             :   /* We have either a class or a category on our hands.  */
   37101                 :           0 :   if (categ || is_class_extension)
   37102                 :           0 :     objc_start_category_interface (name, categ, protos, attributes);
   37103                 :             :   else
   37104                 :             :     {
   37105                 :           0 :       objc_start_class_interface (name, nam_loc, super, protos, attributes);
   37106                 :             :       /* Handle instance variable declarations, if any.  */
   37107                 :           0 :       cp_parser_objc_class_ivars (parser);
   37108                 :           0 :       objc_continue_interface ();
   37109                 :             :     }
   37110                 :             : 
   37111                 :           0 :   cp_parser_objc_method_prototype_list (parser);
   37112                 :             : }
   37113                 :             : 
   37114                 :             : /* Parse an Objective-C class implementation.  */
   37115                 :             : 
   37116                 :             : static void
   37117                 :           0 : cp_parser_objc_class_implementation (cp_parser* parser)
   37118                 :             : {
   37119                 :           0 :   tree name, super, categ;
   37120                 :           0 :   bool is_class_extension;
   37121                 :             : 
   37122                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@implementation'.  */
   37123                 :           0 :   name = cp_parser_identifier (parser);
   37124                 :           0 :   if (name == error_mark_node)
   37125                 :             :     {
   37126                 :             :       /* It's hard to recover because even if valid @implementation
   37127                 :             :          stuff is to follow, we can't compile it (or validate it) if
   37128                 :             :          we don't even know which class it refers to.  Let's assume
   37129                 :             :          this was a stray '@implementation' token in the stream and
   37130                 :             :          skip it.
   37131                 :             :       */
   37132                 :           0 :       return;
   37133                 :             :     }
   37134                 :           0 :   cp_parser_objc_superclass_or_category (parser, false, &super, &categ,
   37135                 :             :                                          &is_class_extension);
   37136                 :             : 
   37137                 :             :   /* We have either a class or a category on our hands.  */
   37138                 :           0 :   if (categ)
   37139                 :           0 :     objc_start_category_implementation (name, categ);
   37140                 :             :   else
   37141                 :             :     {
   37142                 :           0 :       objc_start_class_implementation (name, super);
   37143                 :             :       /* Handle instance variable declarations, if any.  */
   37144                 :           0 :       cp_parser_objc_class_ivars (parser);
   37145                 :           0 :       objc_continue_implementation ();
   37146                 :             :     }
   37147                 :             : 
   37148                 :           0 :   cp_parser_objc_method_definition_list (parser);
   37149                 :             : }
   37150                 :             : 
   37151                 :             : /* Consume the @end token and finish off the implementation.  */
   37152                 :             : 
   37153                 :             : static void
   37154                 :           0 : cp_parser_objc_end_implementation (cp_parser* parser)
   37155                 :             : {
   37156                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
   37157                 :           0 :   objc_finish_implementation ();
   37158                 :           0 : }
   37159                 :             : 
   37160                 :             : /* Parse an Objective-C declaration.  */
   37161                 :             : 
   37162                 :             : static void
   37163                 :           0 : cp_parser_objc_declaration (cp_parser* parser, tree attributes)
   37164                 :             : {
   37165                 :             :   /* Try to figure out what kind of declaration is present.  */
   37166                 :           0 :   cp_token *kwd = cp_lexer_peek_token (parser->lexer);
   37167                 :             : 
   37168                 :           0 :   if (attributes)
   37169                 :           0 :     switch (kwd->keyword)
   37170                 :             :       {
   37171                 :           0 :         case RID_AT_ALIAS:
   37172                 :           0 :         case RID_AT_CLASS:
   37173                 :           0 :         case RID_AT_END:
   37174                 :           0 :           error_at (kwd->location, "attributes may not be specified before"
   37175                 :             :                     " the %<@%D%> Objective-C++ keyword",
   37176                 :             :                     kwd->u.value);
   37177                 :           0 :           attributes = NULL;
   37178                 :           0 :           break;
   37179                 :           0 :         case RID_AT_IMPLEMENTATION:
   37180                 :           0 :           warning_at (kwd->location, OPT_Wattributes,
   37181                 :             :                       "prefix attributes are ignored before %<@%D%>",
   37182                 :             :                       kwd->u.value);
   37183                 :           0 :           attributes = NULL;
   37184                 :             :         default:
   37185                 :             :           break;
   37186                 :             :       }
   37187                 :             : 
   37188                 :           0 :   switch (kwd->keyword)
   37189                 :             :     {
   37190                 :           0 :     case RID_AT_ALIAS:
   37191                 :           0 :       cp_parser_objc_alias_declaration (parser);
   37192                 :           0 :       break;
   37193                 :           0 :     case RID_AT_CLASS:
   37194                 :           0 :       cp_parser_objc_class_declaration (parser);
   37195                 :           0 :       break;
   37196                 :           0 :     case RID_AT_PROTOCOL:
   37197                 :           0 :       cp_parser_objc_protocol_declaration (parser, attributes);
   37198                 :           0 :       break;
   37199                 :           0 :     case RID_AT_INTERFACE:
   37200                 :           0 :       cp_parser_objc_class_interface (parser, attributes);
   37201                 :           0 :       break;
   37202                 :           0 :     case RID_AT_IMPLEMENTATION:
   37203                 :           0 :       cp_parser_objc_class_implementation (parser);
   37204                 :           0 :       break;
   37205                 :           0 :     case RID_AT_END:
   37206                 :           0 :       cp_parser_objc_end_implementation (parser);
   37207                 :           0 :       break;
   37208                 :           0 :     default:
   37209                 :           0 :       error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
   37210                 :             :                 kwd->u.value);
   37211                 :           0 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   37212                 :             :     }
   37213                 :           0 : }
   37214                 :             : 
   37215                 :             : /* Parse an Objective-C try-catch-finally statement.
   37216                 :             : 
   37217                 :             :    objc-try-catch-finally-stmt:
   37218                 :             :      @try compound-statement objc-catch-clause-seq [opt]
   37219                 :             :        objc-finally-clause [opt]
   37220                 :             : 
   37221                 :             :    objc-catch-clause-seq:
   37222                 :             :      objc-catch-clause objc-catch-clause-seq [opt]
   37223                 :             : 
   37224                 :             :    objc-catch-clause:
   37225                 :             :      @catch ( objc-exception-declaration ) compound-statement
   37226                 :             : 
   37227                 :             :    objc-finally-clause:
   37228                 :             :      @finally compound-statement
   37229                 :             : 
   37230                 :             :    objc-exception-declaration:
   37231                 :             :      parameter-declaration
   37232                 :             :      '...'
   37233                 :             : 
   37234                 :             :    where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
   37235                 :             : 
   37236                 :             :    Returns NULL_TREE.
   37237                 :             : 
   37238                 :             :    PS: This function is identical to c_parser_objc_try_catch_finally_statement
   37239                 :             :    for C.  Keep them in sync.  */
   37240                 :             : 
   37241                 :             : static tree
   37242                 :           0 : cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
   37243                 :             : {
   37244                 :           0 :   location_t location;
   37245                 :           0 :   tree stmt;
   37246                 :             : 
   37247                 :           0 :   cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_TRY);
   37248                 :           0 :   location = cp_lexer_peek_token (parser->lexer)->location;
   37249                 :           0 :   objc_maybe_warn_exceptions (location);
   37250                 :             :   /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST
   37251                 :             :      node, lest it get absorbed into the surrounding block.  */
   37252                 :           0 :   stmt = push_stmt_list ();
   37253                 :           0 :   cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
   37254                 :           0 :   objc_begin_try_stmt (location, pop_stmt_list (stmt));
   37255                 :             : 
   37256                 :           0 :   while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH))
   37257                 :             :     {
   37258                 :           0 :       cp_parameter_declarator *parm;
   37259                 :           0 :       tree parameter_declaration = error_mark_node;
   37260                 :           0 :       bool seen_open_paren = false;
   37261                 :           0 :       matching_parens parens;
   37262                 :             : 
   37263                 :           0 :       cp_lexer_consume_token (parser->lexer);
   37264                 :           0 :       if (parens.require_open (parser))
   37265                 :             :         seen_open_paren = true;
   37266                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
   37267                 :             :         {
   37268                 :             :           /* We have "@catch (...)" (where the '...' are literally
   37269                 :             :              what is in the code).  Skip the '...'.
   37270                 :             :              parameter_declaration is set to NULL_TREE, and
   37271                 :             :              objc_being_catch_clauses() knows that that means
   37272                 :             :              '...'.  */
   37273                 :           0 :           cp_lexer_consume_token (parser->lexer);
   37274                 :           0 :           parameter_declaration = NULL_TREE;
   37275                 :             :         }
   37276                 :             :       else
   37277                 :             :         {
   37278                 :             :           /* We have "@catch (NSException *exception)" or something
   37279                 :             :              like that.  Parse the parameter declaration.  */
   37280                 :           0 :           parm = cp_parser_parameter_declaration (parser, CP_PARSER_FLAGS_NONE,
   37281                 :             :                                                   false, NULL);
   37282                 :           0 :           if (parm == NULL)
   37283                 :           0 :             parameter_declaration = error_mark_node;
   37284                 :             :           else
   37285                 :           0 :             parameter_declaration = grokdeclarator (parm->declarator,
   37286                 :             :                                                     &parm->decl_specifiers,
   37287                 :             :                                                     PARM, /*initialized=*/0,
   37288                 :             :                                                     /*attrlist=*/NULL);
   37289                 :             :         }
   37290                 :           0 :       if (seen_open_paren)
   37291                 :           0 :         parens.require_close (parser);
   37292                 :             :       else
   37293                 :             :         {
   37294                 :             :           /* If there was no open parenthesis, we are recovering from
   37295                 :             :              an error, and we are trying to figure out what mistake
   37296                 :             :              the user has made.  */
   37297                 :             : 
   37298                 :             :           /* If there is an immediate closing parenthesis, the user
   37299                 :             :              probably forgot the opening one (ie, they typed "@catch
   37300                 :             :              NSException *e)".  Parse the closing parenthesis and keep
   37301                 :             :              going.  */
   37302                 :           0 :           if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
   37303                 :           0 :             cp_lexer_consume_token (parser->lexer);
   37304                 :             : 
   37305                 :             :           /* If these is no immediate closing parenthesis, the user
   37306                 :             :              probably doesn't know that parenthesis are required at
   37307                 :             :              all (ie, they typed "@catch NSException *e").  So, just
   37308                 :             :              forget about the closing parenthesis and keep going.  */
   37309                 :             :         }
   37310                 :           0 :       objc_begin_catch_clause (parameter_declaration);
   37311                 :           0 :       cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
   37312                 :           0 :       objc_finish_catch_clause ();
   37313                 :             :     }
   37314                 :           0 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY))
   37315                 :             :     {
   37316                 :           0 :       cp_lexer_consume_token (parser->lexer);
   37317                 :           0 :       location = cp_lexer_peek_token (parser->lexer)->location;
   37318                 :             :       /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST
   37319                 :             :          node, lest it get absorbed into the surrounding block.  */
   37320                 :           0 :       stmt = push_stmt_list ();
   37321                 :           0 :       cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
   37322                 :           0 :       objc_build_finally_clause (location, pop_stmt_list (stmt));
   37323                 :             :     }
   37324                 :             : 
   37325                 :           0 :   return objc_finish_try_stmt ();
   37326                 :             : }
   37327                 :             : 
   37328                 :             : /* Parse an Objective-C synchronized statement.
   37329                 :             : 
   37330                 :             :    objc-synchronized-stmt:
   37331                 :             :      @synchronized ( expression ) compound-statement
   37332                 :             : 
   37333                 :             :    Returns NULL_TREE.  */
   37334                 :             : 
   37335                 :             : static tree
   37336                 :           0 : cp_parser_objc_synchronized_statement (cp_parser *parser)
   37337                 :             : {
   37338                 :           0 :   location_t location;
   37339                 :           0 :   tree lock, stmt;
   37340                 :             : 
   37341                 :           0 :   cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED);
   37342                 :             : 
   37343                 :           0 :   location = cp_lexer_peek_token (parser->lexer)->location;
   37344                 :           0 :   objc_maybe_warn_exceptions (location);
   37345                 :           0 :   matching_parens parens;
   37346                 :           0 :   parens.require_open (parser);
   37347                 :           0 :   lock = cp_parser_expression (parser);
   37348                 :           0 :   parens.require_close (parser);
   37349                 :             : 
   37350                 :             :   /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
   37351                 :             :      node, lest it get absorbed into the surrounding block.  */
   37352                 :           0 :   stmt = push_stmt_list ();
   37353                 :           0 :   cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
   37354                 :             : 
   37355                 :           0 :   return objc_build_synchronized (location, lock, pop_stmt_list (stmt));
   37356                 :             : }
   37357                 :             : 
   37358                 :             : /* Parse an Objective-C throw statement.
   37359                 :             : 
   37360                 :             :    objc-throw-stmt:
   37361                 :             :      @throw assignment-expression [opt] ;
   37362                 :             : 
   37363                 :             :    Returns a constructed '@throw' statement.  */
   37364                 :             : 
   37365                 :             : static tree
   37366                 :           0 : cp_parser_objc_throw_statement (cp_parser *parser)
   37367                 :             : {
   37368                 :           0 :   tree expr = NULL_TREE;
   37369                 :           0 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   37370                 :             : 
   37371                 :           0 :   cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW);
   37372                 :             : 
   37373                 :           0 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   37374                 :           0 :     expr = cp_parser_expression (parser);
   37375                 :             : 
   37376                 :           0 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   37377                 :             : 
   37378                 :           0 :   return objc_build_throw_stmt (loc, expr);
   37379                 :             : }
   37380                 :             : 
   37381                 :             : /* Parse an Objective-C statement.  */
   37382                 :             : 
   37383                 :             : static tree
   37384                 :           0 : cp_parser_objc_statement (cp_parser * parser)
   37385                 :             : {
   37386                 :             :   /* Try to figure out what kind of declaration is present.  */
   37387                 :           0 :   cp_token *kwd = cp_lexer_peek_token (parser->lexer);
   37388                 :             : 
   37389                 :           0 :   switch (kwd->keyword)
   37390                 :             :     {
   37391                 :           0 :     case RID_AT_TRY:
   37392                 :           0 :       return cp_parser_objc_try_catch_finally_statement (parser);
   37393                 :           0 :     case RID_AT_SYNCHRONIZED:
   37394                 :           0 :       return cp_parser_objc_synchronized_statement (parser);
   37395                 :           0 :     case RID_AT_THROW:
   37396                 :           0 :       return cp_parser_objc_throw_statement (parser);
   37397                 :           0 :     default:
   37398                 :           0 :       error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
   37399                 :             :                kwd->u.value);
   37400                 :           0 :       cp_parser_skip_to_end_of_block_or_statement (parser);
   37401                 :             :     }
   37402                 :             : 
   37403                 :           0 :   return error_mark_node;
   37404                 :             : }
   37405                 :             : 
   37406                 :             : /* If we are compiling ObjC++ and we see an __attribute__ we neeed to
   37407                 :             :    look ahead to see if an objc keyword follows the attributes.  This
   37408                 :             :    is to detect the use of prefix attributes on ObjC @interface and
   37409                 :             :    @protocol.  */
   37410                 :             : 
   37411                 :             : static bool
   37412                 :           0 : cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib)
   37413                 :             : {
   37414                 :           0 :   cp_lexer_save_tokens (parser->lexer);
   37415                 :           0 :   tree addon = cp_parser_attributes_opt (parser);
   37416                 :           0 :   if (addon
   37417                 :           0 :       && OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
   37418                 :             :     {
   37419                 :           0 :       cp_lexer_commit_tokens (parser->lexer);
   37420                 :           0 :       if (*attrib)
   37421                 :           0 :         TREE_CHAIN (*attrib) = addon;
   37422                 :             :       else
   37423                 :           0 :         *attrib = addon;
   37424                 :           0 :       return true;
   37425                 :             :     }
   37426                 :           0 :   cp_lexer_rollback_tokens (parser->lexer);
   37427                 :           0 :   return false;
   37428                 :             : }
   37429                 :             : 
   37430                 :             : /* This routine is a minimal replacement for
   37431                 :             :    c_parser_struct_declaration () used when parsing the list of
   37432                 :             :    types/names or ObjC++ properties.  For example, when parsing the
   37433                 :             :    code
   37434                 :             : 
   37435                 :             :    @property (readonly) int a, b, c;
   37436                 :             : 
   37437                 :             :    this function is responsible for parsing "int a, int b, int c" and
   37438                 :             :    returning the declarations as CHAIN of DECLs.
   37439                 :             : 
   37440                 :             :    TODO: Share this code with cp_parser_objc_class_ivars.  It's very
   37441                 :             :    similar parsing.  */
   37442                 :             : static tree
   37443                 :           0 : cp_parser_objc_struct_declaration (cp_parser *parser)
   37444                 :             : {
   37445                 :           0 :   tree decls = NULL_TREE;
   37446                 :           0 :   cp_decl_specifier_seq declspecs;
   37447                 :           0 :   int decl_class_or_enum_p;
   37448                 :           0 :   tree prefix_attributes;
   37449                 :             : 
   37450                 :           0 :   cp_parser_decl_specifier_seq (parser,
   37451                 :             :                                 CP_PARSER_FLAGS_NONE,
   37452                 :             :                                 &declspecs,
   37453                 :             :                                 &decl_class_or_enum_p);
   37454                 :             : 
   37455                 :           0 :   if (declspecs.type == error_mark_node)
   37456                 :             :     return error_mark_node;
   37457                 :             : 
   37458                 :             :   /* auto, register, static, extern, mutable.  */
   37459                 :           0 :   if (declspecs.storage_class != sc_none)
   37460                 :             :     {
   37461                 :           0 :       cp_parser_error (parser, "invalid type for property");
   37462                 :           0 :       declspecs.storage_class = sc_none;
   37463                 :             :     }
   37464                 :             : 
   37465                 :             :   /* thread_local.  */
   37466                 :           0 :   if (decl_spec_seq_has_spec_p (&declspecs, ds_thread))
   37467                 :             :     {
   37468                 :           0 :       cp_parser_error (parser, "invalid type for property");
   37469                 :           0 :       declspecs.locations[ds_thread] = 0;
   37470                 :             :     }
   37471                 :             : 
   37472                 :             :   /* typedef.  */
   37473                 :           0 :   if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
   37474                 :             :     {
   37475                 :           0 :       cp_parser_error (parser, "invalid type for property");
   37476                 :           0 :       declspecs.locations[ds_typedef] = 0;
   37477                 :             :     }
   37478                 :             : 
   37479                 :           0 :   prefix_attributes = declspecs.attributes;
   37480                 :           0 :   declspecs.attributes = NULL_TREE;
   37481                 :             : 
   37482                 :             :   /* Keep going until we hit the `;' at the end of the declaration. */
   37483                 :           0 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   37484                 :             :     {
   37485                 :           0 :       tree attributes, first_attribute, decl;
   37486                 :           0 :       cp_declarator *declarator;
   37487                 :           0 :       cp_token *token;
   37488                 :             : 
   37489                 :             :       /* Parse the declarator.  */
   37490                 :           0 :       declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
   37491                 :             :                                          CP_PARSER_FLAGS_NONE,
   37492                 :             :                                          NULL, NULL, false, false, false);
   37493                 :             : 
   37494                 :             :       /* Look for attributes that apply to the ivar.  */
   37495                 :           0 :       attributes = cp_parser_attributes_opt (parser);
   37496                 :             :       /* Remember which attributes are prefix attributes and
   37497                 :             :          which are not.  */
   37498                 :           0 :       first_attribute = attributes;
   37499                 :             :       /* Combine the attributes.  */
   37500                 :           0 :       attributes = attr_chainon (prefix_attributes, attributes);
   37501                 :             : 
   37502                 :           0 :       decl = grokfield (declarator, &declspecs,
   37503                 :             :                         NULL_TREE, /*init_const_expr_p=*/false,
   37504                 :             :                         NULL_TREE, attributes);
   37505                 :             : 
   37506                 :           0 :       if (decl == error_mark_node || decl == NULL_TREE)
   37507                 :           0 :         return error_mark_node;
   37508                 :             : 
   37509                 :             :       /* Reset PREFIX_ATTRIBUTES.  */
   37510                 :           0 :       if (attributes != error_mark_node)
   37511                 :             :         {
   37512                 :           0 :           while (attributes && TREE_CHAIN (attributes) != first_attribute)
   37513                 :           0 :             attributes = TREE_CHAIN (attributes);
   37514                 :           0 :           if (attributes)
   37515                 :           0 :             TREE_CHAIN (attributes) = NULL_TREE;
   37516                 :             :         }
   37517                 :             : 
   37518                 :           0 :       DECL_CHAIN (decl) = decls;
   37519                 :           0 :       decls = decl;
   37520                 :             : 
   37521                 :           0 :       token = cp_lexer_peek_token (parser->lexer);
   37522                 :           0 :       if (token->type == CPP_COMMA)
   37523                 :             :         {
   37524                 :           0 :           cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
   37525                 :           0 :           continue;
   37526                 :             :         }
   37527                 :             :       else
   37528                 :             :         break;
   37529                 :             :     }
   37530                 :             :   return decls;
   37531                 :             : }
   37532                 :             : 
   37533                 :             : /* Parse an Objective-C @property declaration.  The syntax is:
   37534                 :             : 
   37535                 :             :    objc-property-declaration:
   37536                 :             :      '@property' objc-property-attributes[opt] struct-declaration ;
   37537                 :             : 
   37538                 :             :    objc-property-attributes:
   37539                 :             :     '(' objc-property-attribute-list ')'
   37540                 :             : 
   37541                 :             :    objc-property-attribute-list:
   37542                 :             :      objc-property-attribute
   37543                 :             :      objc-property-attribute-list, objc-property-attribute
   37544                 :             : 
   37545                 :             :    objc-property-attribute
   37546                 :             :      'getter' = identifier
   37547                 :             :      'setter' = identifier
   37548                 :             :      'readonly'
   37549                 :             :      'readwrite'
   37550                 :             :      'assign'
   37551                 :             :      'retain'
   37552                 :             :      'copy'
   37553                 :             :      'nonatomic'
   37554                 :             : 
   37555                 :             :   For example:
   37556                 :             :     @property NSString *name;
   37557                 :             :     @property (readonly) id object;
   37558                 :             :     @property (retain, nonatomic, getter=getTheName) id name;
   37559                 :             :     @property int a, b, c;
   37560                 :             : 
   37561                 :             :    PS: This function is identical to
   37562                 :             :    c_parser_objc_at_property_declaration for C.  Keep them in sync.  */
   37563                 :             : static void
   37564                 :           0 : cp_parser_objc_at_property_declaration (cp_parser *parser)
   37565                 :             : {
   37566                 :             :   /* Parse the optional attribute list.
   37567                 :             : 
   37568                 :             :      A list of parsed, but not verified, attributes.  */
   37569                 :           0 :   auto_delete_vec<property_attribute_info> prop_attr_list;
   37570                 :           0 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   37571                 :             : 
   37572                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@property'.  */
   37573                 :             : 
   37574                 :             :   /* Parse the optional attribute list...  */
   37575                 :           0 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   37576                 :             :     {
   37577                 :             :       /* Eat the '('.  */
   37578                 :           0 :       matching_parens parens;
   37579                 :           0 :       location_t attr_start = cp_lexer_peek_token (parser->lexer)->location;
   37580                 :           0 :       parens.consume_open (parser);
   37581                 :           0 :       bool syntax_error = false;
   37582                 :             : 
   37583                 :             :       /* Allow empty @property attribute lists, but with a warning.  */
   37584                 :           0 :       location_t attr_end = cp_lexer_peek_token (parser->lexer)->location;
   37585                 :           0 :       location_t attr_comb;
   37586                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
   37587                 :             :         {
   37588                 :           0 :           attr_comb = make_location (attr_end, attr_start, attr_end);
   37589                 :           0 :           warning_at (attr_comb, OPT_Wattributes,
   37590                 :             :                       "empty property attribute list");
   37591                 :             :         }
   37592                 :             :       else
   37593                 :           0 :         while (true)
   37594                 :             :           {
   37595                 :           0 :             cp_token *token = cp_lexer_peek_token (parser->lexer);
   37596                 :           0 :             attr_start = token->location;
   37597                 :           0 :             attr_end = get_finish (token->location);
   37598                 :           0 :             attr_comb = make_location (attr_start, attr_start, attr_end);
   37599                 :             : 
   37600                 :           0 :             if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
   37601                 :             :               {
   37602                 :           0 :                 warning_at (attr_comb, OPT_Wattributes,
   37603                 :             :                             "missing property attribute");
   37604                 :           0 :                 if (token->type == CPP_CLOSE_PAREN)
   37605                 :             :                   break;
   37606                 :           0 :                 cp_lexer_consume_token (parser->lexer);
   37607                 :           0 :                 continue;
   37608                 :             :               }
   37609                 :             : 
   37610                 :           0 :             tree attr_name = NULL_TREE;
   37611                 :           0 :             if (identifier_p (token->u.value))
   37612                 :           0 :               attr_name = token->u.value;
   37613                 :             : 
   37614                 :           0 :             enum rid keyword;
   37615                 :           0 :             if (token->type == CPP_NAME)
   37616                 :           0 :               keyword = C_RID_CODE (token->u.value);
   37617                 :           0 :             else if (token->type == CPP_KEYWORD
   37618                 :           0 :                      && token->keyword == RID_CLASS)
   37619                 :             :               /* Account for accepting the 'class' keyword in this context.  */
   37620                 :             :               keyword = RID_CLASS;
   37621                 :             :             else
   37622                 :           0 :               keyword = RID_MAX; /* By definition, an unknown property.  */
   37623                 :           0 :             cp_lexer_consume_token (parser->lexer);
   37624                 :             : 
   37625                 :           0 :             enum objc_property_attribute_kind prop_kind
   37626                 :           0 :               = objc_prop_attr_kind_for_rid (keyword);
   37627                 :           0 :             property_attribute_info *prop
   37628                 :           0 :               = new property_attribute_info (attr_name, attr_comb, prop_kind);
   37629                 :           0 :             prop_attr_list.safe_push (prop);
   37630                 :             : 
   37631                 :           0 :             tree meth_name;
   37632                 :           0 :             switch (prop->prop_kind)
   37633                 :             :               {
   37634                 :             :               default: break;
   37635                 :           0 :               case OBJC_PROPERTY_ATTR_UNKNOWN:
   37636                 :           0 :                 if (attr_name)
   37637                 :           0 :                   error_at (attr_start, "unknown property attribute %qE",
   37638                 :             :                             attr_name);
   37639                 :             :                 else
   37640                 :           0 :                   error_at (attr_start, "unknown property attribute");
   37641                 :           0 :                 prop->parse_error = syntax_error = true;
   37642                 :           0 :                 break;
   37643                 :             : 
   37644                 :           0 :               case OBJC_PROPERTY_ATTR_GETTER:
   37645                 :           0 :               case OBJC_PROPERTY_ATTR_SETTER:
   37646                 :           0 :                 if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
   37647                 :             :                   {
   37648                 :           0 :                     attr_comb = make_location (attr_end, attr_start, attr_end);
   37649                 :           0 :                     error_at (attr_comb, "expected %<=%> after Objective-C %qE",
   37650                 :             :                               attr_name);
   37651                 :           0 :                     prop->parse_error = syntax_error = true;
   37652                 :           0 :                     break;
   37653                 :             :                   }
   37654                 :             : 
   37655                 :           0 :                 token = cp_lexer_peek_token (parser->lexer);
   37656                 :           0 :                 attr_end = token->location;
   37657                 :           0 :                 cp_lexer_consume_token (parser->lexer); /* eat the = */
   37658                 :             : 
   37659                 :           0 :                 if (!cp_parser_objc_selector_p
   37660                 :           0 :                      (cp_lexer_peek_token (parser->lexer)->type))
   37661                 :             :                   {
   37662                 :           0 :                     attr_comb = make_location (attr_end, attr_start, attr_end);
   37663                 :           0 :                     error_at (attr_comb, "expected %qE selector name",
   37664                 :             :                               attr_name);
   37665                 :           0 :                     prop->parse_error = syntax_error = true;
   37666                 :           0 :                     break;
   37667                 :             :                   }
   37668                 :             : 
   37669                 :             :                 /* Get the end of the method name, and consume the name.  */
   37670                 :           0 :                 token = cp_lexer_peek_token (parser->lexer);
   37671                 :           0 :                 attr_end = get_finish (token->location);
   37672                 :             :                 /* Because method names may contain C++ keywords, we have a
   37673                 :             :                    routine to fetch them (this also consumes the token).  */
   37674                 :           0 :                 meth_name = cp_parser_objc_selector (parser);
   37675                 :             : 
   37676                 :           0 :                 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
   37677                 :             :                   {
   37678                 :           0 :                     if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
   37679                 :             :                       {
   37680                 :           0 :                         attr_comb = make_location (attr_end, attr_start,
   37681                 :             :                                                    attr_end);
   37682                 :           0 :                         error_at (attr_comb, "setter method names must"
   37683                 :             :                                   " terminate with %<:%>");
   37684                 :           0 :                         prop->parse_error = syntax_error = true;
   37685                 :             :                       }
   37686                 :             :                     else
   37687                 :             :                       {
   37688                 :           0 :                         attr_end = get_finish (cp_lexer_peek_token
   37689                 :           0 :                                                (parser->lexer)->location);
   37690                 :           0 :                         cp_lexer_consume_token (parser->lexer);
   37691                 :             :                       }
   37692                 :           0 :                     attr_comb = make_location (attr_start, attr_start,
   37693                 :             :                                                attr_end);
   37694                 :             :                   }
   37695                 :             :                 else
   37696                 :           0 :                   attr_comb = make_location (attr_start, attr_start,
   37697                 :             :                                              attr_end);
   37698                 :           0 :                 prop->ident = meth_name;
   37699                 :             :                 /* Updated location including all that was successfully
   37700                 :             :                    parsed.  */
   37701                 :           0 :                 prop->prop_loc = attr_comb;
   37702                 :           0 :                 break;
   37703                 :             :               }
   37704                 :             : 
   37705                 :             :             /* If we see a comma here, then keep going - even if we already
   37706                 :             :                saw a syntax error.  For simple mistakes e.g. (asign, getter=x)
   37707                 :             :                this makes a more useful output and avoid spurious warnings
   37708                 :             :                about missing attributes that are, in fact, specified after the
   37709                 :             :                one with the syntax error.  */
   37710                 :           0 :             if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   37711                 :           0 :               cp_lexer_consume_token (parser->lexer);
   37712                 :             :             else
   37713                 :             :               break;
   37714                 :             :           }
   37715                 :             : 
   37716                 :           0 :       if (syntax_error || !parens.require_close (parser))
   37717                 :           0 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   37718                 :             :                                                /*or_comma=*/false,
   37719                 :             :                                                /*consume_paren=*/true);
   37720                 :             :     }
   37721                 :             : 
   37722                 :             :   /* 'properties' is the list of properties that we read.  Usually a
   37723                 :             :      single one, but maybe more (eg, in "@property int a, b, c;" there
   37724                 :             :      are three).
   37725                 :             :      TODO: Update this parsing so that it accepts (erroneous) bitfields so
   37726                 :             :      that we can issue a meaningful and consistent (between C/C++) error
   37727                 :             :      message from objc_add_property_declaration ().  */
   37728                 :           0 :   tree properties = cp_parser_objc_struct_declaration (parser);
   37729                 :             : 
   37730                 :           0 :   if (properties == error_mark_node)
   37731                 :           0 :     cp_parser_skip_to_end_of_statement (parser);
   37732                 :           0 :   else if (properties == NULL_TREE)
   37733                 :           0 :     cp_parser_error (parser, "expected identifier");
   37734                 :             :   else
   37735                 :             :     {
   37736                 :             :       /* Comma-separated properties are chained together in reverse order;
   37737                 :             :          add them one by one.  */
   37738                 :           0 :       properties = nreverse (properties);
   37739                 :           0 :       for (; properties; properties = TREE_CHAIN (properties))
   37740                 :           0 :         objc_add_property_declaration (loc, copy_node (properties),
   37741                 :             :                                        prop_attr_list);
   37742                 :             :     }
   37743                 :             : 
   37744                 :           0 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   37745                 :           0 : }
   37746                 :             : 
   37747                 :             : /* Parse an Objective-C++ @synthesize declaration.  The syntax is:
   37748                 :             : 
   37749                 :             :    objc-synthesize-declaration:
   37750                 :             :      @synthesize objc-synthesize-identifier-list ;
   37751                 :             : 
   37752                 :             :    objc-synthesize-identifier-list:
   37753                 :             :      objc-synthesize-identifier
   37754                 :             :      objc-synthesize-identifier-list, objc-synthesize-identifier
   37755                 :             : 
   37756                 :             :    objc-synthesize-identifier
   37757                 :             :      identifier
   37758                 :             :      identifier = identifier
   37759                 :             : 
   37760                 :             :   For example:
   37761                 :             :     @synthesize MyProperty;
   37762                 :             :     @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
   37763                 :             : 
   37764                 :             :   PS: This function is identical to c_parser_objc_at_synthesize_declaration
   37765                 :             :   for C.  Keep them in sync.
   37766                 :             : */
   37767                 :             : static void
   37768                 :           0 : cp_parser_objc_at_synthesize_declaration (cp_parser *parser)
   37769                 :             : {
   37770                 :           0 :   tree list = NULL_TREE;
   37771                 :           0 :   location_t loc;
   37772                 :           0 :   loc = cp_lexer_peek_token (parser->lexer)->location;
   37773                 :             : 
   37774                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@synthesize'.  */
   37775                 :           0 :   while (true)
   37776                 :             :     {
   37777                 :           0 :       tree property, ivar;
   37778                 :           0 :       property = cp_parser_identifier (parser);
   37779                 :           0 :       if (property == error_mark_node)
   37780                 :             :         {
   37781                 :           0 :           cp_parser_consume_semicolon_at_end_of_statement (parser);
   37782                 :           0 :           return;
   37783                 :             :         }
   37784                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   37785                 :             :         {
   37786                 :           0 :           cp_lexer_consume_token (parser->lexer);
   37787                 :           0 :           ivar = cp_parser_identifier (parser);
   37788                 :           0 :           if (ivar == error_mark_node)
   37789                 :             :             {
   37790                 :           0 :               cp_parser_consume_semicolon_at_end_of_statement (parser);
   37791                 :           0 :               return;
   37792                 :             :             }
   37793                 :             :         }
   37794                 :             :       else
   37795                 :             :         ivar = NULL_TREE;
   37796                 :           0 :       list = chainon (list, build_tree_list (ivar, property));
   37797                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   37798                 :           0 :         cp_lexer_consume_token (parser->lexer);
   37799                 :             :       else
   37800                 :             :         break;
   37801                 :           0 :     }
   37802                 :           0 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   37803                 :           0 :   objc_add_synthesize_declaration (loc, list);
   37804                 :             : }
   37805                 :             : 
   37806                 :             : /* Parse an Objective-C++ @dynamic declaration.  The syntax is:
   37807                 :             : 
   37808                 :             :    objc-dynamic-declaration:
   37809                 :             :      @dynamic identifier-list ;
   37810                 :             : 
   37811                 :             :    For example:
   37812                 :             :      @dynamic MyProperty;
   37813                 :             :      @dynamic MyProperty, AnotherProperty;
   37814                 :             : 
   37815                 :             :   PS: This function is identical to c_parser_objc_at_dynamic_declaration
   37816                 :             :   for C.  Keep them in sync.
   37817                 :             : */
   37818                 :             : static void
   37819                 :           0 : cp_parser_objc_at_dynamic_declaration (cp_parser *parser)
   37820                 :             : {
   37821                 :           0 :   tree list = NULL_TREE;
   37822                 :           0 :   location_t loc;
   37823                 :           0 :   loc = cp_lexer_peek_token (parser->lexer)->location;
   37824                 :             : 
   37825                 :           0 :   cp_lexer_consume_token (parser->lexer);  /* Eat '@dynamic'.  */
   37826                 :           0 :   while (true)
   37827                 :             :     {
   37828                 :           0 :       tree property;
   37829                 :           0 :       property = cp_parser_identifier (parser);
   37830                 :           0 :       if (property == error_mark_node)
   37831                 :             :         {
   37832                 :           0 :           cp_parser_consume_semicolon_at_end_of_statement (parser);
   37833                 :           0 :           return;
   37834                 :             :         }
   37835                 :           0 :       list = chainon (list, build_tree_list (NULL, property));
   37836                 :           0 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   37837                 :           0 :         cp_lexer_consume_token (parser->lexer);
   37838                 :             :       else
   37839                 :             :         break;
   37840                 :           0 :     }
   37841                 :           0 :   cp_parser_consume_semicolon_at_end_of_statement (parser);
   37842                 :           0 :   objc_add_dynamic_declaration (loc, list);
   37843                 :             : }
   37844                 :             : 
   37845                 :             : 
   37846                 :             : /* OpenMP 2.5 / 3.0 / 3.1 / 4.0 / 4.5 / 5.0 parsing routines.  */
   37847                 :             : 
   37848                 :             : /* Returns name of the next clause.
   37849                 :             :    If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
   37850                 :             :    the token is not consumed.  Otherwise appropriate pragma_omp_clause is
   37851                 :             :    returned and the token is consumed.  */
   37852                 :             : 
   37853                 :             : static pragma_omp_clause
   37854                 :       74057 : cp_parser_omp_clause_name (cp_parser *parser)
   37855                 :             : {
   37856                 :       74057 :   pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
   37857                 :             : 
   37858                 :       74057 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
   37859                 :             :     result = PRAGMA_OACC_CLAUSE_AUTO;
   37860                 :             :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
   37861                 :             :     result = PRAGMA_OMP_CLAUSE_IF;
   37862                 :             :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT))
   37863                 :             :     result = PRAGMA_OMP_CLAUSE_DEFAULT;
   37864                 :             :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DELETE))
   37865                 :             :     result = PRAGMA_OACC_CLAUSE_DELETE;
   37866                 :             :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_PRIVATE))
   37867                 :             :     result = PRAGMA_OMP_CLAUSE_PRIVATE;
   37868                 :             :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
   37869                 :             :     result = PRAGMA_OMP_CLAUSE_FOR;
   37870                 :       66265 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   37871                 :             :     {
   37872                 :       66179 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   37873                 :       66179 :       const char *p = IDENTIFIER_POINTER (id);
   37874                 :             : 
   37875                 :       66179 :       switch (p[0])
   37876                 :             :         {
   37877                 :        3763 :         case 'a':
   37878                 :        3763 :           if (!strcmp ("affinity", p))
   37879                 :             :             result = PRAGMA_OMP_CLAUSE_AFFINITY;
   37880                 :        3147 :           else if (!strcmp ("aligned", p))
   37881                 :             :             result = PRAGMA_OMP_CLAUSE_ALIGNED;
   37882                 :        2288 :           else if (!strcmp ("allocate", p))
   37883                 :             :             result = PRAGMA_OMP_CLAUSE_ALLOCATE;
   37884                 :         561 :           else if (!strcmp ("async", p))
   37885                 :             :             result = PRAGMA_OACC_CLAUSE_ASYNC;
   37886                 :         138 :           else if (!strcmp ("attach", p))
   37887                 :       74057 :             result = PRAGMA_OACC_CLAUSE_ATTACH;
   37888                 :             :           break;
   37889                 :         449 :         case 'b':
   37890                 :         449 :           if (!strcmp ("bind", p))
   37891                 :       74057 :             result = PRAGMA_OMP_CLAUSE_BIND;
   37892                 :             :           break;
   37893                 :        8289 :         case 'c':
   37894                 :        8289 :           if (!strcmp ("collapse", p))
   37895                 :             :             result = PRAGMA_OMP_CLAUSE_COLLAPSE;
   37896                 :        3829 :           else if (!strcmp ("copy", p))
   37897                 :             :             result = PRAGMA_OACC_CLAUSE_COPY;
   37898                 :        2507 :           else if (!strcmp ("copyin", p))
   37899                 :             :             result = PRAGMA_OMP_CLAUSE_COPYIN;
   37900                 :        1317 :           else if (!strcmp ("copyout", p))
   37901                 :             :             result = PRAGMA_OACC_CLAUSE_COPYOUT;
   37902                 :         338 :           else if (!strcmp ("copyprivate", p))
   37903                 :             :             result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
   37904                 :         254 :           else if (!strcmp ("create", p))
   37905                 :       74057 :             result = PRAGMA_OACC_CLAUSE_CREATE;
   37906                 :             :           break;
   37907                 :        6272 :         case 'd':
   37908                 :        6272 :           if (!strcmp ("defaultmap", p))
   37909                 :             :             result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
   37910                 :        5456 :           else if (!strcmp ("depend", p))
   37911                 :             :             result = PRAGMA_OMP_CLAUSE_DEPEND;
   37912                 :        3443 :           else if (!strcmp ("detach", p))
   37913                 :             :             result = PRAGMA_OACC_CLAUSE_DETACH;
   37914                 :        3250 :           else if (!strcmp ("device", p))
   37915                 :             :             result = PRAGMA_OMP_CLAUSE_DEVICE;
   37916                 :        2493 :           else if (!strcmp ("deviceptr", p))
   37917                 :             :             result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
   37918                 :        2381 :           else if (!strcmp ("device_resident", p))
   37919                 :             :             result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
   37920                 :        2324 :           else if (!strcmp ("device_type", p))
   37921                 :             :             result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
   37922                 :        2175 :           else if (!strcmp ("dist_schedule", p))
   37923                 :             :             result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
   37924                 :         248 :           else if (!strcmp ("doacross", p))
   37925                 :       74057 :             result = PRAGMA_OMP_CLAUSE_DOACROSS;
   37926                 :             :           break;
   37927                 :         135 :         case 'e':
   37928                 :         135 :           if (!strcmp ("enter", p))
   37929                 :       74057 :             result = PRAGMA_OMP_CLAUSE_ENTER;
   37930                 :             :           break;
   37931                 :        5555 :         case 'f':
   37932                 :        5555 :           if (!strcmp ("filter", p))
   37933                 :             :             result = PRAGMA_OMP_CLAUSE_FILTER;
   37934                 :        5341 :           else if (!strcmp ("final", p))
   37935                 :             :             result = PRAGMA_OMP_CLAUSE_FINAL;
   37936                 :        5011 :           else if (!strcmp ("finalize", p))
   37937                 :             :             result = PRAGMA_OACC_CLAUSE_FINALIZE;
   37938                 :        4965 :           else if (!strcmp ("firstprivate", p))
   37939                 :             :             result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
   37940                 :        2485 :           else if (!strcmp ("from", p))
   37941                 :       74057 :             result = PRAGMA_OMP_CLAUSE_FROM;
   37942                 :             :           break;
   37943                 :        1668 :         case 'g':
   37944                 :        1668 :           if (!strcmp ("gang", p))
   37945                 :             :             result = PRAGMA_OACC_CLAUSE_GANG;
   37946                 :         192 :           else if (!strcmp ("grainsize", p))
   37947                 :       74057 :             result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
   37948                 :             :           break;
   37949                 :         487 :         case 'h':
   37950                 :         487 :           if (!strcmp ("has_device_addr", p))
   37951                 :             :             result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
   37952                 :         186 :           else if (!strcmp ("hint", p))
   37953                 :             :             result = PRAGMA_OMP_CLAUSE_HINT;
   37954                 :         111 :           else if (!strcmp ("host", p))
   37955                 :       74057 :             result = PRAGMA_OACC_CLAUSE_HOST;
   37956                 :             :           break;
   37957                 :        1555 :         case 'i':
   37958                 :        1555 :           if (!strcmp ("if_present", p))
   37959                 :             :             result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
   37960                 :        1489 :           else if (!strcmp ("in_reduction", p))
   37961                 :             :             result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
   37962                 :         639 :           else if (!strcmp ("inbranch", p))
   37963                 :             :             result = PRAGMA_OMP_CLAUSE_INBRANCH;
   37964                 :         490 :           else if (!strcmp ("independent", p))
   37965                 :             :             result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
   37966                 :         393 :           else if (!strcmp ("indirect", p))
   37967                 :             :             result = PRAGMA_OMP_CLAUSE_INDIRECT;
   37968                 :         279 :           else if (!strcmp ("is_device_ptr", p))
   37969                 :       74057 :             result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
   37970                 :             :           break;
   37971                 :        3742 :         case 'l':
   37972                 :        3742 :           if (!strcmp ("lastprivate", p))
   37973                 :             :             result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
   37974                 :        1969 :           else if (!strcmp ("linear", p))
   37975                 :             :             result = PRAGMA_OMP_CLAUSE_LINEAR;
   37976                 :         141 :           else if (!strcmp ("link", p))
   37977                 :       74057 :             result = PRAGMA_OMP_CLAUSE_LINK;
   37978                 :             :           break;
   37979                 :        4749 :         case 'm':
   37980                 :        4749 :           if (!strcmp ("map", p))
   37981                 :             :             result = PRAGMA_OMP_CLAUSE_MAP;
   37982                 :         264 :           else if (!strcmp ("mergeable", p))
   37983                 :       74057 :             result = PRAGMA_OMP_CLAUSE_MERGEABLE;
   37984                 :             :           break;
   37985                 :        4412 :         case 'n':
   37986                 :        4412 :           if (!strcmp ("no_create", p))
   37987                 :             :             result = PRAGMA_OACC_CLAUSE_NO_CREATE;
   37988                 :        4396 :           else if (!strcmp ("nogroup", p))
   37989                 :             :             result = PRAGMA_OMP_CLAUSE_NOGROUP;
   37990                 :        4349 :           else if (!strcmp ("nohost", p))
   37991                 :             :             result = PRAGMA_OACC_CLAUSE_NOHOST;
   37992                 :        4251 :           else if (!strcmp ("nontemporal", p))
   37993                 :             :             result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
   37994                 :        3833 :           else if (!strcmp ("notinbranch", p))
   37995                 :             :             result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
   37996                 :        3267 :           else if (!strcmp ("nowait", p))
   37997                 :             :             result = PRAGMA_OMP_CLAUSE_NOWAIT;
   37998                 :        2631 :           else if (!strcmp ("num_gangs", p))
   37999                 :             :             result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
   38000                 :        2137 :           else if (!strcmp ("num_tasks", p))
   38001                 :             :             result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
   38002                 :        1981 :           else if (!strcmp ("num_teams", p))
   38003                 :             :             result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
   38004                 :        1230 :           else if (!strcmp ("num_threads", p))
   38005                 :             :             result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
   38006                 :         374 :           else if (!strcmp ("num_workers", p))
   38007                 :       74057 :             result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
   38008                 :             :           break;
   38009                 :        2127 :         case 'o':
   38010                 :        2127 :           if (!strcmp ("ordered", p))
   38011                 :             :             result = PRAGMA_OMP_CLAUSE_ORDERED;
   38012                 :        1383 :           else if (!strcmp ("order", p))
   38013                 :       74057 :             result = PRAGMA_OMP_CLAUSE_ORDER;
   38014                 :             :           break;
   38015                 :        1873 :         case 'p':
   38016                 :        1873 :           if (!strcmp ("parallel", p))
   38017                 :             :             result = PRAGMA_OMP_CLAUSE_PARALLEL;
   38018                 :        1474 :           else if (!strcmp ("present", p))
   38019                 :             :             result = PRAGMA_OACC_CLAUSE_PRESENT;
   38020                 :        1225 :           else if (!strcmp ("present_or_copy", p)
   38021                 :        1194 :                    || !strcmp ("pcopy", p))
   38022                 :             :             result = PRAGMA_OACC_CLAUSE_COPY;
   38023                 :        1165 :           else if (!strcmp ("present_or_copyin", p)
   38024                 :        1122 :                    || !strcmp ("pcopyin", p))
   38025                 :             :             result = PRAGMA_OACC_CLAUSE_COPYIN;
   38026                 :        1096 :           else if (!strcmp ("present_or_copyout", p)
   38027                 :        1022 :                    || !strcmp ("pcopyout", p))
   38028                 :             :             result = PRAGMA_OACC_CLAUSE_COPYOUT;
   38029                 :         989 :           else if (!strcmp ("present_or_create", p)
   38030                 :         951 :                    || !strcmp ("pcreate", p))
   38031                 :             :             result = PRAGMA_OACC_CLAUSE_CREATE;
   38032                 :         941 :           else if (!strcmp ("priority", p))
   38033                 :             :             result = PRAGMA_OMP_CLAUSE_PRIORITY;
   38034                 :         619 :           else if (!strcmp ("proc_bind", p))
   38035                 :       74057 :             result = PRAGMA_OMP_CLAUSE_PROC_BIND;
   38036                 :             :           break;
   38037                 :        5756 :         case 'r':
   38038                 :        5756 :           if (!strcmp ("reduction", p))
   38039                 :       74057 :             result = PRAGMA_OMP_CLAUSE_REDUCTION;
   38040                 :             :           break;
   38041                 :        8628 :         case 's':
   38042                 :        8628 :           if (!strcmp ("safelen", p))
   38043                 :             :             result = PRAGMA_OMP_CLAUSE_SAFELEN;
   38044                 :        8067 :           else if (!strcmp ("schedule", p))
   38045                 :             :             result = PRAGMA_OMP_CLAUSE_SCHEDULE;
   38046                 :        4061 :           else if (!strcmp ("sections", p))
   38047                 :             :             result = PRAGMA_OMP_CLAUSE_SECTIONS;
   38048                 :        3761 :           else if (!strcmp ("self", p))
   38049                 :             :             result = PRAGMA_OACC_CLAUSE_SELF;
   38050                 :        3594 :           else if (!strcmp ("seq", p))
   38051                 :             :             result = PRAGMA_OACC_CLAUSE_SEQ;
   38052                 :        2664 :           else if (!strcmp ("shared", p))
   38053                 :             :             result = PRAGMA_OMP_CLAUSE_SHARED;
   38054                 :        1123 :           else if (!strcmp ("simd", p))
   38055                 :             :             result = PRAGMA_OMP_CLAUSE_SIMD;
   38056                 :         909 :           else if (!strcmp ("simdlen", p))
   38057                 :       74057 :             result = PRAGMA_OMP_CLAUSE_SIMDLEN;
   38058                 :             :           break;
   38059                 :        2567 :         case 't':
   38060                 :        2567 :           if (!strcmp ("task_reduction", p))
   38061                 :             :             result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
   38062                 :        2314 :           else if (!strcmp ("taskgroup", p))
   38063                 :             :             result = PRAGMA_OMP_CLAUSE_TASKGROUP;
   38064                 :        1895 :           else if (!strcmp ("thread_limit", p))
   38065                 :             :             result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
   38066                 :        1387 :           else if (!strcmp ("threads", p))
   38067                 :             :             result = PRAGMA_OMP_CLAUSE_THREADS;
   38068                 :        1231 :           else if (!strcmp ("tile", p))
   38069                 :             :             result = PRAGMA_OACC_CLAUSE_TILE;
   38070                 :         810 :           else if (!strcmp ("to", p))
   38071                 :       74057 :             result = PRAGMA_OMP_CLAUSE_TO;
   38072                 :             :           break;
   38073                 :         900 :         case 'u':
   38074                 :         900 :           if (!strcmp ("uniform", p))
   38075                 :             :             result = PRAGMA_OMP_CLAUSE_UNIFORM;
   38076                 :         460 :           else if (!strcmp ("untied", p))
   38077                 :             :             result = PRAGMA_OMP_CLAUSE_UNTIED;
   38078                 :         184 :           else if (!strcmp ("use_device", p))
   38079                 :             :             result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
   38080                 :         112 :           else if (!strcmp ("use_device_addr", p))
   38081                 :             :             result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
   38082                 :          30 :           else if (!strcmp ("use_device_ptr", p))
   38083                 :       74057 :             result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
   38084                 :             :           break;
   38085                 :        1782 :         case 'v':
   38086                 :        1782 :           if (!strcmp ("vector", p))
   38087                 :             :             result = PRAGMA_OACC_CLAUSE_VECTOR;
   38088                 :         380 :           else if (!strcmp ("vector_length", p))
   38089                 :       74057 :             result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
   38090                 :             :           break;
   38091                 :        1466 :         case 'w':
   38092                 :        1466 :           if (!strcmp ("wait", p))
   38093                 :             :             result = PRAGMA_OACC_CLAUSE_WAIT;
   38094                 :        1246 :           else if (!strcmp ("worker", p))
   38095                 :       74057 :             result = PRAGMA_OACC_CLAUSE_WORKER;
   38096                 :             :           break;
   38097                 :             :         }
   38098                 :             :     }
   38099                 :             : 
   38100                 :       74057 :   if (result != PRAGMA_OMP_CLAUSE_NONE)
   38101                 :       73943 :     cp_lexer_consume_token (parser->lexer);
   38102                 :             : 
   38103                 :       74057 :   return result;
   38104                 :             : }
   38105                 :             : 
   38106                 :             : /* Validate that a clause of the given type does not already exist.  */
   38107                 :             : 
   38108                 :             : static void
   38109                 :       34121 : check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
   38110                 :             :                            const char *name, location_t location)
   38111                 :             : {
   38112                 :       34121 :   if (omp_find_clause (clauses, code))
   38113                 :        1352 :     error_at (location, "too many %qs clauses", name);
   38114                 :       34121 : }
   38115                 :             : 
   38116                 :             : /* OpenMP 2.5:
   38117                 :             :    variable-list:
   38118                 :             :      identifier
   38119                 :             :      variable-list , identifier
   38120                 :             : 
   38121                 :             :    In addition, we match a closing parenthesis (or, if COLON is non-NULL,
   38122                 :             :    colon).  An opening parenthesis will have been consumed by the caller.
   38123                 :             : 
   38124                 :             :    If KIND is nonzero, create the appropriate node and install the decl
   38125                 :             :    in OMP_CLAUSE_DECL and add the node to the head of the list.
   38126                 :             : 
   38127                 :             :    If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
   38128                 :             :    return the list created.
   38129                 :             : 
   38130                 :             :    COLON can be NULL if only closing parenthesis should end the list,
   38131                 :             :    or pointer to bool which will receive false if the list is terminated
   38132                 :             :    by closing parenthesis or true if the list is terminated by colon.
   38133                 :             : 
   38134                 :             :    The optional ALLOW_DEREF argument is true if list items can use the deref
   38135                 :             :    (->) operator.  */
   38136                 :             : 
   38137                 :             : struct omp_dim
   38138                 :             : {
   38139                 :             :   tree low_bound, length;
   38140                 :             :   location_t loc;
   38141                 :             :   bool no_colon;
   38142                 :       10729 :   omp_dim (tree lb, tree len, location_t lo, bool nc)
   38143                 :       10729 :     : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
   38144                 :             : };
   38145                 :             : 
   38146                 :             : static tree
   38147                 :       37895 : cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
   38148                 :             :                                 tree list, bool *colon,
   38149                 :             :                                 bool map_lvalue = false)
   38150                 :             : {
   38151                 :       37895 :   auto_vec<omp_dim> dims;
   38152                 :       37895 :   bool array_section_p;
   38153                 :       37895 :   cp_token *token;
   38154                 :       37895 :   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   38155                 :       37895 :   if (colon)
   38156                 :             :     {
   38157                 :        4147 :       parser->colon_corrects_to_scope_p = false;
   38158                 :        4147 :       *colon = false;
   38159                 :             :     }
   38160                 :       48891 :   while (1)
   38161                 :             :     {
   38162                 :       43393 :       tree name, decl;
   38163                 :             : 
   38164                 :       43393 :       if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   38165                 :        2478 :         cp_parser_parse_tentatively (parser);
   38166                 :             :       /* This condition doesn't include OMP_CLAUSE_DEPEND or
   38167                 :             :          OMP_CLAUSE_AFFINITY since lvalue ("locator list") parsing for those is
   38168                 :             :          handled further down the function.  */
   38169                 :       40915 :       else if (map_lvalue
   38170                 :        8583 :                && (kind == OMP_CLAUSE_MAP
   38171                 :             :                    || kind == OMP_CLAUSE_TO
   38172                 :        8583 :                    || kind == OMP_CLAUSE_FROM))
   38173                 :             :         {
   38174                 :        8583 :           auto s = make_temp_override (parser->omp_array_section_p, true);
   38175                 :        8583 :           token = cp_lexer_peek_token (parser->lexer);
   38176                 :        8583 :           location_t loc = token->location;
   38177                 :        8583 :           decl = cp_parser_assignment_expression (parser);
   38178                 :             : 
   38179                 :             :           /* This code rewrites a parsed expression containing various tree
   38180                 :             :              codes used to represent array accesses into a more uniform nest of
   38181                 :             :              OMP_ARRAY_SECTION nodes before it is processed by
   38182                 :             :              semantics.cc:handle_omp_array_sections_1.  It might be more
   38183                 :             :              efficient to move this logic to that function instead, analysing
   38184                 :             :              the parsed expression directly rather than this preprocessed
   38185                 :             :              form.  */
   38186                 :        8583 :           dims.truncate (0);
   38187                 :        8583 :           if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
   38188                 :             :             {
   38189                 :        4082 :               while (TREE_CODE (decl) == OMP_ARRAY_SECTION)
   38190                 :             :                 {
   38191                 :        2259 :                   tree low_bound = TREE_OPERAND (decl, 1);
   38192                 :        2259 :                   tree length = TREE_OPERAND (decl, 2);
   38193                 :        2259 :                   dims.safe_push (omp_dim (low_bound, length, loc, false));
   38194                 :        2259 :                   decl = TREE_OPERAND (decl, 0);
   38195                 :             :                 }
   38196                 :             : 
   38197                 :        1863 :               while (TREE_CODE (decl) == ARRAY_REF
   38198                 :             :                      || TREE_CODE (decl) == INDIRECT_REF
   38199                 :        1863 :                      || TREE_CODE (decl) == COMPOUND_EXPR)
   38200                 :             :                 {
   38201                 :         248 :                   if (REFERENCE_REF_P (decl))
   38202                 :             :                     break;
   38203                 :             : 
   38204                 :          40 :                   if (TREE_CODE (decl) == COMPOUND_EXPR)
   38205                 :             :                     {
   38206                 :           4 :                       decl = TREE_OPERAND (decl, 1);
   38207                 :           4 :                       STRIP_NOPS (decl);
   38208                 :             :                     }
   38209                 :          36 :                   else if (TREE_CODE (decl) == INDIRECT_REF)
   38210                 :             :                     {
   38211                 :          24 :                       dims.safe_push (omp_dim (integer_zero_node,
   38212                 :             :                                                integer_one_node, loc, true));
   38213                 :          24 :                       decl = TREE_OPERAND (decl, 0);
   38214                 :             :                     }
   38215                 :             :                   else  /* ARRAY_REF. */
   38216                 :             :                     {
   38217                 :          12 :                       tree index = TREE_OPERAND (decl, 1);
   38218                 :          12 :                       dims.safe_push (omp_dim (index, integer_one_node, loc,
   38219                 :             :                                                true));
   38220                 :          12 :                       decl = TREE_OPERAND (decl, 0);
   38221                 :             :                     }
   38222                 :             :                 }
   38223                 :             : 
   38224                 :             :               /* Bare references have their own special handling, so remove
   38225                 :             :                  the explicit dereference added by convert_from_reference.  */
   38226                 :        1823 :               if (REFERENCE_REF_P (decl))
   38227                 :         208 :                 decl = TREE_OPERAND (decl, 0);
   38228                 :             : 
   38229                 :        5941 :               for (int i = dims.length () - 1; i >= 0; i--)
   38230                 :        2295 :                 decl = grok_omp_array_section (loc, decl, dims[i].low_bound,
   38231                 :        2295 :                                                dims[i].length);
   38232                 :             :             }
   38233                 :        6760 :           else if (TREE_CODE (decl) == INDIRECT_REF)
   38234                 :             :             {
   38235                 :         497 :               bool ref_p = REFERENCE_REF_P (decl);
   38236                 :             : 
   38237                 :             :               /* If we have "*foo" and
   38238                 :             :                  - it's an indirection of a reference, "unconvert" it, i.e.
   38239                 :             :                    strip the indirection (to just "foo").
   38240                 :             :                  - it's an indirection of a pointer, turn it into
   38241                 :             :                    "foo[0:1]".  */
   38242                 :         497 :               decl = TREE_OPERAND (decl, 0);
   38243                 :         497 :               STRIP_NOPS (decl);
   38244                 :             : 
   38245                 :         497 :               if (!ref_p)
   38246                 :         173 :                 decl = grok_omp_array_section (loc, decl, integer_zero_node,
   38247                 :             :                                                integer_one_node);
   38248                 :             :             }
   38249                 :        6263 :           else if (TREE_CODE (decl) == ARRAY_REF)
   38250                 :             :             {
   38251                 :          91 :               tree idx = TREE_OPERAND (decl, 1);
   38252                 :             : 
   38253                 :          91 :               decl = TREE_OPERAND (decl, 0);
   38254                 :          91 :               STRIP_NOPS (decl);
   38255                 :             : 
   38256                 :          91 :               decl = grok_omp_array_section (loc, decl, idx, integer_one_node);
   38257                 :             :             }
   38258                 :        6172 :           else if (TREE_CODE (decl) == NON_LVALUE_EXPR
   38259                 :        6172 :                    || CONVERT_EXPR_P (decl))
   38260                 :          24 :             decl = TREE_OPERAND (decl, 0);
   38261                 :             : 
   38262                 :        8583 :           goto build_clause;
   38263                 :        8583 :         }
   38264                 :       34810 :       token = cp_lexer_peek_token (parser->lexer);
   38265                 :       34810 :       if (kind != 0
   38266                 :       34810 :           && cp_parser_is_keyword (token, RID_THIS))
   38267                 :             :         {
   38268                 :         280 :           decl = finish_this_expr ();
   38269                 :         280 :           if (TREE_CODE (decl) == NON_LVALUE_EXPR
   38270                 :         280 :               || CONVERT_EXPR_P (decl))
   38271                 :         272 :             decl = TREE_OPERAND (decl, 0);
   38272                 :         280 :           cp_lexer_consume_token (parser->lexer);
   38273                 :             :         }
   38274                 :       34530 :       else if (cp_parser_is_keyword (token, RID_FUNCTION_NAME)
   38275                 :       34523 :                || cp_parser_is_keyword (token, RID_PRETTY_FUNCTION_NAME)
   38276                 :       69046 :                || cp_parser_is_keyword (token, RID_C99_FUNCTION_NAME))
   38277                 :             :         {
   38278                 :          23 :           cp_id_kind idk;
   38279                 :          23 :           decl = cp_parser_primary_expression (parser, false, false, false,
   38280                 :             :                                                &idk);
   38281                 :             :         }
   38282                 :       34507 :       else if (kind == OMP_CLAUSE_DEPEND
   38283                 :        1751 :                && cp_parser_is_keyword (token, RID_OMP_ALL_MEMORY)
   38284                 :       34553 :                && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA)
   38285                 :          37 :                    || cp_lexer_nth_token_is (parser->lexer, 2,
   38286                 :             :                                              CPP_CLOSE_PAREN)))
   38287                 :             :         {
   38288                 :          42 :           decl = ridpointers[RID_OMP_ALL_MEMORY];
   38289                 :          42 :           cp_lexer_consume_token (parser->lexer);
   38290                 :             :         }
   38291                 :             :       else
   38292                 :             :         {
   38293                 :       34465 :           name = cp_parser_id_expression (parser, /*template_p=*/false,
   38294                 :             :                                           /*check_dependency_p=*/true,
   38295                 :             :                                           /*template_p=*/NULL,
   38296                 :             :                                           /*declarator_p=*/false,
   38297                 :             :                                           /*optional_p=*/false);
   38298                 :       34465 :           if (name == error_mark_node)
   38299                 :             :             {
   38300                 :         123 :               if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   38301                 :         123 :                   && cp_parser_simulate_error (parser))
   38302                 :          63 :                 goto depend_lvalue;
   38303                 :          60 :               goto skip_comma;
   38304                 :             :             }
   38305                 :             : 
   38306                 :       34342 :           if (identifier_p (name))
   38307                 :       34330 :             decl = cp_parser_lookup_name_simple (parser, name, token->location);
   38308                 :             :           else
   38309                 :             :             decl = name;
   38310                 :       34342 :           if (decl == error_mark_node)
   38311                 :             :             {
   38312                 :          32 :               if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   38313                 :          32 :                   && cp_parser_simulate_error (parser))
   38314                 :          12 :                 goto depend_lvalue;
   38315                 :          20 :               cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
   38316                 :             :                                            token->location);
   38317                 :             :             }
   38318                 :             :         }
   38319                 :       34675 :       if (outer_automatic_var_p (decl))
   38320                 :           7 :         decl = process_outer_var_ref (decl, tf_warning_or_error);
   38321                 :       34675 :       if (decl == error_mark_node)
   38322                 :             :         ;
   38323                 :       34647 :       else if (kind != 0)
   38324                 :             :         {
   38325                 :       34188 :           switch (kind)
   38326                 :             :             {
   38327                 :         880 :             case OMP_CLAUSE__CACHE_:
   38328                 :             :               /* The OpenACC cache directive explicitly only allows "array
   38329                 :             :                  elements or subarrays".  */
   38330                 :         880 :               if (cp_lexer_peek_token (parser->lexer)->type != CPP_OPEN_SQUARE)
   38331                 :             :                 {
   38332                 :          24 :                   error_at (token->location, "expected %<[%>");
   38333                 :          24 :                   decl = error_mark_node;
   38334                 :          24 :                   break;
   38335                 :             :                 }
   38336                 :             :               /* FALLTHROUGH.  */
   38337                 :             :             case OMP_CLAUSE_MAP:
   38338                 :             :             case OMP_CLAUSE_FROM:
   38339                 :             :             case OMP_CLAUSE_TO:
   38340                 :         856 :             start_component_ref:
   38341                 :        7019 :               while (cp_lexer_next_token_is (parser->lexer, CPP_DOT)
   38342                 :        7019 :                      || cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
   38343                 :             :                 {
   38344                 :         487 :                   cpp_ttype ttype
   38345                 :         487 :                     = cp_lexer_next_token_is (parser->lexer, CPP_DOT)
   38346                 :         487 :                       ? CPP_DOT : CPP_DEREF;
   38347                 :         487 :                   location_t loc
   38348                 :         487 :                     = cp_lexer_peek_token (parser->lexer)->location;
   38349                 :         487 :                   cp_id_kind idk = CP_ID_KIND_NONE;
   38350                 :         487 :                   cp_lexer_consume_token (parser->lexer);
   38351                 :         487 :                   decl = convert_from_reference (decl);
   38352                 :         487 :                   decl = (cp_parser_postfix_dot_deref_expression
   38353                 :         487 :                           (parser, ttype, cp_expr (decl, token->location),
   38354                 :             :                            false, &idk, loc));
   38355                 :             :                 }
   38356                 :             :               /* FALLTHROUGH.  */
   38357                 :       17306 :             case OMP_CLAUSE_AFFINITY:
   38358                 :       17306 :             case OMP_CLAUSE_DEPEND:
   38359                 :       17306 :             case OMP_CLAUSE_REDUCTION:
   38360                 :       17306 :             case OMP_CLAUSE_IN_REDUCTION:
   38361                 :       17306 :             case OMP_CLAUSE_TASK_REDUCTION:
   38362                 :       17306 :             case OMP_CLAUSE_HAS_DEVICE_ADDR:
   38363                 :       17306 :               array_section_p = false;
   38364                 :       17306 :               dims.truncate (0);
   38365                 :       43046 :               while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
   38366                 :             :                 {
   38367                 :        8434 :                   location_t loc = UNKNOWN_LOCATION;
   38368                 :        8434 :                   tree low_bound = NULL_TREE, length = NULL_TREE;
   38369                 :        8434 :                   bool no_colon = false;
   38370                 :             : 
   38371                 :        8434 :                   parser->colon_corrects_to_scope_p = false;
   38372                 :        8434 :                   cp_lexer_consume_token (parser->lexer);
   38373                 :        8434 :                   if (!cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   38374                 :             :                     {
   38375                 :        6821 :                       loc = cp_lexer_peek_token (parser->lexer)->location;
   38376                 :        6821 :                       low_bound = cp_parser_expression (parser);
   38377                 :             :                       /* Later handling is not prepared to see through these.  */
   38378                 :        6821 :                       gcc_checking_assert (!location_wrapper_p (low_bound));
   38379                 :             :                     }
   38380                 :        8434 :                   if (!colon)
   38381                 :        8434 :                     parser->colon_corrects_to_scope_p
   38382                 :        8434 :                       = saved_colon_corrects_to_scope_p;
   38383                 :        8434 :                   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
   38384                 :             :                     {
   38385                 :        1147 :                       length = integer_one_node;
   38386                 :        1147 :                       no_colon = true;
   38387                 :             :                     }
   38388                 :             :                   else
   38389                 :             :                     {
   38390                 :             :                       /* Look for `:'.  */
   38391                 :        7287 :                       if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   38392                 :             :                         {
   38393                 :           0 :                           if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   38394                 :           0 :                               && cp_parser_simulate_error (parser))
   38395                 :           0 :                             goto depend_lvalue;
   38396                 :           0 :                           goto skip_comma;
   38397                 :             :                         }
   38398                 :        7287 :                       if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   38399                 :        1356 :                         cp_parser_commit_to_tentative_parse (parser);
   38400                 :             :                       else
   38401                 :             :                         array_section_p = true;
   38402                 :        7287 :                       if (!cp_lexer_next_token_is (parser->lexer,
   38403                 :             :                                                    CPP_CLOSE_SQUARE))
   38404                 :             :                         {
   38405                 :        6259 :                           length = cp_parser_expression (parser);
   38406                 :             :                           /* Later handling is not prepared to see through these.  */
   38407                 :        6259 :                           gcc_checking_assert (!location_wrapper_p (length));
   38408                 :             :                         }
   38409                 :             :                     }
   38410                 :             :                   /* Look for the closing `]'.  */
   38411                 :        8434 :                   if (!cp_parser_require (parser, CPP_CLOSE_SQUARE,
   38412                 :             :                                           RT_CLOSE_SQUARE))
   38413                 :             :                     {
   38414                 :           0 :                       if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   38415                 :           0 :                           && cp_parser_simulate_error (parser))
   38416                 :           0 :                         goto depend_lvalue;
   38417                 :           0 :                       goto skip_comma;
   38418                 :             :                     }
   38419                 :             : 
   38420                 :        8434 :                   dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
   38421                 :             :                 }
   38422                 :             : 
   38423                 :       17306 :               if ((kind == OMP_CLAUSE_MAP
   38424                 :       17306 :                    || kind == OMP_CLAUSE_FROM
   38425                 :       11630 :                    || kind == OMP_CLAUSE_TO)
   38426                 :        5676 :                   && !array_section_p
   38427                 :       20404 :                   && (cp_lexer_next_token_is (parser->lexer, CPP_DOT)
   38428                 :        3095 :                       || cp_lexer_next_token_is (parser->lexer, CPP_DEREF)))
   38429                 :             :                 {
   38430                 :          12 :                   for (unsigned i = 0; i < dims.length (); i++)
   38431                 :             :                     {
   38432                 :           3 :                       gcc_assert (dims[i].length == integer_one_node);
   38433                 :           3 :                       decl = build_array_ref (dims[i].loc,
   38434                 :           3 :                                               decl, dims[i].low_bound);
   38435                 :             :                     }
   38436                 :           3 :                   goto start_component_ref;
   38437                 :             :                 }
   38438                 :             :               else
   38439                 :       41011 :                 for (unsigned i = 0; i < dims.length (); i++)
   38440                 :       16862 :                   decl = build_omp_array_section (input_location, decl,
   38441                 :        8431 :                                                   dims[i].low_bound,
   38442                 :        8431 :                                                   dims[i].length);
   38443                 :             :               break;
   38444                 :             :             default:
   38445                 :             :               break;
   38446                 :             :             }
   38447                 :             : 
   38448                 :       34188 :           if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   38449                 :             :             {
   38450                 :        2403 :               if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
   38451                 :        2242 :                   && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
   38452                 :        2534 :                   && cp_parser_simulate_error (parser))
   38453                 :             :                 {
   38454                 :         206 :                 depend_lvalue:
   38455                 :         206 :                   cp_parser_abort_tentative_parse (parser);
   38456                 :         206 :                   decl = cp_parser_assignment_expression (parser, NULL,
   38457                 :             :                                                           false, false);
   38458                 :             :                 }
   38459                 :             :               else
   38460                 :        2272 :                 cp_parser_parse_definitely (parser);
   38461                 :             :             }
   38462                 :             : 
   38463                 :       31785 :         build_clause:
   38464                 :       42846 :           tree u = build_omp_clause (token->location, kind);
   38465                 :       42846 :           OMP_CLAUSE_DECL (u) = decl;
   38466                 :       42846 :           OMP_CLAUSE_CHAIN (u) = list;
   38467                 :       42846 :           list = u;
   38468                 :             :         }
   38469                 :             :       else
   38470                 :         459 :         list = tree_cons (decl, NULL_TREE, list);
   38471                 :             : 
   38472                 :       43349 :     get_comma:
   38473                 :       43349 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   38474                 :             :         break;
   38475                 :        5498 :       cp_lexer_consume_token (parser->lexer);
   38476                 :        5498 :     }
   38477                 :             : 
   38478                 :       37851 :   if (colon)
   38479                 :        4155 :     parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   38480                 :             : 
   38481                 :        4155 :   if (colon != NULL && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   38482                 :             :     {
   38483                 :        1929 :       *colon = true;
   38484                 :        1929 :       cp_parser_require (parser, CPP_COLON, RT_COLON);
   38485                 :        1929 :       return list;
   38486                 :             :     }
   38487                 :             : 
   38488                 :       35922 :   if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
   38489                 :             :     {
   38490                 :         280 :       int ending;
   38491                 :             : 
   38492                 :             :       /* Try to resync to an unnested comma.  Copied from
   38493                 :             :          cp_parser_parenthesized_expression_list.  */
   38494                 :         220 :     skip_comma:
   38495                 :         280 :       if (colon)
   38496                 :          16 :         parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   38497                 :         280 :       ending = cp_parser_skip_to_closing_parenthesis (parser,
   38498                 :             :                                                       /*recovering=*/true,
   38499                 :             :                                                       /*or_comma=*/true,
   38500                 :             :                                                       /*consume_paren=*/true);
   38501                 :         280 :       if (ending < 0)
   38502                 :          16 :         goto get_comma;
   38503                 :             :     }
   38504                 :             : 
   38505                 :             :   return list;
   38506                 :       37895 : }
   38507                 :             : 
   38508                 :             : /* Similarly, but expect leading and trailing parenthesis.  This is a very
   38509                 :             :    common case for omp clauses.  */
   38510                 :             : 
   38511                 :             : static tree
   38512                 :        9922 : cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list,
   38513                 :             :                         bool map_lvalue = false)
   38514                 :             : {
   38515                 :        9922 :   if (parser->lexer->in_omp_decl_attribute)
   38516                 :             :     {
   38517                 :         105 :       if (kind)
   38518                 :             :         {
   38519                 :          60 :           location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   38520                 :          60 :           tree u = build_omp_clause (loc, kind);
   38521                 :          60 :           OMP_CLAUSE_DECL (u) = parser->lexer->in_omp_decl_attribute;
   38522                 :          60 :           OMP_CLAUSE_CHAIN (u) = list;
   38523                 :          60 :           return u;
   38524                 :             :         }
   38525                 :             :       else
   38526                 :          45 :         return tree_cons (parser->lexer->in_omp_decl_attribute, NULL_TREE,
   38527                 :          45 :                           list);
   38528                 :             :     }
   38529                 :             : 
   38530                 :        9817 :   if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   38531                 :        9801 :     return cp_parser_omp_var_list_no_open (parser, kind, list, NULL,
   38532                 :        9801 :                                            map_lvalue);
   38533                 :             :   return list;
   38534                 :             : }
   38535                 :             : 
   38536                 :             : /* OpenACC 2.0:
   38537                 :             :    copy ( variable-list )
   38538                 :             :    copyin ( variable-list )
   38539                 :             :    copyout ( variable-list )
   38540                 :             :    create ( variable-list )
   38541                 :             :    delete ( variable-list )
   38542                 :             :    present ( variable-list )
   38543                 :             : 
   38544                 :             :    OpenACC 2.6:
   38545                 :             :    no_create ( variable-list )
   38546                 :             :    attach ( variable-list )
   38547                 :             :    detach ( variable-list )
   38548                 :             : 
   38549                 :             :    OpenACC 2.7:
   38550                 :             :    copyin (readonly : variable-list )
   38551                 :             :  */
   38552                 :             : 
   38553                 :             : static tree
   38554                 :        4735 : cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
   38555                 :             :                             tree list)
   38556                 :             : {
   38557                 :        4735 :   enum gomp_map_kind kind;
   38558                 :        4735 :   switch (c_kind)
   38559                 :             :     {
   38560                 :             :     case PRAGMA_OACC_CLAUSE_ATTACH:
   38561                 :             :       kind = GOMP_MAP_ATTACH;
   38562                 :             :       break;
   38563                 :        1382 :     case PRAGMA_OACC_CLAUSE_COPY:
   38564                 :        1382 :       kind = GOMP_MAP_TOFROM;
   38565                 :        1382 :       break;
   38566                 :         921 :     case PRAGMA_OACC_CLAUSE_COPYIN:
   38567                 :         921 :       kind = GOMP_MAP_TO;
   38568                 :         921 :       break;
   38569                 :        1086 :     case PRAGMA_OACC_CLAUSE_COPYOUT:
   38570                 :        1086 :       kind = GOMP_MAP_FROM;
   38571                 :        1086 :       break;
   38572                 :         302 :     case PRAGMA_OACC_CLAUSE_CREATE:
   38573                 :         302 :       kind = GOMP_MAP_ALLOC;
   38574                 :         302 :       break;
   38575                 :         175 :     case PRAGMA_OACC_CLAUSE_DELETE:
   38576                 :         175 :       kind = GOMP_MAP_RELEASE;
   38577                 :         175 :       break;
   38578                 :         116 :     case PRAGMA_OACC_CLAUSE_DETACH:
   38579                 :         116 :       kind = GOMP_MAP_DETACH;
   38580                 :         116 :       break;
   38581                 :          82 :     case PRAGMA_OACC_CLAUSE_DEVICE:
   38582                 :          82 :       kind = GOMP_MAP_FORCE_TO;
   38583                 :          82 :       break;
   38584                 :          57 :     case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
   38585                 :          57 :       kind = GOMP_MAP_DEVICE_RESIDENT;
   38586                 :          57 :       break;
   38587                 :          52 :     case PRAGMA_OACC_CLAUSE_LINK:
   38588                 :          52 :       kind = GOMP_MAP_LINK;
   38589                 :          52 :       break;
   38590                 :          16 :     case PRAGMA_OACC_CLAUSE_NO_CREATE:
   38591                 :          16 :       kind = GOMP_MAP_IF_PRESENT;
   38592                 :          16 :       break;
   38593                 :         249 :     case PRAGMA_OACC_CLAUSE_PRESENT:
   38594                 :         249 :       kind = GOMP_MAP_FORCE_PRESENT;
   38595                 :         249 :       break;
   38596                 :         167 :     case PRAGMA_OACC_CLAUSE_SELF:
   38597                 :             :       /* "The 'host' clause is a synonym for the 'self' clause."  */
   38598                 :         167 :     case PRAGMA_OACC_CLAUSE_HOST:
   38599                 :         167 :       kind = GOMP_MAP_FORCE_FROM;
   38600                 :         167 :       break;
   38601                 :           0 :     default:
   38602                 :           0 :       gcc_unreachable ();
   38603                 :             :     }
   38604                 :             : 
   38605                 :        4735 :   tree nl = list;
   38606                 :        4735 :   bool readonly = false;
   38607                 :        4735 :   if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   38608                 :             :     {
   38609                 :             :       /* Turn on readonly modifier parsing for copyin clause.  */
   38610                 :        4735 :       if (c_kind == PRAGMA_OACC_CLAUSE_COPYIN)
   38611                 :             :         {
   38612                 :         921 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   38613                 :         921 :           if (token->type == CPP_NAME
   38614                 :         920 :               && !strcmp (IDENTIFIER_POINTER (token->u.value), "readonly")
   38615                 :         949 :               && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
   38616                 :             :             {
   38617                 :          28 :               cp_lexer_consume_token (parser->lexer);
   38618                 :          28 :               cp_lexer_consume_token (parser->lexer);
   38619                 :          28 :               readonly = true;
   38620                 :             :             }
   38621                 :             :         }
   38622                 :        4735 :       nl = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list, NULL,
   38623                 :             :                                            false);
   38624                 :             :     }
   38625                 :             : 
   38626                 :       10408 :   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   38627                 :             :     {
   38628                 :        5673 :       OMP_CLAUSE_SET_MAP_KIND (c, kind);
   38629                 :        5673 :       if (readonly)
   38630                 :          52 :         OMP_CLAUSE_MAP_READONLY (c) = 1;
   38631                 :             :     }
   38632                 :             : 
   38633                 :        4735 :   return nl;
   38634                 :             : }
   38635                 :             : 
   38636                 :             : /* OpenACC 2.0:
   38637                 :             :    deviceptr ( variable-list ) */
   38638                 :             : 
   38639                 :             : static tree
   38640                 :         112 : cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list)
   38641                 :             : {
   38642                 :         112 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   38643                 :         112 :   tree vars, t;
   38644                 :             : 
   38645                 :             :   /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
   38646                 :             :      cp_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
   38647                 :             :      variable-list must only allow for pointer variables.  */
   38648                 :         112 :   vars = cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
   38649                 :         224 :   for (t = vars; t; t = TREE_CHAIN (t))
   38650                 :             :     {
   38651                 :         112 :       tree v = TREE_PURPOSE (t);
   38652                 :         112 :       tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
   38653                 :         112 :       OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
   38654                 :         112 :       OMP_CLAUSE_DECL (u) = v;
   38655                 :         112 :       OMP_CLAUSE_CHAIN (u) = list;
   38656                 :         112 :       list = u;
   38657                 :             :     }
   38658                 :             : 
   38659                 :         112 :   return list;
   38660                 :             : }
   38661                 :             : 
   38662                 :             : /* OpenACC 2.5:
   38663                 :             :    auto
   38664                 :             :    finalize
   38665                 :             :    independent
   38666                 :             :    nohost
   38667                 :             :    seq */
   38668                 :             : 
   38669                 :             : static tree
   38670                 :        1574 : cp_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
   38671                 :             :                               tree list)
   38672                 :             : {
   38673                 :        1574 :   check_no_duplicate_clause (list, code, omp_clause_code_name[code], loc);
   38674                 :             : 
   38675                 :        1574 :   tree c = build_omp_clause (loc, code);
   38676                 :        1574 :   OMP_CLAUSE_CHAIN (c) = list;
   38677                 :             : 
   38678                 :        1574 :   return c;
   38679                 :             : }
   38680                 :             : 
   38681                 :             :  /* OpenACC:
   38682                 :             :    num_gangs ( expression )
   38683                 :             :    num_workers ( expression )
   38684                 :             :    vector_length ( expression )  */
   38685                 :             : 
   38686                 :             : static tree
   38687                 :        1248 : cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
   38688                 :             :                                   const char *str, tree list)
   38689                 :             : {
   38690                 :        1248 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   38691                 :             : 
   38692                 :        1248 :   matching_parens parens;
   38693                 :        1248 :   if (!parens.require_open (parser))
   38694                 :             :     return list;
   38695                 :             : 
   38696                 :        1224 :   tree t = cp_parser_assignment_expression (parser, NULL, false, false);
   38697                 :             : 
   38698                 :        1224 :   if (t == error_mark_node
   38699                 :        2352 :       || !parens.require_close (parser))
   38700                 :             :     {
   38701                 :         240 :       cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   38702                 :             :                                              /*or_comma=*/false,
   38703                 :             :                                              /*consume_paren=*/true);
   38704                 :         240 :       return list;
   38705                 :             :     }
   38706                 :             : 
   38707                 :         984 :   check_no_duplicate_clause (list, code, str, loc);
   38708                 :             : 
   38709                 :         984 :   tree c = build_omp_clause (loc, code);
   38710                 :         984 :   OMP_CLAUSE_OPERAND (c, 0) = t;
   38711                 :         984 :   OMP_CLAUSE_CHAIN (c) = list;
   38712                 :         984 :   return c;
   38713                 :             : }
   38714                 :             : 
   38715                 :             : /* OpenACC:
   38716                 :             : 
   38717                 :             :     gang [( gang-arg-list )]
   38718                 :             :     worker [( [num:] int-expr )]
   38719                 :             :     vector [( [length:] int-expr )]
   38720                 :             : 
   38721                 :             :   where gang-arg is one of:
   38722                 :             : 
   38723                 :             :     [num:] int-expr
   38724                 :             :     static: size-expr
   38725                 :             : 
   38726                 :             :   and size-expr may be:
   38727                 :             : 
   38728                 :             :     *
   38729                 :             :     int-expr
   38730                 :             : */
   38731                 :             : 
   38732                 :             : static tree
   38733                 :        4124 : cp_parser_oacc_shape_clause (cp_parser *parser, location_t loc,
   38734                 :             :                              omp_clause_code kind,
   38735                 :             :                              const char *str, tree list)
   38736                 :             : {
   38737                 :        4124 :   const char *id = "num";
   38738                 :        4124 :   cp_lexer *lexer = parser->lexer;
   38739                 :        4124 :   tree ops[2] = { NULL_TREE, NULL_TREE }, c;
   38740                 :             : 
   38741                 :        4124 :   if (kind == OMP_CLAUSE_VECTOR)
   38742                 :        1402 :     id = "length";
   38743                 :             : 
   38744                 :        4124 :   if (cp_lexer_next_token_is (lexer, CPP_OPEN_PAREN))
   38745                 :             :     {
   38746                 :         567 :       matching_parens parens;
   38747                 :         567 :       parens.consume_open (parser);
   38748                 :             : 
   38749                 :         627 :       do
   38750                 :             :         {
   38751                 :         627 :           cp_token *next = cp_lexer_peek_token (lexer);
   38752                 :         627 :           int idx = 0;
   38753                 :             : 
   38754                 :             :           /* Gang static argument.  */
   38755                 :         627 :           if (kind == OMP_CLAUSE_GANG
   38756                 :         627 :               && cp_lexer_next_token_is_keyword (lexer, RID_STATIC))
   38757                 :             :             {
   38758                 :         140 :               cp_lexer_consume_token (lexer);
   38759                 :             : 
   38760                 :         140 :               if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   38761                 :           0 :                 goto cleanup_error;
   38762                 :             : 
   38763                 :         140 :               idx = 1;
   38764                 :         140 :               if (ops[idx] != NULL)
   38765                 :             :                 {
   38766                 :           0 :                   cp_parser_error (parser, "too many %<static%> arguments");
   38767                 :           0 :                   goto cleanup_error;
   38768                 :             :                 }
   38769                 :             : 
   38770                 :             :               /* Check for the '*' argument.  */
   38771                 :         140 :               if (cp_lexer_next_token_is (lexer, CPP_MULT)
   38772                 :         140 :                   && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA)
   38773                 :          57 :                       || cp_lexer_nth_token_is (parser->lexer, 2,
   38774                 :             :                                                 CPP_CLOSE_PAREN)))
   38775                 :             :                 {
   38776                 :          53 :                   cp_lexer_consume_token (lexer);
   38777                 :          53 :                   ops[idx] = integer_minus_one_node;
   38778                 :             : 
   38779                 :          53 :                   if (cp_lexer_next_token_is (lexer, CPP_COMMA))
   38780                 :             :                     {
   38781                 :           4 :                       cp_lexer_consume_token (lexer);
   38782                 :           4 :                       continue;
   38783                 :             :                     }
   38784                 :             :                   else break;
   38785                 :             :                 }
   38786                 :             :             }
   38787                 :             :           /* Worker num: argument and vector length: arguments.  */
   38788                 :         487 :           else if (cp_lexer_next_token_is (lexer, CPP_NAME)
   38789                 :         343 :                    && id_equal (next->u.value, id)
   38790                 :         798 :                    && cp_lexer_nth_token_is (lexer, 2, CPP_COLON))
   38791                 :             :             {
   38792                 :         287 :               cp_lexer_consume_token (lexer);  /* id  */
   38793                 :         287 :               cp_lexer_consume_token (lexer);  /* ':'  */
   38794                 :             :             }
   38795                 :             : 
   38796                 :             :           /* Now collect the actual argument.  */
   38797                 :         574 :           if (ops[idx] != NULL_TREE)
   38798                 :             :             {
   38799                 :          20 :               cp_parser_error (parser, "unexpected argument");
   38800                 :          20 :               goto cleanup_error;
   38801                 :             :             }
   38802                 :             : 
   38803                 :         554 :           tree expr = cp_parser_assignment_expression (parser, NULL, false,
   38804                 :             :                                                        false);
   38805                 :         554 :           if (expr == error_mark_node)
   38806                 :          36 :             goto cleanup_error;
   38807                 :             : 
   38808                 :         518 :           mark_exp_read (expr);
   38809                 :         518 :           ops[idx] = expr;
   38810                 :             : 
   38811                 :         574 :           if (kind == OMP_CLAUSE_GANG
   38812                 :         518 :               && cp_lexer_next_token_is (lexer, CPP_COMMA))
   38813                 :             :             {
   38814                 :          56 :               cp_lexer_consume_token (lexer);
   38815                 :          56 :               continue;
   38816                 :             :             }
   38817                 :             :           break;
   38818                 :             :         }
   38819                 :             :       while (1);
   38820                 :             : 
   38821                 :         511 :       if (!parens.require_close (parser))
   38822                 :          20 :         goto cleanup_error;
   38823                 :             :     }
   38824                 :             : 
   38825                 :        4048 :   check_no_duplicate_clause (list, kind, str, loc);
   38826                 :             : 
   38827                 :        4048 :   c = build_omp_clause (loc, kind);
   38828                 :             : 
   38829                 :        4048 :   if (ops[1])
   38830                 :         136 :     OMP_CLAUSE_OPERAND (c, 1) = ops[1];
   38831                 :             : 
   38832                 :        4048 :   OMP_CLAUSE_OPERAND (c, 0) = ops[0];
   38833                 :        4048 :   OMP_CLAUSE_CHAIN (c) = list;
   38834                 :             : 
   38835                 :        4048 :   return c;
   38836                 :             : 
   38837                 :          76 :  cleanup_error:
   38838                 :          76 :   cp_parser_skip_to_closing_parenthesis (parser, false, false, true);
   38839                 :          76 :   return list;
   38840                 :             : }
   38841                 :             : 
   38842                 :             : /* OpenACC 2.0:
   38843                 :             :    tile ( size-expr-list ) */
   38844                 :             : 
   38845                 :             : static tree
   38846                 :         421 : cp_parser_oacc_clause_tile (cp_parser *parser, location_t clause_loc, tree list)
   38847                 :             : {
   38848                 :         421 :   tree c, expr = error_mark_node;
   38849                 :         421 :   tree tile = NULL_TREE;
   38850                 :             : 
   38851                 :             :   /* Collapse and tile are mutually exclusive.  (The spec doesn't say
   38852                 :             :      so, but the spec authors never considered such a case and have
   38853                 :             :      differing opinions on what it might mean, including 'not
   38854                 :             :      allowed'.)  */
   38855                 :         421 :   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile", clause_loc);
   38856                 :         421 :   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse",
   38857                 :             :                              clause_loc);
   38858                 :             : 
   38859                 :         421 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   38860                 :             :     return list;
   38861                 :             : 
   38862                 :         556 :   do
   38863                 :             :     {
   38864                 :         556 :       if (tile && !cp_parser_require (parser, CPP_COMMA, RT_COMMA))
   38865                 :             :         return list;
   38866                 :             : 
   38867                 :         556 :       if (cp_lexer_next_token_is (parser->lexer, CPP_MULT)
   38868                 :         556 :           && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA)
   38869                 :         190 :               || cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN)))
   38870                 :             :         {
   38871                 :         212 :           cp_lexer_consume_token (parser->lexer);
   38872                 :         212 :           expr = integer_zero_node;
   38873                 :             :         }
   38874                 :             :       else
   38875                 :         344 :         expr = cp_parser_constant_expression (parser);
   38876                 :             : 
   38877                 :         556 :       tile = tree_cons (NULL_TREE, expr, tile);
   38878                 :             :     }
   38879                 :         556 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN));
   38880                 :             : 
   38881                 :             :   /* Consume the trailing ')'.  */
   38882                 :         401 :   cp_lexer_consume_token (parser->lexer);
   38883                 :             : 
   38884                 :         401 :   c = build_omp_clause (clause_loc, OMP_CLAUSE_TILE);
   38885                 :         401 :   tile = nreverse (tile);
   38886                 :         401 :   OMP_CLAUSE_TILE_LIST (c) = tile;
   38887                 :         401 :   OMP_CLAUSE_CHAIN (c) = list;
   38888                 :         401 :   return c;
   38889                 :             : }
   38890                 :             : 
   38891                 :             : /* OpenACC 2.0
   38892                 :             :    Parse wait clause or directive parameters.  */
   38893                 :             : 
   38894                 :             : static tree
   38895                 :         240 : cp_parser_oacc_wait_list (cp_parser *parser, location_t clause_loc, tree list)
   38896                 :             : {
   38897                 :         240 :   vec<tree, va_gc> *args;
   38898                 :         240 :   tree t, args_tree;
   38899                 :             : 
   38900                 :         240 :   args = cp_parser_parenthesized_expression_list (parser, non_attr,
   38901                 :             :                                                   /*cast_p=*/false,
   38902                 :             :                                                   /*allow_expansion_p=*/true,
   38903                 :             :                                                   /*non_constant_p=*/NULL);
   38904                 :             : 
   38905                 :         240 :   if (args == NULL || args->length () == 0)
   38906                 :             :     {
   38907                 :          16 :       if (args != NULL)
   38908                 :             :         {
   38909                 :           4 :           cp_parser_error (parser, "expected integer expression list");
   38910                 :           4 :           release_tree_vector (args);
   38911                 :             :         }
   38912                 :          16 :       return list;
   38913                 :             :     }
   38914                 :             : 
   38915                 :         224 :   args_tree = build_tree_list_vec (args);
   38916                 :             : 
   38917                 :         224 :   release_tree_vector (args);
   38918                 :             : 
   38919                 :         556 :   for (t = args_tree; t; t = TREE_CHAIN (t))
   38920                 :             :     {
   38921                 :         332 :       tree targ = TREE_VALUE (t);
   38922                 :             : 
   38923                 :         332 :       if (targ != error_mark_node)
   38924                 :             :         {
   38925                 :         284 :           if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
   38926                 :          24 :             error ("%<wait%> expression must be integral");
   38927                 :             :           else
   38928                 :             :             {
   38929                 :         260 :               tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
   38930                 :             : 
   38931                 :         260 :               targ = mark_rvalue_use (targ);
   38932                 :         260 :               OMP_CLAUSE_DECL (c) = targ;
   38933                 :         260 :               OMP_CLAUSE_CHAIN (c) = list;
   38934                 :         260 :               list = c;
   38935                 :             :             }
   38936                 :             :         }
   38937                 :             :     }
   38938                 :             : 
   38939                 :             :   return list;
   38940                 :             : }
   38941                 :             : 
   38942                 :             : /* OpenACC:
   38943                 :             :    wait [( int-expr-list )] */
   38944                 :             : 
   38945                 :             : static tree
   38946                 :         220 : cp_parser_oacc_clause_wait (cp_parser *parser, tree list)
   38947                 :             : {
   38948                 :         220 :   location_t location = cp_lexer_peek_token (parser->lexer)->location;
   38949                 :             : 
   38950                 :         220 :   if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
   38951                 :         161 :     list = cp_parser_oacc_wait_list (parser, location, list);
   38952                 :             :   else
   38953                 :             :     {
   38954                 :          59 :       tree c = build_omp_clause (location, OMP_CLAUSE_WAIT);
   38955                 :             : 
   38956                 :          59 :       OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
   38957                 :          59 :       OMP_CLAUSE_CHAIN (c) = list;
   38958                 :          59 :       list = c;
   38959                 :             :     }
   38960                 :             : 
   38961                 :         220 :   return list;
   38962                 :             : }
   38963                 :             : 
   38964                 :             : /* OpenMP 3.0:
   38965                 :             :    collapse ( constant-expression ) */
   38966                 :             : 
   38967                 :             : static tree
   38968                 :        4460 : cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location)
   38969                 :             : {
   38970                 :        4460 :   tree c, num;
   38971                 :        4460 :   location_t loc;
   38972                 :        4460 :   HOST_WIDE_INT n;
   38973                 :             : 
   38974                 :        4460 :   loc = cp_lexer_peek_token (parser->lexer)->location;
   38975                 :        4460 :   matching_parens parens;
   38976                 :        4460 :   if (!parens.require_open (parser))
   38977                 :             :     return list;
   38978                 :             : 
   38979                 :        4460 :   num = cp_parser_constant_expression (parser);
   38980                 :             : 
   38981                 :        4460 :   if (!parens.require_close (parser))
   38982                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   38983                 :             :                                            /*or_comma=*/false,
   38984                 :             :                                            /*consume_paren=*/true);
   38985                 :             : 
   38986                 :        4460 :   if (num == error_mark_node)
   38987                 :             :     return list;
   38988                 :        4460 :   num = fold_non_dependent_expr (num);
   38989                 :        4460 :   if (!tree_fits_shwi_p (num)
   38990                 :        4456 :       || !INTEGRAL_TYPE_P (TREE_TYPE (num))
   38991                 :        4456 :       || (n = tree_to_shwi (num)) <= 0
   38992                 :        8916 :       || (int) n != n)
   38993                 :             :     {
   38994                 :           4 :       error_at (loc, "collapse argument needs positive constant integer expression");
   38995                 :           4 :       return list;
   38996                 :             :     }
   38997                 :             : 
   38998                 :        4456 :   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse", location);
   38999                 :        4456 :   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile", location);
   39000                 :        4456 :   c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
   39001                 :        4456 :   OMP_CLAUSE_CHAIN (c) = list;
   39002                 :        4456 :   OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
   39003                 :             : 
   39004                 :        4456 :   return c;
   39005                 :             : }
   39006                 :             : 
   39007                 :             : /* OpenMP 2.5:
   39008                 :             :    default ( none | shared )
   39009                 :             : 
   39010                 :             :    OpenMP 5.1:
   39011                 :             :    default ( private | firstprivate )
   39012                 :             : 
   39013                 :             :    OpenACC:
   39014                 :             :    default ( none | present ) */
   39015                 :             : 
   39016                 :             : static tree
   39017                 :        2464 : cp_parser_omp_clause_default (cp_parser *parser, tree list,
   39018                 :             :                               location_t location, bool is_oacc)
   39019                 :             : {
   39020                 :        2464 :   enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
   39021                 :        2464 :   tree c;
   39022                 :             : 
   39023                 :        2464 :   matching_parens parens;
   39024                 :        2464 :   if (!parens.require_open (parser))
   39025                 :             :     return list;
   39026                 :        2456 :   if (!is_oacc && cp_lexer_next_token_is_keyword (parser->lexer, RID_PRIVATE))
   39027                 :             :     {
   39028                 :          34 :       kind = OMP_CLAUSE_DEFAULT_PRIVATE;
   39029                 :          34 :       cp_lexer_consume_token (parser->lexer);
   39030                 :             :     }
   39031                 :        2422 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   39032                 :             :     {
   39033                 :        2382 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   39034                 :        2382 :       const char *p = IDENTIFIER_POINTER (id);
   39035                 :             : 
   39036                 :        2382 :       switch (p[0])
   39037                 :             :         {
   39038                 :        1333 :         case 'n':
   39039                 :        1333 :           if (strcmp ("none", p) != 0)
   39040                 :           0 :             goto invalid_kind;
   39041                 :             :           kind = OMP_CLAUSE_DEFAULT_NONE;
   39042                 :             :           break;
   39043                 :             : 
   39044                 :          39 :         case 'p':
   39045                 :          39 :           if (strcmp ("present", p) != 0 || !is_oacc)
   39046                 :           0 :             goto invalid_kind;
   39047                 :             :           kind = OMP_CLAUSE_DEFAULT_PRESENT;
   39048                 :             :           break;
   39049                 :             : 
   39050                 :          42 :         case 'f':
   39051                 :          42 :           if (strcmp ("firstprivate", p) != 0 || is_oacc)
   39052                 :           0 :             goto invalid_kind;
   39053                 :             :           kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   39054                 :             :           break;
   39055                 :             : 
   39056                 :         952 :         case 's':
   39057                 :         952 :           if (strcmp ("shared", p) != 0 || is_oacc)
   39058                 :           0 :             goto invalid_kind;
   39059                 :             :           kind = OMP_CLAUSE_DEFAULT_SHARED;
   39060                 :             :           break;
   39061                 :             : 
   39062                 :          16 :         default:
   39063                 :          16 :           goto invalid_kind;
   39064                 :             :         }
   39065                 :             : 
   39066                 :        2350 :       cp_lexer_consume_token (parser->lexer);
   39067                 :             :     }
   39068                 :             :   else
   39069                 :             :     {
   39070                 :          72 :     invalid_kind:
   39071                 :          72 :       if (is_oacc)
   39072                 :          56 :         cp_parser_error (parser, "expected %<none%> or %<present%>");
   39073                 :             :       else
   39074                 :          16 :         cp_parser_error (parser, "expected %<none%>, %<shared%>, "
   39075                 :             :                                  "%<private%> or %<firstprivate%>");
   39076                 :             :     }
   39077                 :             : 
   39078                 :        2456 :   if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED
   39079                 :        2384 :       || !parens.require_close (parser))
   39080                 :          96 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39081                 :             :                                            /*or_comma=*/false,
   39082                 :             :                                            /*consume_paren=*/true);
   39083                 :             : 
   39084                 :        2456 :   if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
   39085                 :             :     return list;
   39086                 :             : 
   39087                 :        2384 :   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default", location);
   39088                 :        2384 :   c = build_omp_clause (location, OMP_CLAUSE_DEFAULT);
   39089                 :        2384 :   OMP_CLAUSE_CHAIN (c) = list;
   39090                 :        2384 :   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
   39091                 :             : 
   39092                 :        2384 :   return c;
   39093                 :             : }
   39094                 :             : 
   39095                 :             : /* OpenMP 3.1:
   39096                 :             :    final ( expression ) */
   39097                 :             : 
   39098                 :             : static tree
   39099                 :         330 : cp_parser_omp_clause_final (cp_parser *parser, tree list, location_t location)
   39100                 :             : {
   39101                 :         330 :   tree t, c;
   39102                 :             : 
   39103                 :         330 :   matching_parens parens;
   39104                 :         330 :   if (!parens.require_open (parser))
   39105                 :             :     return list;
   39106                 :             : 
   39107                 :         330 :   t = cp_parser_assignment_expression (parser);
   39108                 :             : 
   39109                 :         330 :   if (t == error_mark_node
   39110                 :         660 :       || !parens.require_close (parser))
   39111                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39112                 :             :                                            /*or_comma=*/false,
   39113                 :             :                                            /*consume_paren=*/true);
   39114                 :             : 
   39115                 :         330 :   check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final", location);
   39116                 :             : 
   39117                 :         330 :   c = build_omp_clause (location, OMP_CLAUSE_FINAL);
   39118                 :         330 :   OMP_CLAUSE_FINAL_EXPR (c) = t;
   39119                 :         330 :   OMP_CLAUSE_CHAIN (c) = list;
   39120                 :             : 
   39121                 :         330 :   return c;
   39122                 :             : }
   39123                 :             : 
   39124                 :             : /* OpenMP 5.1:
   39125                 :             :    indirect [( expression )]
   39126                 :             : */
   39127                 :             : 
   39128                 :             : static tree
   39129                 :         114 : cp_parser_omp_clause_indirect (cp_parser *parser, tree list,
   39130                 :             :                                location_t location)
   39131                 :             : {
   39132                 :         114 :   tree t;
   39133                 :             : 
   39134                 :         114 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   39135                 :             :     {
   39136                 :          74 :       matching_parens parens;
   39137                 :          74 :       if (!parens.require_open (parser))
   39138                 :           0 :         return list;
   39139                 :             : 
   39140                 :          74 :       bool non_constant_p;
   39141                 :          74 :       t = cp_parser_constant_expression (parser, true, &non_constant_p);
   39142                 :             : 
   39143                 :          74 :       if (t != error_mark_node && non_constant_p)
   39144                 :           4 :         error_at (location, "expected constant logical expression");
   39145                 :             : 
   39146                 :          74 :       if (t == error_mark_node
   39147                 :         148 :           || !parens.require_close (parser))
   39148                 :           0 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39149                 :             :                                                /*or_comma=*/false,
   39150                 :             :                                                /*consume_paren=*/true);
   39151                 :             :     }
   39152                 :             :   else
   39153                 :          40 :     t = integer_one_node;
   39154                 :             : 
   39155                 :         114 :   check_no_duplicate_clause (list, OMP_CLAUSE_INDIRECT, "indirect", location);
   39156                 :             : 
   39157                 :         114 :   tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
   39158                 :         114 :   OMP_CLAUSE_INDIRECT_EXPR (c) = t;
   39159                 :         114 :   OMP_CLAUSE_CHAIN (c) = list;
   39160                 :             : 
   39161                 :         114 :   return c;
   39162                 :             : }
   39163                 :             : 
   39164                 :             : /* OpenMP 2.5:
   39165                 :             :    if ( expression )
   39166                 :             : 
   39167                 :             :    OpenMP 4.5:
   39168                 :             :    if ( directive-name-modifier : expression )
   39169                 :             : 
   39170                 :             :    directive-name-modifier:
   39171                 :             :      parallel | task | taskloop | target data | target | target update
   39172                 :             :      | target enter data | target exit data
   39173                 :             : 
   39174                 :             :    OpenMP 5.0:
   39175                 :             :    directive-name-modifier:
   39176                 :             :      ... | simd | cancel  */
   39177                 :             : 
   39178                 :             : static tree
   39179                 :        2401 : cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
   39180                 :             :                          bool is_omp)
   39181                 :             : {
   39182                 :        2401 :   tree t, c;
   39183                 :        2401 :   enum tree_code if_modifier = ERROR_MARK;
   39184                 :             : 
   39185                 :        2401 :   matching_parens parens;
   39186                 :        2401 :   if (!parens.require_open (parser))
   39187                 :             :     return list;
   39188                 :             : 
   39189                 :        2401 :   if (is_omp && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   39190                 :             :     {
   39191                 :        1947 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   39192                 :        1947 :       const char *p = IDENTIFIER_POINTER (id);
   39193                 :        1947 :       int n = 2;
   39194                 :             : 
   39195                 :        1947 :       if (strcmp ("cancel", p) == 0)
   39196                 :             :         if_modifier = VOID_CST;
   39197                 :        1899 :       else if (strcmp ("parallel", p) == 0)
   39198                 :             :         if_modifier = OMP_PARALLEL;
   39199                 :        1415 :       else if (strcmp ("simd", p) == 0)
   39200                 :             :         if_modifier = OMP_SIMD;
   39201                 :        1150 :       else if (strcmp ("task", p) == 0)
   39202                 :             :         if_modifier = OMP_TASK;
   39203                 :        1108 :       else if (strcmp ("taskloop", p) == 0)
   39204                 :             :         if_modifier = OMP_TASKLOOP;
   39205                 :         926 :       else if (strcmp ("target", p) == 0)
   39206                 :             :         {
   39207                 :         362 :           if_modifier = OMP_TARGET;
   39208                 :         362 :           if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   39209                 :             :             {
   39210                 :         138 :               id = cp_lexer_peek_nth_token (parser->lexer, 2)->u.value;
   39211                 :         138 :               p = IDENTIFIER_POINTER (id);
   39212                 :         138 :               if (strcmp ("data", p) == 0)
   39213                 :             :                 if_modifier = OMP_TARGET_DATA;
   39214                 :         108 :               else if (strcmp ("update", p) == 0)
   39215                 :             :                 if_modifier = OMP_TARGET_UPDATE;
   39216                 :          68 :               else if (strcmp ("enter", p) == 0)
   39217                 :             :                 if_modifier = OMP_TARGET_ENTER_DATA;
   39218                 :          38 :               else if (strcmp ("exit", p) == 0)
   39219                 :             :                 if_modifier = OMP_TARGET_EXIT_DATA;
   39220                 :           0 :               if (if_modifier != OMP_TARGET)
   39221                 :             :                 n = 3;
   39222                 :             :               else
   39223                 :             :                 {
   39224                 :           0 :                   location_t loc
   39225                 :           0 :                     = cp_lexer_peek_nth_token (parser->lexer, 2)->location;
   39226                 :           0 :                   error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
   39227                 :             :                                  "or %<exit%>");
   39228                 :           0 :                   if_modifier = ERROR_MARK;
   39229                 :             :                 }
   39230                 :         138 :               if (if_modifier == OMP_TARGET_ENTER_DATA
   39231                 :         138 :                   || if_modifier == OMP_TARGET_EXIT_DATA)
   39232                 :             :                 {
   39233                 :          68 :                   if (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME))
   39234                 :             :                     {
   39235                 :          68 :                       id = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value;
   39236                 :          68 :                       p = IDENTIFIER_POINTER (id);
   39237                 :          68 :                       if (strcmp ("data", p) == 0)
   39238                 :             :                         n = 4;
   39239                 :             :                     }
   39240                 :           0 :                   if (n != 4)
   39241                 :             :                     {
   39242                 :           0 :                       location_t loc
   39243                 :           0 :                         = cp_lexer_peek_nth_token (parser->lexer, 3)->location;
   39244                 :           0 :                       error_at (loc, "expected %<data%>");
   39245                 :           0 :                       if_modifier = ERROR_MARK;
   39246                 :             :                     }
   39247                 :             :                 }
   39248                 :             :             }
   39249                 :             :         }
   39250                 :         138 :       if (if_modifier != ERROR_MARK)
   39251                 :             :         {
   39252                 :        1383 :           if (cp_lexer_nth_token_is (parser->lexer, n, CPP_COLON))
   39253                 :             :             {
   39254                 :        4343 :               while (n-- > 0)
   39255                 :        2964 :                 cp_lexer_consume_token (parser->lexer);
   39256                 :             :             }
   39257                 :             :           else
   39258                 :             :             {
   39259                 :           4 :               if (n > 2)
   39260                 :             :                 {
   39261                 :           0 :                   location_t loc
   39262                 :           0 :                     = cp_lexer_peek_nth_token (parser->lexer, n)->location;
   39263                 :           0 :                   error_at (loc, "expected %<:%>");
   39264                 :             :                 }
   39265                 :             :               if_modifier = ERROR_MARK;
   39266                 :             :             }
   39267                 :             :         }
   39268                 :             :     }
   39269                 :             : 
   39270                 :        2401 :   t = cp_parser_assignment_expression (parser);
   39271                 :             : 
   39272                 :        2401 :   if (t == error_mark_node
   39273                 :        4802 :       || !parens.require_close (parser))
   39274                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39275                 :             :                                            /*or_comma=*/false,
   39276                 :             :                                            /*consume_paren=*/true);
   39277                 :             : 
   39278                 :       12343 :   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
   39279                 :       10102 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
   39280                 :             :       {
   39281                 :         626 :         if (if_modifier != ERROR_MARK
   39282                 :         626 :             && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
   39283                 :             :           {
   39284                 :          36 :             const char *p = NULL;
   39285                 :          36 :             switch (if_modifier)
   39286                 :             :               {
   39287                 :             :               case VOID_CST: p = "cancel"; break;
   39288                 :           4 :               case OMP_PARALLEL: p = "parallel"; break;
   39289                 :           0 :               case OMP_SIMD: p = "simd"; break;
   39290                 :           4 :               case OMP_TASK: p = "task"; break;
   39291                 :           4 :               case OMP_TASKLOOP: p = "taskloop"; break;
   39292                 :           4 :               case OMP_TARGET_DATA: p = "target data"; break;
   39293                 :           4 :               case OMP_TARGET: p = "target"; break;
   39294                 :           4 :               case OMP_TARGET_UPDATE: p = "target update"; break;
   39295                 :           4 :               case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
   39296                 :           4 :               case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
   39297                 :           0 :               default: gcc_unreachable ();
   39298                 :             :               }
   39299                 :          36 :             error_at (location, "too many %<if%> clauses with %qs modifier",
   39300                 :             :                       p);
   39301                 :          36 :             return list;
   39302                 :             :           }
   39303                 :         590 :         else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
   39304                 :             :           {
   39305                 :          52 :             if (!is_omp)
   39306                 :           4 :               error_at (location, "too many %<if%> clauses");
   39307                 :             :             else
   39308                 :          48 :               error_at (location, "too many %<if%> clauses without modifier");
   39309                 :          52 :             return list;
   39310                 :             :           }
   39311                 :         538 :         else if (if_modifier == ERROR_MARK
   39312                 :         538 :                  || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
   39313                 :             :           {
   39314                 :          72 :             error_at (location, "if any %<if%> clause has modifier, then all "
   39315                 :             :                                 "%<if%> clauses have to use modifier");
   39316                 :          72 :             return list;
   39317                 :             :           }
   39318                 :             :       }
   39319                 :             : 
   39320                 :        2241 :   c = build_omp_clause (location, OMP_CLAUSE_IF);
   39321                 :        2241 :   OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
   39322                 :        2241 :   OMP_CLAUSE_IF_EXPR (c) = t;
   39323                 :        2241 :   OMP_CLAUSE_CHAIN (c) = list;
   39324                 :             : 
   39325                 :        2241 :   return c;
   39326                 :             : }
   39327                 :             : 
   39328                 :             : /* OpenMP 3.1:
   39329                 :             :    mergeable */
   39330                 :             : 
   39331                 :             : static tree
   39332                 :         264 : cp_parser_omp_clause_mergeable (cp_parser * /*parser*/,
   39333                 :             :                                 tree list, location_t location)
   39334                 :             : {
   39335                 :         264 :   tree c;
   39336                 :             : 
   39337                 :         264 :   check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable",
   39338                 :             :                              location);
   39339                 :             : 
   39340                 :         264 :   c = build_omp_clause (location, OMP_CLAUSE_MERGEABLE);
   39341                 :         264 :   OMP_CLAUSE_CHAIN (c) = list;
   39342                 :         264 :   return c;
   39343                 :             : }
   39344                 :             : 
   39345                 :             : /* OpenMP 2.5:
   39346                 :             :    nowait */
   39347                 :             : 
   39348                 :             : static tree
   39349                 :         636 : cp_parser_omp_clause_nowait (cp_parser * /*parser*/,
   39350                 :             :                              tree list, location_t location)
   39351                 :             : {
   39352                 :         636 :   tree c;
   39353                 :             : 
   39354                 :         636 :   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait", location);
   39355                 :             : 
   39356                 :         636 :   c = build_omp_clause (location, OMP_CLAUSE_NOWAIT);
   39357                 :         636 :   OMP_CLAUSE_CHAIN (c) = list;
   39358                 :         636 :   return c;
   39359                 :             : }
   39360                 :             : 
   39361                 :             : /* OpenMP 2.5:
   39362                 :             :    num_threads ( expression ) */
   39363                 :             : 
   39364                 :             : static tree
   39365                 :         856 : cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
   39366                 :             :                                   location_t location)
   39367                 :             : {
   39368                 :         856 :   tree t, c;
   39369                 :             : 
   39370                 :         856 :   matching_parens parens;
   39371                 :         856 :   if (!parens.require_open (parser))
   39372                 :             :     return list;
   39373                 :             : 
   39374                 :         856 :   t = cp_parser_assignment_expression (parser);
   39375                 :             : 
   39376                 :         856 :   if (t == error_mark_node
   39377                 :        1712 :       || !parens.require_close (parser))
   39378                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39379                 :             :                                            /*or_comma=*/false,
   39380                 :             :                                            /*consume_paren=*/true);
   39381                 :             : 
   39382                 :         856 :   check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS,
   39383                 :             :                              "num_threads", location);
   39384                 :             : 
   39385                 :         856 :   c = build_omp_clause (location, OMP_CLAUSE_NUM_THREADS);
   39386                 :         856 :   OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
   39387                 :         856 :   OMP_CLAUSE_CHAIN (c) = list;
   39388                 :             : 
   39389                 :         856 :   return c;
   39390                 :             : }
   39391                 :             : 
   39392                 :             : /* OpenMP 4.5:
   39393                 :             :    num_tasks ( expression )
   39394                 :             : 
   39395                 :             :    OpenMP 5.1:
   39396                 :             :    num_tasks ( strict : expression ) */
   39397                 :             : 
   39398                 :             : static tree
   39399                 :         156 : cp_parser_omp_clause_num_tasks (cp_parser *parser, tree list,
   39400                 :             :                                 location_t location)
   39401                 :             : {
   39402                 :         156 :   tree t, c;
   39403                 :             : 
   39404                 :         156 :   matching_parens parens;
   39405                 :         156 :   if (!parens.require_open (parser))
   39406                 :             :     return list;
   39407                 :             : 
   39408                 :         156 :   bool strict = false;
   39409                 :         156 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   39410                 :         156 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
   39411                 :             :     {
   39412                 :           1 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   39413                 :           1 :       if (!strcmp (IDENTIFIER_POINTER (id), "strict"))
   39414                 :             :         {
   39415                 :           1 :           strict = true;
   39416                 :           1 :           cp_lexer_consume_token (parser->lexer);
   39417                 :           1 :           cp_lexer_consume_token (parser->lexer);
   39418                 :             :         }
   39419                 :             :     }
   39420                 :             : 
   39421                 :         156 :   t = cp_parser_assignment_expression (parser);
   39422                 :             : 
   39423                 :         156 :   if (t == error_mark_node
   39424                 :         312 :       || !parens.require_close (parser))
   39425                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39426                 :             :                                            /*or_comma=*/false,
   39427                 :             :                                            /*consume_paren=*/true);
   39428                 :             : 
   39429                 :         156 :   check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS,
   39430                 :             :                              "num_tasks", location);
   39431                 :             : 
   39432                 :         156 :   c = build_omp_clause (location, OMP_CLAUSE_NUM_TASKS);
   39433                 :         156 :   OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
   39434                 :         156 :   OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
   39435                 :         156 :   OMP_CLAUSE_CHAIN (c) = list;
   39436                 :             : 
   39437                 :         156 :   return c;
   39438                 :             : }
   39439                 :             : 
   39440                 :             : /* OpenMP 4.5:
   39441                 :             :    grainsize ( expression )
   39442                 :             : 
   39443                 :             :    OpenMP 5.1:
   39444                 :             :    grainsize ( strict : expression ) */
   39445                 :             : 
   39446                 :             : static tree
   39447                 :         192 : cp_parser_omp_clause_grainsize (cp_parser *parser, tree list,
   39448                 :             :                                 location_t location)
   39449                 :             : {
   39450                 :         192 :   tree t, c;
   39451                 :             : 
   39452                 :         192 :   matching_parens parens;
   39453                 :         192 :   if (!parens.require_open (parser))
   39454                 :             :     return list;
   39455                 :             : 
   39456                 :         192 :   bool strict = false;
   39457                 :         192 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   39458                 :         192 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
   39459                 :             :     {
   39460                 :           1 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   39461                 :           1 :       if (!strcmp (IDENTIFIER_POINTER (id), "strict"))
   39462                 :             :         {
   39463                 :           1 :           strict = true;
   39464                 :           1 :           cp_lexer_consume_token (parser->lexer);
   39465                 :           1 :           cp_lexer_consume_token (parser->lexer);
   39466                 :             :         }
   39467                 :             :     }
   39468                 :             : 
   39469                 :         192 :   t = cp_parser_assignment_expression (parser);
   39470                 :             : 
   39471                 :         192 :   if (t == error_mark_node
   39472                 :         384 :       || !parens.require_close (parser))
   39473                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39474                 :             :                                            /*or_comma=*/false,
   39475                 :             :                                            /*consume_paren=*/true);
   39476                 :             : 
   39477                 :         192 :   check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE,
   39478                 :             :                              "grainsize", location);
   39479                 :             : 
   39480                 :         192 :   c = build_omp_clause (location, OMP_CLAUSE_GRAINSIZE);
   39481                 :         192 :   OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
   39482                 :         192 :   OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
   39483                 :         192 :   OMP_CLAUSE_CHAIN (c) = list;
   39484                 :             : 
   39485                 :         192 :   return c;
   39486                 :             : }
   39487                 :             : 
   39488                 :             : /* OpenMP 4.5:
   39489                 :             :    priority ( expression ) */
   39490                 :             : 
   39491                 :             : static tree
   39492                 :         322 : cp_parser_omp_clause_priority (cp_parser *parser, tree list,
   39493                 :             :                                location_t location)
   39494                 :             : {
   39495                 :         322 :   tree t, c;
   39496                 :             : 
   39497                 :         322 :   matching_parens parens;
   39498                 :         322 :   if (!parens.require_open (parser))
   39499                 :             :     return list;
   39500                 :             : 
   39501                 :         322 :   t = cp_parser_assignment_expression (parser);
   39502                 :             : 
   39503                 :         322 :   if (t == error_mark_node
   39504                 :         644 :       || !parens.require_close (parser))
   39505                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39506                 :             :                                            /*or_comma=*/false,
   39507                 :             :                                            /*consume_paren=*/true);
   39508                 :             : 
   39509                 :         322 :   check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY,
   39510                 :             :                              "priority", location);
   39511                 :             : 
   39512                 :         322 :   c = build_omp_clause (location, OMP_CLAUSE_PRIORITY);
   39513                 :         322 :   OMP_CLAUSE_PRIORITY_EXPR (c) = t;
   39514                 :         322 :   OMP_CLAUSE_CHAIN (c) = list;
   39515                 :             : 
   39516                 :         322 :   return c;
   39517                 :             : }
   39518                 :             : 
   39519                 :             : /* OpenMP 4.5:
   39520                 :             :    hint ( expression ) */
   39521                 :             : 
   39522                 :             : static tree
   39523                 :         225 : cp_parser_omp_clause_hint (cp_parser *parser, tree list, location_t location)
   39524                 :             : {
   39525                 :         225 :   tree t, c;
   39526                 :             : 
   39527                 :         225 :   matching_parens parens;
   39528                 :         225 :   if (!parens.require_open (parser))
   39529                 :             :     return list;
   39530                 :             : 
   39531                 :         225 :   t = cp_parser_assignment_expression (parser);
   39532                 :             : 
   39533                 :         225 :   if (t != error_mark_node)
   39534                 :             :     {
   39535                 :         225 :       t = fold_non_dependent_expr (t);
   39536                 :         225 :       if (!value_dependent_expression_p (t)
   39537                 :         225 :           && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
   39538                 :         165 :               || !tree_fits_shwi_p (t)
   39539                 :         152 :               || tree_int_cst_sgn (t) == -1))
   39540                 :          18 :         error_at (location, "expected constant integer expression with "
   39541                 :             :                             "valid sync-hint value");
   39542                 :             :     }
   39543                 :         225 :   if (t == error_mark_node
   39544                 :         450 :       || !parens.require_close (parser))
   39545                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39546                 :             :                                            /*or_comma=*/false,
   39547                 :             :                                            /*consume_paren=*/true);
   39548                 :         225 :   check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint", location);
   39549                 :             : 
   39550                 :         225 :   c = build_omp_clause (location, OMP_CLAUSE_HINT);
   39551                 :         225 :   OMP_CLAUSE_HINT_EXPR (c) = t;
   39552                 :         225 :   OMP_CLAUSE_CHAIN (c) = list;
   39553                 :             : 
   39554                 :         225 :   return c;
   39555                 :             : }
   39556                 :             : 
   39557                 :             : /* OpenMP 5.1:
   39558                 :             :    filter ( integer-expression ) */
   39559                 :             : 
   39560                 :             : static tree
   39561                 :         214 : cp_parser_omp_clause_filter (cp_parser *parser, tree list, location_t location)
   39562                 :             : {
   39563                 :         214 :   tree t, c;
   39564                 :             : 
   39565                 :         214 :   matching_parens parens;
   39566                 :         214 :   if (!parens.require_open (parser))
   39567                 :             :     return list;
   39568                 :             : 
   39569                 :         214 :   t = cp_parser_assignment_expression (parser);
   39570                 :             : 
   39571                 :         214 :   if (t == error_mark_node
   39572                 :         428 :       || !parens.require_close (parser))
   39573                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39574                 :             :                                            /*or_comma=*/false,
   39575                 :             :                                            /*consume_paren=*/true);
   39576                 :         214 :   check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter", location);
   39577                 :             : 
   39578                 :         214 :   c = build_omp_clause (location, OMP_CLAUSE_FILTER);
   39579                 :         214 :   OMP_CLAUSE_FILTER_EXPR (c) = t;
   39580                 :         214 :   OMP_CLAUSE_CHAIN (c) = list;
   39581                 :             : 
   39582                 :         214 :   return c;
   39583                 :             : }
   39584                 :             : 
   39585                 :             : /* OpenMP 4.5:
   39586                 :             :    defaultmap ( tofrom : scalar )
   39587                 :             : 
   39588                 :             :    OpenMP 5.0:
   39589                 :             :    defaultmap ( implicit-behavior [ : variable-category ] ) */
   39590                 :             : 
   39591                 :             : static tree
   39592                 :         816 : cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
   39593                 :             :                                  location_t location)
   39594                 :             : {
   39595                 :         816 :   tree c, id;
   39596                 :         816 :   const char *p;
   39597                 :         816 :   enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
   39598                 :         816 :   enum omp_clause_defaultmap_kind category
   39599                 :             :     = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
   39600                 :             : 
   39601                 :         816 :   matching_parens parens;
   39602                 :         816 :   if (!parens.require_open (parser))
   39603                 :             :     return list;
   39604                 :             : 
   39605                 :         816 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT))
   39606                 :             :     p = "default";
   39607                 :         793 :   else if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   39608                 :             :     {
   39609                 :           8 :     invalid_behavior:
   39610                 :          12 :       cp_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
   39611                 :             :                                "%<tofrom%>, %<firstprivate%>, %<none%> "
   39612                 :             :                                "or %<default%>");
   39613                 :          12 :       goto out_err;
   39614                 :             :     }
   39615                 :             :   else
   39616                 :             :     {
   39617                 :         785 :       id = cp_lexer_peek_token (parser->lexer)->u.value;
   39618                 :         785 :       p = IDENTIFIER_POINTER (id);
   39619                 :             :     }
   39620                 :             : 
   39621                 :         808 :   switch (p[0])
   39622                 :             :     {
   39623                 :          24 :     case 'a':
   39624                 :          24 :       if (strcmp ("alloc", p) == 0)
   39625                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
   39626                 :             :       else
   39627                 :           0 :         goto invalid_behavior;
   39628                 :             :       break;
   39629                 :             : 
   39630                 :          23 :     case 'd':
   39631                 :          23 :       if (strcmp ("default", p) == 0)
   39632                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
   39633                 :             :       else
   39634                 :           0 :         goto invalid_behavior;
   39635                 :             :       break;
   39636                 :             : 
   39637                 :          92 :     case 'f':
   39638                 :          92 :       if (strcmp ("firstprivate", p) == 0)
   39639                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
   39640                 :          12 :       else if (strcmp ("from", p) == 0)
   39641                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
   39642                 :             :       else
   39643                 :           0 :         goto invalid_behavior;
   39644                 :             :       break;
   39645                 :             : 
   39646                 :         380 :     case 'n':
   39647                 :         380 :       if (strcmp ("none", p) == 0)
   39648                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
   39649                 :             :       else
   39650                 :           0 :         goto invalid_behavior;
   39651                 :             :       break;
   39652                 :             : 
   39653                 :          10 :     case 'p':
   39654                 :          10 :       if (strcmp ("present", p) == 0)
   39655                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
   39656                 :             :       else
   39657                 :           0 :         goto invalid_behavior;
   39658                 :             :       break;
   39659                 :             : 
   39660                 :         275 :     case 't':
   39661                 :         275 :       if (strcmp ("tofrom", p) == 0)
   39662                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
   39663                 :          16 :       else if (strcmp ("to", p) == 0)
   39664                 :             :         behavior = OMP_CLAUSE_DEFAULTMAP_TO;
   39665                 :             :       else
   39666                 :           0 :         goto invalid_behavior;
   39667                 :             :       break;
   39668                 :             : 
   39669                 :           4 :     default:
   39670                 :           4 :       goto invalid_behavior;
   39671                 :             :     }
   39672                 :         804 :   cp_lexer_consume_token (parser->lexer);
   39673                 :             : 
   39674                 :         804 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
   39675                 :             :     {
   39676                 :         406 :       if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   39677                 :          12 :         goto out_err;
   39678                 :             : 
   39679                 :         394 :       if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   39680                 :             :         {
   39681                 :           4 :         invalid_category:
   39682                 :           8 :           cp_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
   39683                 :             :                                    "%<all%>");
   39684                 :           8 :           goto out_err;
   39685                 :             :         }
   39686                 :         390 :       id = cp_lexer_peek_token (parser->lexer)->u.value;
   39687                 :         390 :       p = IDENTIFIER_POINTER (id);
   39688                 :             : 
   39689                 :         390 :       switch (p[0])
   39690                 :             :         {
   39691                 :          76 :         case 'a':
   39692                 :          76 :           if (strcmp ("aggregate", p) == 0)
   39693                 :             :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
   39694                 :          32 :           else if (strcmp ("all", p) == 0)
   39695                 :             :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
   39696                 :             :           else
   39697                 :           0 :             goto invalid_category;
   39698                 :             :           break;
   39699                 :             : 
   39700                 :          39 :         case 'p':
   39701                 :          39 :           if (strcmp ("pointer", p) == 0)
   39702                 :             :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
   39703                 :             :           else
   39704                 :           0 :             goto invalid_category;
   39705                 :             :           break;
   39706                 :             : 
   39707                 :         271 :         case 's':
   39708                 :         271 :           if (strcmp ("scalar", p) == 0)
   39709                 :             :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
   39710                 :             :           else
   39711                 :           0 :             goto invalid_category;
   39712                 :             :           break;
   39713                 :             : 
   39714                 :           4 :         default:
   39715                 :           4 :           goto invalid_category;
   39716                 :             :         }
   39717                 :             : 
   39718                 :         386 :       cp_lexer_consume_token (parser->lexer);
   39719                 :             :     }
   39720                 :         784 :   if (!parens.require_close (parser))
   39721                 :           0 :     goto out_err;
   39722                 :             : 
   39723                 :        2534 :   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
   39724                 :        1802 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
   39725                 :        1802 :         && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
   39726                 :             :             || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
   39727                 :          92 :             || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
   39728                 :          88 :             || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
   39729                 :             :                 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
   39730                 :          80 :             || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
   39731                 :             :                 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
   39732                 :             :       {
   39733                 :          52 :         enum omp_clause_defaultmap_kind cat = category;
   39734                 :          52 :         location_t loc = OMP_CLAUSE_LOCATION (c);
   39735                 :          52 :         if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
   39736                 :          52 :             || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
   39737                 :          12 :                 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
   39738                 :             :                     != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
   39739                 :          32 :           cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
   39740                 :          52 :         p = NULL;
   39741                 :          52 :         switch (cat)
   39742                 :             :           {
   39743                 :             :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
   39744                 :             :             p = NULL;
   39745                 :             :             break;
   39746                 :          12 :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
   39747                 :          12 :             p = "all";
   39748                 :          12 :             break;
   39749                 :           8 :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
   39750                 :           8 :             p = "aggregate";
   39751                 :           8 :             break;
   39752                 :          12 :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
   39753                 :          12 :             p = "pointer";
   39754                 :          12 :             break;
   39755                 :             :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
   39756                 :             :             p = "scalar";
   39757                 :             :             break;
   39758                 :           0 :           default:
   39759                 :           0 :             gcc_unreachable ();
   39760                 :             :           }
   39761                 :          32 :         if (p)
   39762                 :          40 :           error_at (loc, "too many %<defaultmap%> clauses with %qs category",
   39763                 :             :                     p);
   39764                 :             :         else
   39765                 :          12 :           error_at (loc, "too many %<defaultmap%> clauses with unspecified "
   39766                 :             :                          "category");
   39767                 :             :         break;
   39768                 :             :       }
   39769                 :             : 
   39770                 :         784 :   c = build_omp_clause (location, OMP_CLAUSE_DEFAULTMAP);
   39771                 :         784 :   OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
   39772                 :         784 :   OMP_CLAUSE_CHAIN (c) = list;
   39773                 :         784 :   return c;
   39774                 :             : 
   39775                 :          32 :  out_err:
   39776                 :          32 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39777                 :             :                                          /*or_comma=*/false,
   39778                 :             :                                          /*consume_paren=*/true);
   39779                 :          32 :   return list;
   39780                 :             : }
   39781                 :             : 
   39782                 :             : /* OpenMP 5.0:
   39783                 :             :    order ( concurrent )
   39784                 :             : 
   39785                 :             :    OpenMP 5.1:
   39786                 :             :    order ( order-modifier : concurrent )
   39787                 :             : 
   39788                 :             :    order-modifier:
   39789                 :             :      reproducible
   39790                 :             :      unconstrained  */
   39791                 :             : 
   39792                 :             : static tree
   39793                 :        1379 : cp_parser_omp_clause_order (cp_parser *parser, tree list, location_t location)
   39794                 :             : {
   39795                 :        1379 :   tree c, id;
   39796                 :        1379 :   const char *p;
   39797                 :        1379 :   bool unconstrained = false;
   39798                 :        1379 :   bool reproducible = false;
   39799                 :             : 
   39800                 :        1379 :   matching_parens parens;
   39801                 :        1379 :   if (!parens.require_open (parser))
   39802                 :             :     return list;
   39803                 :             : 
   39804                 :        1371 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   39805                 :        1371 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
   39806                 :             :     {
   39807                 :         416 :       id = cp_lexer_peek_token (parser->lexer)->u.value;
   39808                 :         416 :       p = IDENTIFIER_POINTER (id);
   39809                 :         416 :       if (strcmp (p, "unconstrained") == 0)
   39810                 :             :         unconstrained = true;
   39811                 :         212 :       else if (strcmp (p, "reproducible") == 0)
   39812                 :             :         reproducible = true;
   39813                 :             :       else
   39814                 :             :         {
   39815                 :           4 :           cp_parser_error (parser, "expected %<reproducible%> or "
   39816                 :             :                                    "%<unconstrained%>");
   39817                 :           4 :           goto out_err;
   39818                 :             :         }
   39819                 :         412 :       cp_lexer_consume_token (parser->lexer);
   39820                 :         412 :       cp_lexer_consume_token (parser->lexer);
   39821                 :             :     }
   39822                 :        1367 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   39823                 :             :     {
   39824                 :           0 :       cp_parser_error (parser, "expected %<concurrent%>");
   39825                 :           0 :       goto out_err;
   39826                 :             :     }
   39827                 :             :   else
   39828                 :             :     {
   39829                 :        1367 :       id = cp_lexer_peek_token (parser->lexer)->u.value;
   39830                 :        1367 :       p = IDENTIFIER_POINTER (id);
   39831                 :             :     }
   39832                 :        1367 :   if (strcmp (p, "concurrent") != 0)
   39833                 :             :     {
   39834                 :           4 :       cp_parser_error (parser, "expected %<concurrent%>");
   39835                 :           4 :       goto out_err;
   39836                 :             :     }
   39837                 :        1363 :   cp_lexer_consume_token (parser->lexer);
   39838                 :        1363 :   if (!parens.require_close (parser))
   39839                 :           4 :     goto out_err;
   39840                 :             : 
   39841                 :        1359 :   check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order", location);
   39842                 :        1359 :   c = build_omp_clause (location, OMP_CLAUSE_ORDER);
   39843                 :        1359 :   OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
   39844                 :        1359 :   OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
   39845                 :        1359 :   OMP_CLAUSE_CHAIN (c) = list;
   39846                 :        1359 :   return c;
   39847                 :             : 
   39848                 :          12 :  out_err:
   39849                 :          12 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39850                 :             :                                          /*or_comma=*/false,
   39851                 :             :                                          /*consume_paren=*/true);
   39852                 :          12 :   return list;
   39853                 :             : }
   39854                 :             : 
   39855                 :             : /* OpenMP 5.0:
   39856                 :             :    bind ( teams | parallel | thread ) */
   39857                 :             : 
   39858                 :             : static tree
   39859                 :         449 : cp_parser_omp_clause_bind (cp_parser *parser, tree list,
   39860                 :             :                            location_t location)
   39861                 :             : {
   39862                 :         449 :   tree c;
   39863                 :         449 :   const char *p;
   39864                 :         449 :   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
   39865                 :             : 
   39866                 :         449 :   matching_parens parens;
   39867                 :         449 :   if (!parens.require_open (parser))
   39868                 :             :     return list;
   39869                 :             : 
   39870                 :         441 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   39871                 :             :     {
   39872                 :          12 :     invalid:
   39873                 :          16 :       cp_parser_error (parser,
   39874                 :             :                        "expected %<teams%>, %<parallel%> or %<thread%>");
   39875                 :          16 :       goto out_err;
   39876                 :             :     }
   39877                 :             :   else
   39878                 :             :     {
   39879                 :         429 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   39880                 :         429 :       p = IDENTIFIER_POINTER (id);
   39881                 :             :     }
   39882                 :         429 :   if (strcmp (p, "teams") == 0)
   39883                 :             :     kind = OMP_CLAUSE_BIND_TEAMS;
   39884                 :         295 :   else if (strcmp (p, "parallel") == 0)
   39885                 :             :     kind = OMP_CLAUSE_BIND_PARALLEL;
   39886                 :         148 :   else if (strcmp (p, "thread") != 0)
   39887                 :           4 :     goto invalid;
   39888                 :         425 :   cp_lexer_consume_token (parser->lexer);
   39889                 :         425 :   if (!parens.require_close (parser))
   39890                 :           4 :     goto out_err;
   39891                 :             : 
   39892                 :             :   /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind", location); */
   39893                 :         421 :   c = build_omp_clause (location, OMP_CLAUSE_BIND);
   39894                 :         421 :   OMP_CLAUSE_BIND_KIND (c) = kind;
   39895                 :         421 :   OMP_CLAUSE_CHAIN (c) = list;
   39896                 :         421 :   return c;
   39897                 :             : 
   39898                 :          20 :  out_err:
   39899                 :          20 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39900                 :             :                                          /*or_comma=*/false,
   39901                 :             :                                          /*consume_paren=*/true);
   39902                 :          20 :   return list;
   39903                 :             : }
   39904                 :             : 
   39905                 :             : /* OpenMP 2.5:
   39906                 :             :    ordered
   39907                 :             : 
   39908                 :             :    OpenMP 4.5:
   39909                 :             :    ordered ( constant-expression ) */
   39910                 :             : 
   39911                 :             : static tree
   39912                 :         744 : cp_parser_omp_clause_ordered (cp_parser *parser,
   39913                 :             :                               tree list, location_t location)
   39914                 :             : {
   39915                 :         744 :   tree c, num = NULL_TREE;
   39916                 :         744 :   HOST_WIDE_INT n;
   39917                 :             : 
   39918                 :         744 :   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
   39919                 :             :                              "ordered", location);
   39920                 :             : 
   39921                 :         744 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   39922                 :             :     {
   39923                 :         420 :       matching_parens parens;
   39924                 :         420 :       parens.consume_open (parser);
   39925                 :             : 
   39926                 :         420 :       num = cp_parser_constant_expression (parser);
   39927                 :             : 
   39928                 :         420 :       if (!parens.require_close (parser))
   39929                 :           4 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   39930                 :             :                                                /*or_comma=*/false,
   39931                 :             :                                                /*consume_paren=*/true);
   39932                 :             : 
   39933                 :         420 :       if (num == error_mark_node)
   39934                 :           4 :         return list;
   39935                 :         420 :       num = fold_non_dependent_expr (num);
   39936                 :         420 :       if (!tree_fits_shwi_p (num)
   39937                 :         416 :           || !INTEGRAL_TYPE_P (TREE_TYPE (num))
   39938                 :         416 :           || (n = tree_to_shwi (num)) <= 0
   39939                 :         836 :           || (int) n != n)
   39940                 :             :         {
   39941                 :           4 :           error_at (location,
   39942                 :             :                     "ordered argument needs positive constant integer "
   39943                 :             :                     "expression");
   39944                 :           4 :           return list;
   39945                 :             :         }
   39946                 :             :     }
   39947                 :             : 
   39948                 :         740 :   c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
   39949                 :         740 :   OMP_CLAUSE_ORDERED_EXPR (c) = num;
   39950                 :         740 :   OMP_CLAUSE_CHAIN (c) = list;
   39951                 :         740 :   return c;
   39952                 :             : }
   39953                 :             : 
   39954                 :             : /* OpenMP 2.5:
   39955                 :             :    reduction ( reduction-operator : variable-list )
   39956                 :             : 
   39957                 :             :    reduction-operator:
   39958                 :             :      One of: + * - & ^ | && ||
   39959                 :             : 
   39960                 :             :    OpenMP 3.1:
   39961                 :             : 
   39962                 :             :    reduction-operator:
   39963                 :             :      One of: + * - & ^ | && || min max
   39964                 :             : 
   39965                 :             :    OpenMP 4.0:
   39966                 :             : 
   39967                 :             :    reduction-operator:
   39968                 :             :      One of: + * - & ^ | && ||
   39969                 :             :      id-expression
   39970                 :             : 
   39971                 :             :    OpenMP 5.0:
   39972                 :             :    reduction ( reduction-modifier, reduction-operator : variable-list )
   39973                 :             :    in_reduction ( reduction-operator : variable-list )
   39974                 :             :    task_reduction ( reduction-operator : variable-list )  */
   39975                 :             : 
   39976                 :             : static tree
   39977                 :        6859 : cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
   39978                 :             :                                 bool is_omp, tree list)
   39979                 :             : {
   39980                 :        6859 :   enum tree_code code = ERROR_MARK;
   39981                 :        6859 :   tree nlist, c, id = NULL_TREE;
   39982                 :        6859 :   bool task = false;
   39983                 :        6859 :   bool inscan = false;
   39984                 :             : 
   39985                 :        6859 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   39986                 :             :     return list;
   39987                 :             : 
   39988                 :        6859 :   if (kind == OMP_CLAUSE_REDUCTION && is_omp)
   39989                 :             :     {
   39990                 :        3695 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT)
   39991                 :        3695 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
   39992                 :             :         {
   39993                 :         304 :           cp_lexer_consume_token (parser->lexer);
   39994                 :         304 :           cp_lexer_consume_token (parser->lexer);
   39995                 :             :         }
   39996                 :        3391 :       else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   39997                 :        3391 :                && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
   39998                 :             :         {
   39999                 :         660 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40000                 :         660 :           const char *p = IDENTIFIER_POINTER (id);
   40001                 :         660 :           if (strcmp (p, "task") == 0)
   40002                 :             :             task = true;
   40003                 :         426 :           else if (strcmp (p, "inscan") == 0)
   40004                 :         426 :             inscan = true;
   40005                 :         660 :           if (task || inscan)
   40006                 :             :             {
   40007                 :         660 :               cp_lexer_consume_token (parser->lexer);
   40008                 :         660 :               cp_lexer_consume_token (parser->lexer);
   40009                 :             :             }
   40010                 :             :         }
   40011                 :             :     }
   40012                 :             : 
   40013                 :        6859 :   switch (cp_lexer_peek_token (parser->lexer)->type)
   40014                 :             :     {
   40015                 :        5297 :     case CPP_PLUS: code = PLUS_EXPR; break;
   40016                 :         425 :     case CPP_MULT: code = MULT_EXPR; break;
   40017                 :         408 :     case CPP_MINUS: code = MINUS_EXPR; break;
   40018                 :          45 :     case CPP_AND: code = BIT_AND_EXPR; break;
   40019                 :          19 :     case CPP_XOR: code = BIT_XOR_EXPR; break;
   40020                 :          54 :     case CPP_OR: code = BIT_IOR_EXPR; break;
   40021                 :          74 :     case CPP_AND_AND: code = TRUTH_ANDIF_EXPR; break;
   40022                 :             :     case CPP_OR_OR: code = TRUTH_ORIF_EXPR; break;
   40023                 :             :     default: break;
   40024                 :             :     }
   40025                 :             : 
   40026                 :        6322 :   if (code != ERROR_MARK)
   40027                 :        6400 :     cp_lexer_consume_token (parser->lexer);
   40028                 :             :   else
   40029                 :             :     {
   40030                 :         459 :       bool saved_colon_corrects_to_scope_p;
   40031                 :         459 :       saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   40032                 :         459 :       parser->colon_corrects_to_scope_p = false;
   40033                 :         459 :       id = cp_parser_id_expression (parser, /*template_p=*/false,
   40034                 :             :                                     /*check_dependency_p=*/true,
   40035                 :             :                                     /*template_p=*/NULL,
   40036                 :             :                                     /*declarator_p=*/false,
   40037                 :             :                                     /*optional_p=*/false);
   40038                 :         459 :       parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   40039                 :         459 :       if (identifier_p (id))
   40040                 :             :         {
   40041                 :         455 :           const char *p = IDENTIFIER_POINTER (id);
   40042                 :             : 
   40043                 :         455 :           if (strcmp (p, "min") == 0)
   40044                 :             :             code = MIN_EXPR;
   40045                 :         398 :           else if (strcmp (p, "max") == 0)
   40046                 :             :             code = MAX_EXPR;
   40047                 :         299 :           else if (id == ovl_op_identifier (false, PLUS_EXPR))
   40048                 :             :             code = PLUS_EXPR;
   40049                 :         267 :           else if (id == ovl_op_identifier (false, MULT_EXPR))
   40050                 :             :             code = MULT_EXPR;
   40051                 :         267 :           else if (id == ovl_op_identifier (false, MINUS_EXPR))
   40052                 :             :             code = MINUS_EXPR;
   40053                 :         259 :           else if (id == ovl_op_identifier (false, BIT_AND_EXPR))
   40054                 :             :             code = BIT_AND_EXPR;
   40055                 :         259 :           else if (id == ovl_op_identifier (false, BIT_IOR_EXPR))
   40056                 :             :             code = BIT_IOR_EXPR;
   40057                 :         259 :           else if (id == ovl_op_identifier (false, BIT_XOR_EXPR))
   40058                 :             :             code = BIT_XOR_EXPR;
   40059                 :         259 :           else if (id == ovl_op_identifier (false, TRUTH_ANDIF_EXPR))
   40060                 :             :             code = TRUTH_ANDIF_EXPR;
   40061                 :         259 :           else if (id == ovl_op_identifier (false, TRUTH_ORIF_EXPR))
   40062                 :           0 :             code = TRUTH_ORIF_EXPR;
   40063                 :         455 :           id = omp_reduction_id (code, id, NULL_TREE);
   40064                 :         455 :           tree scope = parser->scope;
   40065                 :         455 :           if (scope)
   40066                 :          52 :             id = build_qualified_name (NULL_TREE, scope, id, false);
   40067                 :         455 :           parser->scope = NULL_TREE;
   40068                 :         455 :           parser->qualifying_scope = NULL_TREE;
   40069                 :         455 :           parser->object_scope = NULL_TREE;
   40070                 :             :         }
   40071                 :             :       else
   40072                 :             :         {
   40073                 :           4 :           error ("invalid reduction-identifier");
   40074                 :           4 :          resync_fail:
   40075                 :           4 :           cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40076                 :             :                                                  /*or_comma=*/false,
   40077                 :             :                                                  /*consume_paren=*/true);
   40078                 :           4 :           return list;
   40079                 :             :         }
   40080                 :             :     }
   40081                 :             : 
   40082                 :        6855 :   if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   40083                 :           0 :     goto resync_fail;
   40084                 :             : 
   40085                 :        6855 :   nlist = cp_parser_omp_var_list_no_open (parser, kind, list,
   40086                 :             :                                           NULL);
   40087                 :       21776 :   for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   40088                 :             :     {
   40089                 :        8066 :       OMP_CLAUSE_REDUCTION_CODE (c) = code;
   40090                 :        8066 :       if (task)
   40091                 :         346 :         OMP_CLAUSE_REDUCTION_TASK (c) = 1;
   40092                 :        7720 :       else if (inscan)
   40093                 :         438 :         OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
   40094                 :        8066 :       OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = id;
   40095                 :             :     }
   40096                 :             : 
   40097                 :             :   return nlist;
   40098                 :             : }
   40099                 :             : 
   40100                 :             : /* OpenMP 2.5:
   40101                 :             :    schedule ( schedule-kind )
   40102                 :             :    schedule ( schedule-kind , expression )
   40103                 :             : 
   40104                 :             :    schedule-kind:
   40105                 :             :      static | dynamic | guided | runtime | auto
   40106                 :             : 
   40107                 :             :    OpenMP 4.5:
   40108                 :             :    schedule ( schedule-modifier : schedule-kind )
   40109                 :             :    schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
   40110                 :             : 
   40111                 :             :    schedule-modifier:
   40112                 :             :      simd
   40113                 :             :      monotonic
   40114                 :             :      nonmonotonic  */
   40115                 :             : 
   40116                 :             : static tree
   40117                 :        4006 : cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
   40118                 :             : {
   40119                 :        4006 :   tree c, t;
   40120                 :        4006 :   int modifiers = 0, nmodifiers = 0;
   40121                 :             : 
   40122                 :        4006 :   matching_parens parens;
   40123                 :        4006 :   if (!parens.require_open (parser))
   40124                 :             :     return list;
   40125                 :             : 
   40126                 :        3998 :   c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);
   40127                 :             : 
   40128                 :        3998 :   location_t comma = UNKNOWN_LOCATION;
   40129                 :        8046 :   while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   40130                 :             :     {
   40131                 :        1942 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40132                 :        1942 :       const char *p = IDENTIFIER_POINTER (id);
   40133                 :        1942 :       if (strcmp ("simd", p) == 0)
   40134                 :          67 :         OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
   40135                 :        1875 :       else if (strcmp ("monotonic", p) == 0)
   40136                 :         116 :         modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
   40137                 :        1759 :       else if (strcmp ("nonmonotonic", p) == 0)
   40138                 :         145 :         modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
   40139                 :             :       else
   40140                 :             :         break;
   40141                 :         328 :       comma = UNKNOWN_LOCATION;
   40142                 :         328 :       cp_lexer_consume_token (parser->lexer);
   40143                 :         328 :       if (nmodifiers++ == 0
   40144                 :         328 :           && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   40145                 :             :         {
   40146                 :          50 :           comma = cp_lexer_peek_token (parser->lexer)->location;
   40147                 :          50 :           cp_lexer_consume_token (parser->lexer);
   40148                 :             :         }
   40149                 :             :       else
   40150                 :             :         {
   40151                 :         278 :           cp_parser_require (parser, CPP_COLON, RT_COLON);
   40152                 :         278 :           break;
   40153                 :             :         }
   40154                 :             :     }
   40155                 :        3998 :   if (comma != UNKNOWN_LOCATION)
   40156                 :          12 :     error_at (comma, "expected %<:%>");
   40157                 :             : 
   40158                 :        3998 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   40159                 :             :     {
   40160                 :        1797 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40161                 :        1797 :       const char *p = IDENTIFIER_POINTER (id);
   40162                 :             : 
   40163                 :        1797 :       switch (p[0])
   40164                 :             :         {
   40165                 :         187 :         case 'd':
   40166                 :         187 :           if (strcmp ("dynamic", p) != 0)
   40167                 :           0 :             goto invalid_kind;
   40168                 :         187 :           OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
   40169                 :         187 :           break;
   40170                 :             : 
   40171                 :         755 :         case 'g':
   40172                 :         755 :           if (strcmp ("guided", p) != 0)
   40173                 :           0 :             goto invalid_kind;
   40174                 :         755 :           OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
   40175                 :         755 :           break;
   40176                 :             : 
   40177                 :         851 :         case 'r':
   40178                 :         851 :           if (strcmp ("runtime", p) != 0)
   40179                 :           0 :             goto invalid_kind;
   40180                 :         851 :           OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
   40181                 :         851 :           break;
   40182                 :             : 
   40183                 :           4 :         default:
   40184                 :           4 :           goto invalid_kind;
   40185                 :             :         }
   40186                 :             :     }
   40187                 :        2201 :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC))
   40188                 :        1510 :     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
   40189                 :         691 :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
   40190                 :         687 :     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
   40191                 :             :   else
   40192                 :           4 :     goto invalid_kind;
   40193                 :        3990 :   cp_lexer_consume_token (parser->lexer);
   40194                 :             : 
   40195                 :        3990 :   if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
   40196                 :             :                     | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
   40197                 :             :       == (OMP_CLAUSE_SCHEDULE_MONOTONIC
   40198                 :             :           | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
   40199                 :             :     {
   40200                 :           8 :       error_at (location, "both %<monotonic%> and %<nonmonotonic%> modifiers "
   40201                 :             :                           "specified");
   40202                 :           8 :       modifiers = 0;
   40203                 :             :     }
   40204                 :             : 
   40205                 :        3990 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   40206                 :             :     {
   40207                 :        2152 :       cp_token *token;
   40208                 :        2152 :       cp_lexer_consume_token (parser->lexer);
   40209                 :             : 
   40210                 :        2152 :       token = cp_lexer_peek_token (parser->lexer);
   40211                 :        2152 :       t = cp_parser_assignment_expression (parser);
   40212                 :             : 
   40213                 :        2152 :       if (t == error_mark_node)
   40214                 :           0 :         goto resync_fail;
   40215                 :        2152 :       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
   40216                 :           4 :         error_at (token->location, "schedule %<runtime%> does not take "
   40217                 :             :                   "a %<chunk_size%> parameter");
   40218                 :        2148 :       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
   40219                 :           0 :         error_at (token->location, "schedule %<auto%> does not take "
   40220                 :             :                   "a %<chunk_size%> parameter");
   40221                 :             :       else
   40222                 :        2148 :         OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
   40223                 :             : 
   40224                 :        2152 :       if (!parens.require_close (parser))
   40225                 :           8 :         goto resync_fail;
   40226                 :             :     }
   40227                 :        1838 :   else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
   40228                 :          12 :     goto resync_fail;
   40229                 :             : 
   40230                 :        7940 :   OMP_CLAUSE_SCHEDULE_KIND (c)
   40231                 :        7940 :     = (enum omp_clause_schedule_kind)
   40232                 :        3970 :       (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
   40233                 :             : 
   40234                 :        3970 :   check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);
   40235                 :        3970 :   OMP_CLAUSE_CHAIN (c) = list;
   40236                 :        3970 :   return c;
   40237                 :             : 
   40238                 :           8 :  invalid_kind:
   40239                 :           8 :   cp_parser_error (parser, "invalid schedule kind");
   40240                 :          28 :  resync_fail:
   40241                 :          28 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40242                 :             :                                          /*or_comma=*/false,
   40243                 :             :                                          /*consume_paren=*/true);
   40244                 :          28 :   return list;
   40245                 :             : }
   40246                 :             : 
   40247                 :             : /* OpenMP 3.0:
   40248                 :             :    untied */
   40249                 :             : 
   40250                 :             : static tree
   40251                 :         276 : cp_parser_omp_clause_untied (cp_parser * /*parser*/,
   40252                 :             :                              tree list, location_t location)
   40253                 :             : {
   40254                 :         276 :   tree c;
   40255                 :             : 
   40256                 :         276 :   check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied", location);
   40257                 :             : 
   40258                 :         276 :   c = build_omp_clause (location, OMP_CLAUSE_UNTIED);
   40259                 :         276 :   OMP_CLAUSE_CHAIN (c) = list;
   40260                 :         276 :   return c;
   40261                 :             : }
   40262                 :             : 
   40263                 :             : /* OpenMP 4.0:
   40264                 :             :    inbranch
   40265                 :             :    notinbranch */
   40266                 :             : 
   40267                 :             : static tree
   40268                 :         715 : cp_parser_omp_clause_branch (cp_parser * /*parser*/, enum omp_clause_code code,
   40269                 :             :                              tree list, location_t location)
   40270                 :             : {
   40271                 :         715 :   check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
   40272                 :         715 :   tree c = build_omp_clause (location, code);
   40273                 :         715 :   OMP_CLAUSE_CHAIN (c) = list;
   40274                 :         715 :   return c;
   40275                 :             : }
   40276                 :             : 
   40277                 :             : /* OpenMP 4.0:
   40278                 :             :    parallel
   40279                 :             :    for
   40280                 :             :    sections
   40281                 :             :    taskgroup */
   40282                 :             : 
   40283                 :             : static tree
   40284                 :        1427 : cp_parser_omp_clause_cancelkind (cp_parser * /*parser*/,
   40285                 :             :                                  enum omp_clause_code code,
   40286                 :             :                                  tree list, location_t location)
   40287                 :             : {
   40288                 :        1427 :   tree c = build_omp_clause (location, code);
   40289                 :        1427 :   OMP_CLAUSE_CHAIN (c) = list;
   40290                 :        1427 :   return c;
   40291                 :             : }
   40292                 :             : 
   40293                 :             : /* OpenMP 4.5:
   40294                 :             :    nogroup */
   40295                 :             : 
   40296                 :             : static tree
   40297                 :          47 : cp_parser_omp_clause_nogroup (cp_parser * /*parser*/,
   40298                 :             :                               tree list, location_t location)
   40299                 :             : {
   40300                 :          47 :   check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup", location);
   40301                 :          47 :   tree c = build_omp_clause (location, OMP_CLAUSE_NOGROUP);
   40302                 :          47 :   OMP_CLAUSE_CHAIN (c) = list;
   40303                 :          47 :   return c;
   40304                 :             : }
   40305                 :             : 
   40306                 :             : /* OpenMP 4.5:
   40307                 :             :    simd
   40308                 :             :    threads */
   40309                 :             : 
   40310                 :             : static tree
   40311                 :         370 : cp_parser_omp_clause_orderedkind (cp_parser * /*parser*/,
   40312                 :             :                                   enum omp_clause_code code,
   40313                 :             :                                   tree list, location_t location)
   40314                 :             : {
   40315                 :         370 :   check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
   40316                 :         370 :   tree c = build_omp_clause (location, code);
   40317                 :         370 :   OMP_CLAUSE_CHAIN (c) = list;
   40318                 :         370 :   return c;
   40319                 :             : }
   40320                 :             : 
   40321                 :             : /* OpenMP 4.0:
   40322                 :             :    num_teams ( expression )
   40323                 :             : 
   40324                 :             :    OpenMP 5.1:
   40325                 :             :    num_teams ( expression : expression ) */
   40326                 :             : 
   40327                 :             : static tree
   40328                 :         751 : cp_parser_omp_clause_num_teams (cp_parser *parser, tree list,
   40329                 :             :                                 location_t location)
   40330                 :             : {
   40331                 :         751 :   tree upper, lower = NULL_TREE, c;
   40332                 :             : 
   40333                 :         751 :   matching_parens parens;
   40334                 :         751 :   if (!parens.require_open (parser))
   40335                 :             :     return list;
   40336                 :             : 
   40337                 :         751 :   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   40338                 :         751 :   parser->colon_corrects_to_scope_p = false;
   40339                 :         751 :   upper = cp_parser_assignment_expression (parser);
   40340                 :         751 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   40341                 :             : 
   40342                 :         751 :   if (upper != error_mark_node
   40343                 :         751 :       && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   40344                 :             :     {
   40345                 :         264 :       lower = upper;
   40346                 :         264 :       cp_lexer_consume_token (parser->lexer);
   40347                 :         264 :       upper = cp_parser_assignment_expression (parser);
   40348                 :             :     }
   40349                 :             : 
   40350                 :         751 :   if (upper == error_mark_node
   40351                 :        1502 :       || !parens.require_close (parser))
   40352                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40353                 :             :                                            /*or_comma=*/false,
   40354                 :             :                                            /*consume_paren=*/true);
   40355                 :             : 
   40356                 :         751 :   check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS,
   40357                 :             :                              "num_teams", location);
   40358                 :             : 
   40359                 :         751 :   c = build_omp_clause (location, OMP_CLAUSE_NUM_TEAMS);
   40360                 :         751 :   OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
   40361                 :         751 :   OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
   40362                 :         751 :   OMP_CLAUSE_CHAIN (c) = list;
   40363                 :             : 
   40364                 :         751 :   return c;
   40365                 :             : }
   40366                 :             : 
   40367                 :             : /* OpenMP 4.0:
   40368                 :             :    thread_limit ( expression ) */
   40369                 :             : 
   40370                 :             : static tree
   40371                 :         508 : cp_parser_omp_clause_thread_limit (cp_parser *parser, tree list,
   40372                 :             :                                    location_t location)
   40373                 :             : {
   40374                 :         508 :   tree t, c;
   40375                 :             : 
   40376                 :         508 :   matching_parens parens;
   40377                 :         508 :   if (!parens.require_open (parser))
   40378                 :             :     return list;
   40379                 :             : 
   40380                 :         508 :   t = cp_parser_assignment_expression (parser);
   40381                 :             : 
   40382                 :         508 :   if (t == error_mark_node
   40383                 :        1016 :       || !parens.require_close (parser))
   40384                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40385                 :             :                                            /*or_comma=*/false,
   40386                 :             :                                            /*consume_paren=*/true);
   40387                 :             : 
   40388                 :         508 :   check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
   40389                 :             :                              "thread_limit", location);
   40390                 :             : 
   40391                 :         508 :   c = build_omp_clause (location, OMP_CLAUSE_THREAD_LIMIT);
   40392                 :         508 :   OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
   40393                 :         508 :   OMP_CLAUSE_CHAIN (c) = list;
   40394                 :             : 
   40395                 :         508 :   return c;
   40396                 :             : }
   40397                 :             : 
   40398                 :             : /* OpenMP 4.0:
   40399                 :             :    aligned ( variable-list )
   40400                 :             :    aligned ( variable-list : constant-expression )  */
   40401                 :             : 
   40402                 :             : static tree
   40403                 :         859 : cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
   40404                 :             : {
   40405                 :         859 :   tree nlist, c, alignment = NULL_TREE;
   40406                 :         859 :   bool colon;
   40407                 :             : 
   40408                 :         859 :   matching_parens parens;
   40409                 :         859 :   if (!parens.require_open (parser))
   40410                 :             :     return list;
   40411                 :             : 
   40412                 :         859 :   nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALIGNED, list,
   40413                 :             :                                           &colon);
   40414                 :             : 
   40415                 :         859 :   if (colon)
   40416                 :             :     {
   40417                 :         807 :       alignment = cp_parser_constant_expression (parser);
   40418                 :             : 
   40419                 :         807 :       if (!parens.require_close (parser))
   40420                 :           4 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40421                 :             :                                                /*or_comma=*/false,
   40422                 :             :                                                /*consume_paren=*/true);
   40423                 :             : 
   40424                 :         807 :       if (alignment == error_mark_node)
   40425                 :          52 :         alignment = NULL_TREE;
   40426                 :             :     }
   40427                 :             : 
   40428                 :        1779 :   for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   40429                 :         920 :     OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
   40430                 :             : 
   40431                 :             :   return nlist;
   40432                 :             : }
   40433                 :             : 
   40434                 :             : /* OpenMP 5.0:
   40435                 :             :    allocate ( variable-list )
   40436                 :             :    allocate ( expression : variable-list )
   40437                 :             : 
   40438                 :             :    OpenMP 5.1:
   40439                 :             :    allocate ( allocator-modifier : variable-list )
   40440                 :             :    allocate ( allocator-modifier , allocator-modifier : variable-list )
   40441                 :             : 
   40442                 :             :    allocator-modifier:
   40443                 :             :    allocator ( expression )
   40444                 :             :    align ( expression )  */
   40445                 :             : 
   40446                 :             : static tree
   40447                 :        1727 : cp_parser_omp_clause_allocate (cp_parser *parser, tree list)
   40448                 :             : {
   40449                 :        1727 :   tree nlist, c, allocator = NULL_TREE, align = NULL_TREE;
   40450                 :        1727 :   bool colon, has_modifiers = false;
   40451                 :             : 
   40452                 :        1727 :   matching_parens parens;
   40453                 :        1727 :   if (!parens.require_open (parser))
   40454                 :             :     return list;
   40455                 :             : 
   40456                 :        1727 :   cp_parser_parse_tentatively (parser);
   40457                 :        1727 :   bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   40458                 :        1727 :   parser->colon_corrects_to_scope_p = false;
   40459                 :        1806 :   for (int mod = 0; mod < 2; mod++)
   40460                 :        1806 :     if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   40461                 :        1806 :         && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
   40462                 :             :       {
   40463                 :         249 :         tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40464                 :         249 :         const char *p = IDENTIFIER_POINTER (id);
   40465                 :         249 :         if (strcmp (p, "allocator") != 0 && strcmp (p, "align") != 0)
   40466                 :             :           break;
   40467                 :         241 :         cp_lexer_consume_token (parser->lexer);
   40468                 :         241 :         matching_parens parens2;
   40469                 :         241 :         if (!parens2.require_open (parser))
   40470                 :             :           break;
   40471                 :         241 :         if (strcmp (p, "allocator") == 0)
   40472                 :             :           {
   40473                 :         126 :             if (allocator != NULL_TREE)
   40474                 :             :               break;
   40475                 :         122 :             allocator = cp_parser_assignment_expression (parser);
   40476                 :             :           }
   40477                 :             :         else
   40478                 :             :           {
   40479                 :         115 :             if (align != NULL_TREE)
   40480                 :             :               break;
   40481                 :         111 :             align = cp_parser_assignment_expression (parser);
   40482                 :             :           }
   40483                 :         233 :         if (!parens2.require_close (parser))
   40484                 :             :           break;
   40485                 :         233 :         if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   40486                 :             :           {
   40487                 :             :             has_modifiers = true;
   40488                 :             :             break;
   40489                 :             :           }
   40490                 :          79 :         if (mod != 0 || cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
   40491                 :             :           break;
   40492                 :          79 :         cp_lexer_consume_token (parser->lexer);
   40493                 :             :       }
   40494                 :             :     else
   40495                 :             :       break;
   40496                 :        1727 :   if (!has_modifiers)
   40497                 :             :     {
   40498                 :        1573 :       cp_parser_abort_tentative_parse (parser);
   40499                 :        1573 :       align = NULL_TREE;
   40500                 :        1573 :       allocator = NULL_TREE;
   40501                 :        1573 :       cp_parser_parse_tentatively (parser);
   40502                 :        1573 :       allocator = cp_parser_assignment_expression (parser);
   40503                 :             :     }
   40504                 :        1727 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   40505                 :        1727 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   40506                 :             :     {
   40507                 :         602 :       cp_parser_parse_definitely (parser);
   40508                 :         602 :       cp_lexer_consume_token (parser->lexer);
   40509                 :         602 :       if (allocator == error_mark_node)
   40510                 :           4 :         allocator = NULL_TREE;
   40511                 :         602 :       if (align == error_mark_node)
   40512                 :           0 :         align = NULL_TREE;
   40513                 :             :     }
   40514                 :             :   else
   40515                 :             :     {
   40516                 :        1125 :       cp_parser_abort_tentative_parse (parser);
   40517                 :        1125 :       allocator = NULL_TREE;
   40518                 :        1125 :       align = NULL_TREE;
   40519                 :             :     }
   40520                 :             : 
   40521                 :        1727 :   nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALLOCATE, list,
   40522                 :             :                                           &colon);
   40523                 :             : 
   40524                 :        1727 :   if (allocator || align)
   40525                 :        1348 :     for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   40526                 :             :       {
   40527                 :         750 :         OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
   40528                 :         750 :         OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
   40529                 :             :       }
   40530                 :             : 
   40531                 :             :   return nlist;
   40532                 :             : }
   40533                 :             : 
   40534                 :             : /* OpenMP 2.5:
   40535                 :             :    lastprivate ( variable-list )
   40536                 :             : 
   40537                 :             :    OpenMP 5.0:
   40538                 :             :    lastprivate ( [ lastprivate-modifier : ] variable-list )  */
   40539                 :             : 
   40540                 :             : static tree
   40541                 :        1773 : cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list)
   40542                 :             : {
   40543                 :        1773 :   bool conditional = false;
   40544                 :             : 
   40545                 :        1773 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   40546                 :             :     return list;
   40547                 :             : 
   40548                 :        1773 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   40549                 :        1773 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
   40550                 :             :     {
   40551                 :         174 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40552                 :         174 :       const char *p = IDENTIFIER_POINTER (id);
   40553                 :             : 
   40554                 :         174 :       if (strcmp ("conditional", p) == 0)
   40555                 :             :         {
   40556                 :         174 :           conditional = true;
   40557                 :         174 :           cp_lexer_consume_token (parser->lexer);
   40558                 :         174 :           cp_lexer_consume_token (parser->lexer);
   40559                 :             :         }
   40560                 :             :     }
   40561                 :             : 
   40562                 :        1773 :   tree nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LASTPRIVATE,
   40563                 :             :                                                list, NULL);
   40564                 :             : 
   40565                 :        1773 :   if (conditional)
   40566                 :         392 :     for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   40567                 :         218 :       OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
   40568                 :             :   return nlist;
   40569                 :             : }
   40570                 :             : 
   40571                 :             : /* OpenMP 4.0:
   40572                 :             :    linear ( variable-list )
   40573                 :             :    linear ( variable-list : expression )
   40574                 :             : 
   40575                 :             :    OpenMP 4.5:
   40576                 :             :    linear ( modifier ( variable-list ) )
   40577                 :             :    linear ( modifier ( variable-list ) : expression )
   40578                 :             : 
   40579                 :             :    modifier:
   40580                 :             :      val
   40581                 :             :      ref
   40582                 :             :      uval
   40583                 :             : 
   40584                 :             :    OpenMP 5.2:
   40585                 :             :    linear ( variable-list : modifiers-list )
   40586                 :             : 
   40587                 :             :    modifiers:
   40588                 :             :      val
   40589                 :             :      ref
   40590                 :             :      uval
   40591                 :             :      step ( expression )  */
   40592                 :             : 
   40593                 :             : static tree
   40594                 :        1828 : cp_parser_omp_clause_linear (cp_parser *parser, tree list,
   40595                 :             :                              bool declare_simd)
   40596                 :             : {
   40597                 :        1828 :   tree nlist, c, step = integer_one_node;
   40598                 :        1828 :   bool colon;
   40599                 :        1828 :   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
   40600                 :        1828 :   bool old_linear_modifier = false;
   40601                 :             : 
   40602                 :        1828 :   matching_parens parens;
   40603                 :        1828 :   if (!parens.require_open (parser))
   40604                 :             :     return list;
   40605                 :             : 
   40606                 :        1828 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   40607                 :             :     {
   40608                 :        1772 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40609                 :        1772 :       const char *p = IDENTIFIER_POINTER (id);
   40610                 :             : 
   40611                 :        1772 :       if (strcmp ("ref", p) == 0)
   40612                 :             :         kind = OMP_CLAUSE_LINEAR_REF;
   40613                 :        1681 :       else if (strcmp ("val", p) == 0)
   40614                 :             :         kind = OMP_CLAUSE_LINEAR_VAL;
   40615                 :        1585 :       else if (strcmp ("uval", p) == 0)
   40616                 :          80 :         kind = OMP_CLAUSE_LINEAR_UVAL;
   40617                 :        1772 :       if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
   40618                 :             :         {
   40619                 :         267 :           cp_lexer_consume_token (parser->lexer);
   40620                 :         267 :           old_linear_modifier = true;
   40621                 :             :         }
   40622                 :             :       else
   40623                 :             :         kind = OMP_CLAUSE_LINEAR_DEFAULT;
   40624                 :             :     }
   40625                 :             : 
   40626                 :         267 :   if (kind == OMP_CLAUSE_LINEAR_DEFAULT)
   40627                 :        1561 :     nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list,
   40628                 :             :                                             &colon);
   40629                 :             :   else
   40630                 :             :     {
   40631                 :         267 :       nlist = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINEAR, list);
   40632                 :         267 :       colon = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
   40633                 :         267 :       if (colon)
   40634                 :         227 :         cp_parser_require (parser, CPP_COLON, RT_COLON);
   40635                 :          40 :       else if (!parens.require_close (parser))
   40636                 :           0 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40637                 :             :                                                /*or_comma=*/false,
   40638                 :             :                                                /*consume_paren=*/true);
   40639                 :             :     }
   40640                 :             : 
   40641                 :        1828 :   if (colon)
   40642                 :             :     {
   40643                 :        1349 :       bool has_modifiers = false;
   40644                 :        1349 :       if (kind == OMP_CLAUSE_LINEAR_DEFAULT
   40645                 :        1349 :           && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   40646                 :             :         {
   40647                 :         258 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40648                 :         258 :           const char *p = IDENTIFIER_POINTER (id);
   40649                 :         258 :           size_t pos = 0;
   40650                 :         258 :           if (strcmp ("ref", p) == 0
   40651                 :         242 :               || strcmp ("val", p) == 0
   40652                 :         208 :               || strcmp ("uval", p) == 0)
   40653                 :             :             pos = 2;
   40654                 :         194 :           else if (strcmp ("step", p) == 0
   40655                 :         194 :                    && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
   40656                 :             :             {
   40657                 :          85 :               pos = cp_parser_skip_balanced_tokens (parser, 2);
   40658                 :          85 :               if (pos == 2)
   40659                 :             :                 pos = 0;
   40660                 :             :             }
   40661                 :          85 :           if (pos != 0
   40662                 :         149 :               && (cp_lexer_nth_token_is (parser->lexer, pos, CPP_COMMA)
   40663                 :          72 :                   || cp_lexer_nth_token_is (parser->lexer, pos,
   40664                 :             :                                             CPP_CLOSE_PAREN)))
   40665                 :             :             has_modifiers = true;
   40666                 :             :         }
   40667                 :             : 
   40668                 :        1221 :       step = NULL_TREE;
   40669                 :             :       if (has_modifiers)
   40670                 :             :         {
   40671                 :         205 :           while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   40672                 :             :             {
   40673                 :         205 :               tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40674                 :         205 :               const char *p = IDENTIFIER_POINTER (id);
   40675                 :         205 :               enum omp_clause_linear_kind nkind = OMP_CLAUSE_LINEAR_DEFAULT;
   40676                 :         205 :               if (strcmp ("ref", p) == 0)
   40677                 :             :                 nkind = OMP_CLAUSE_LINEAR_REF;
   40678                 :         184 :               else if (strcmp ("val", p) == 0)
   40679                 :             :                 nkind = OMP_CLAUSE_LINEAR_VAL;
   40680                 :         139 :               else if (strcmp ("uval", p) == 0)
   40681                 :             :                 nkind = OMP_CLAUSE_LINEAR_UVAL;
   40682                 :         118 :               if (nkind != OMP_CLAUSE_LINEAR_DEFAULT)
   40683                 :             :                 {
   40684                 :          87 :                   if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
   40685                 :           0 :                     error_at (cp_lexer_peek_token (parser->lexer)->location,
   40686                 :             :                               "multiple linear modifiers");
   40687                 :          87 :                   kind = nkind;
   40688                 :          87 :                   cp_lexer_consume_token (parser->lexer);
   40689                 :             :                 }
   40690                 :         118 :               else if (strcmp ("step", p) == 0)
   40691                 :             :                 {
   40692                 :         118 :                   location_t step_loc
   40693                 :         118 :                     = cp_lexer_peek_token (parser->lexer)->location;
   40694                 :         118 :                   cp_lexer_consume_token (parser->lexer);
   40695                 :         118 :                   matching_parens parens2;
   40696                 :         118 :                   if (parens2.require_open (parser))
   40697                 :             :                     {
   40698                 :         118 :                       if (step)
   40699                 :           0 :                         error_at (step_loc, "multiple %<step%> modifiers");
   40700                 :         118 :                       if (declare_simd
   40701                 :          28 :                           && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   40702                 :         125 :                           && cp_lexer_nth_token_is (parser->lexer, 2,
   40703                 :             :                                                     CPP_CLOSE_PAREN))
   40704                 :             :                         {
   40705                 :           7 :                           cp_token *token
   40706                 :           7 :                             = cp_lexer_peek_token (parser->lexer);
   40707                 :           7 :                           location_t tok_loc = token->location;
   40708                 :           7 :                           cp_parser_parse_tentatively (parser);
   40709                 :           7 :                           step = cp_parser_id_expression (parser, false, true,
   40710                 :             :                                                           NULL, false, false);
   40711                 :           7 :                           if (step != error_mark_node)
   40712                 :           7 :                             step = cp_parser_lookup_name_simple (parser, step,
   40713                 :             :                                                                  tok_loc);
   40714                 :           7 :                           if (step == error_mark_node)
   40715                 :             :                             {
   40716                 :           0 :                               step = NULL_TREE;
   40717                 :           0 :                               cp_parser_abort_tentative_parse (parser);
   40718                 :             :                             }
   40719                 :           7 :                           else if (!cp_parser_parse_definitely (parser))
   40720                 :             :                             step = NULL_TREE;
   40721                 :             :                         }
   40722                 :         118 :                       if (!step)
   40723                 :         111 :                         step = cp_parser_assignment_expression (parser);
   40724                 :         118 :                       if (!parens2.require_close (parser))
   40725                 :           4 :                         cp_parser_skip_to_closing_parenthesis (parser, true,
   40726                 :             :                                                                false, true);
   40727                 :             :                     }
   40728                 :             :                   else
   40729                 :             :                     break;
   40730                 :             :                 }
   40731                 :             :               else
   40732                 :             :                 break;
   40733                 :         205 :               if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   40734                 :             :                 {
   40735                 :          77 :                   cp_lexer_consume_token (parser->lexer);
   40736                 :          77 :                   continue;
   40737                 :             :                 }
   40738                 :             :               break;
   40739                 :             :             }
   40740                 :         128 :           if (!step)
   40741                 :          10 :             step = integer_one_node;
   40742                 :             :         }
   40743                 :        1221 :       else if (declare_simd
   40744                 :         508 :                && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   40745                 :        1328 :                && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
   40746                 :             :         {
   40747                 :          90 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   40748                 :          90 :           cp_parser_parse_tentatively (parser);
   40749                 :          90 :           step = cp_parser_id_expression (parser, /*template_p=*/false,
   40750                 :             :                                           /*check_dependency_p=*/true,
   40751                 :             :                                           /*template_p=*/NULL,
   40752                 :             :                                           /*declarator_p=*/false,
   40753                 :             :                                           /*optional_p=*/false);
   40754                 :          90 :           if (step != error_mark_node)
   40755                 :          90 :             step = cp_parser_lookup_name_simple (parser, step, token->location);
   40756                 :          90 :           if (step == error_mark_node)
   40757                 :             :             {
   40758                 :           0 :               step = NULL_TREE;
   40759                 :           0 :               cp_parser_abort_tentative_parse (parser);
   40760                 :             :             }
   40761                 :          90 :           else if (!cp_parser_parse_definitely (parser))
   40762                 :             :             step = NULL_TREE;
   40763                 :             :         }
   40764                 :         100 :       if (!step)
   40765                 :        1131 :         step = cp_parser_assignment_expression (parser);
   40766                 :             : 
   40767                 :        1349 :       if (!parens.require_close (parser))
   40768                 :           4 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40769                 :             :                                                /*or_comma=*/false,
   40770                 :             :                                                /*consume_paren=*/true);
   40771                 :             : 
   40772                 :        1349 :       if (step == error_mark_node)
   40773                 :             :         return list;
   40774                 :             :     }
   40775                 :             : 
   40776                 :        3684 :   for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   40777                 :             :     {
   40778                 :        1872 :       OMP_CLAUSE_LINEAR_STEP (c) = step;
   40779                 :        1872 :       OMP_CLAUSE_LINEAR_KIND (c) = kind;
   40780                 :        1872 :       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
   40781                 :             :     }
   40782                 :             : 
   40783                 :             :   return nlist;
   40784                 :             : }
   40785                 :             : 
   40786                 :             : /* OpenMP 4.0:
   40787                 :             :    safelen ( constant-expression )  */
   40788                 :             : 
   40789                 :             : static tree
   40790                 :         561 : cp_parser_omp_clause_safelen (cp_parser *parser, tree list,
   40791                 :             :                               location_t location)
   40792                 :             : {
   40793                 :         561 :   tree t, c;
   40794                 :             : 
   40795                 :         561 :   matching_parens parens;
   40796                 :         561 :   if (!parens.require_open (parser))
   40797                 :             :     return list;
   40798                 :             : 
   40799                 :         561 :   t = cp_parser_constant_expression (parser);
   40800                 :             : 
   40801                 :         561 :   if (t == error_mark_node
   40802                 :        1122 :       || !parens.require_close (parser))
   40803                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40804                 :             :                                            /*or_comma=*/false,
   40805                 :             :                                            /*consume_paren=*/true);
   40806                 :             : 
   40807                 :         561 :   check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen", location);
   40808                 :             : 
   40809                 :         561 :   c = build_omp_clause (location, OMP_CLAUSE_SAFELEN);
   40810                 :         561 :   OMP_CLAUSE_SAFELEN_EXPR (c) = t;
   40811                 :         561 :   OMP_CLAUSE_CHAIN (c) = list;
   40812                 :             : 
   40813                 :         561 :   return c;
   40814                 :             : }
   40815                 :             : 
   40816                 :             : /* OpenMP 4.0:
   40817                 :             :    simdlen ( constant-expression )  */
   40818                 :             : 
   40819                 :             : static tree
   40820                 :         909 : cp_parser_omp_clause_simdlen (cp_parser *parser, tree list,
   40821                 :             :                               location_t location)
   40822                 :             : {
   40823                 :         909 :   tree t, c;
   40824                 :             : 
   40825                 :         909 :   matching_parens parens;
   40826                 :         909 :   if (!parens.require_open (parser))
   40827                 :             :     return list;
   40828                 :             : 
   40829                 :         909 :   t = cp_parser_constant_expression (parser);
   40830                 :             : 
   40831                 :         909 :   if (t == error_mark_node
   40832                 :        1818 :       || !parens.require_close (parser))
   40833                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40834                 :             :                                            /*or_comma=*/false,
   40835                 :             :                                            /*consume_paren=*/true);
   40836                 :             : 
   40837                 :         909 :   check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen", location);
   40838                 :             : 
   40839                 :         909 :   c = build_omp_clause (location, OMP_CLAUSE_SIMDLEN);
   40840                 :         909 :   OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
   40841                 :         909 :   OMP_CLAUSE_CHAIN (c) = list;
   40842                 :             : 
   40843                 :         909 :   return c;
   40844                 :             : }
   40845                 :             : 
   40846                 :             : /* OpenMP 4.5:
   40847                 :             :    vec:
   40848                 :             :      identifier [+/- integer]
   40849                 :             :      vec , identifier [+/- integer]
   40850                 :             : */
   40851                 :             : 
   40852                 :             : static tree
   40853                 :         384 : cp_parser_omp_clause_doacross_sink (cp_parser *parser, location_t clause_loc,
   40854                 :             :                                     tree list, bool depend_p)
   40855                 :             : {
   40856                 :         384 :   tree vec = NULL;
   40857                 :             : 
   40858                 :         384 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
   40859                 :             :     {
   40860                 :           0 :       cp_parser_error (parser, "expected identifier");
   40861                 :           0 :       return list;
   40862                 :             :     }
   40863                 :             : 
   40864                 :         384 :   if (!depend_p)
   40865                 :             :     {
   40866                 :         128 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   40867                 :         128 :       if (strcmp (IDENTIFIER_POINTER (id), "omp_cur_iteration") == 0
   40868                 :          64 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_MINUS)
   40869                 :          56 :           && cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER)
   40870                 :         180 :           && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN))
   40871                 :             :         {
   40872                 :          52 :           tree val = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value;
   40873                 :          52 :           if (integer_onep (val))
   40874                 :             :             {
   40875                 :          52 :               cp_lexer_consume_token (parser->lexer);
   40876                 :          52 :               cp_lexer_consume_token (parser->lexer);
   40877                 :          52 :               cp_lexer_consume_token (parser->lexer);
   40878                 :          52 :               tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
   40879                 :          52 :               OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
   40880                 :          52 :               OMP_CLAUSE_CHAIN (u) = list;
   40881                 :          52 :               return u;
   40882                 :             :             }
   40883                 :             :         }
   40884                 :             :     }
   40885                 :             : 
   40886                 :         480 :   while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   40887                 :             :     {
   40888                 :         480 :       location_t id_loc = cp_lexer_peek_token (parser->lexer)->location;
   40889                 :         480 :       tree t, identifier = cp_parser_identifier (parser);
   40890                 :         480 :       tree addend = NULL;
   40891                 :             : 
   40892                 :         480 :       if (identifier == error_mark_node)
   40893                 :             :         t = error_mark_node;
   40894                 :             :       else
   40895                 :             :         {
   40896                 :         480 :           t = cp_parser_lookup_name_simple
   40897                 :         960 :                 (parser, identifier,
   40898                 :         480 :                  cp_lexer_peek_token (parser->lexer)->location);
   40899                 :         480 :           if (t == error_mark_node)
   40900                 :          24 :             cp_parser_name_lookup_error (parser, identifier, t, NLE_NULL,
   40901                 :             :                                          id_loc);
   40902                 :             :         }
   40903                 :             : 
   40904                 :         480 :       bool neg = false;
   40905                 :         480 :       if (cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
   40906                 :             :         neg = true;
   40907                 :         122 :       else if (!cp_lexer_next_token_is (parser->lexer, CPP_PLUS))
   40908                 :             :         {
   40909                 :          42 :           addend = integer_zero_node;
   40910                 :          42 :           goto add_to_vector;
   40911                 :             :         }
   40912                 :         438 :       cp_lexer_consume_token (parser->lexer);
   40913                 :             : 
   40914                 :         438 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER))
   40915                 :             :         {
   40916                 :           4 :           cp_parser_error (parser, "expected integer");
   40917                 :           4 :           return list;
   40918                 :             :         }
   40919                 :             : 
   40920                 :         434 :       addend = cp_lexer_peek_token (parser->lexer)->u.value;
   40921                 :         434 :       if (TREE_CODE (addend) != INTEGER_CST)
   40922                 :             :         {
   40923                 :           0 :           cp_parser_error (parser, "expected integer");
   40924                 :           0 :           return list;
   40925                 :             :         }
   40926                 :         434 :       cp_lexer_consume_token (parser->lexer);
   40927                 :             : 
   40928                 :         476 :     add_to_vector:
   40929                 :         476 :       if (t != error_mark_node)
   40930                 :             :         {
   40931                 :         456 :           vec = tree_cons (addend, t, vec);
   40932                 :         456 :           if (neg)
   40933                 :         346 :             OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
   40934                 :             :         }
   40935                 :             : 
   40936                 :         476 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
   40937                 :         476 :           || !cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   40938                 :             :         break;
   40939                 :             : 
   40940                 :         148 :       cp_lexer_consume_token (parser->lexer);
   40941                 :             :     }
   40942                 :             : 
   40943                 :         328 :   if (vec)
   40944                 :             :     {
   40945                 :         312 :       tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
   40946                 :         312 :       OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
   40947                 :         312 :       OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
   40948                 :         312 :       OMP_CLAUSE_DECL (u) = nreverse (vec);
   40949                 :         312 :       OMP_CLAUSE_CHAIN (u) = list;
   40950                 :         312 :       return u;
   40951                 :             :     }
   40952                 :             :   return list;
   40953                 :             : }
   40954                 :             : 
   40955                 :             : /* OpenMP 5.0:
   40956                 :             :    detach ( event-handle ) */
   40957                 :             : 
   40958                 :             : static tree
   40959                 :          77 : cp_parser_omp_clause_detach (cp_parser *parser, tree list)
   40960                 :             : {
   40961                 :          77 :   matching_parens parens;
   40962                 :             : 
   40963                 :          77 :   if (!parens.require_open (parser))
   40964                 :             :     return list;
   40965                 :             : 
   40966                 :          77 :   cp_token *token;
   40967                 :          77 :   tree name, decl;
   40968                 :             : 
   40969                 :          77 :   token = cp_lexer_peek_token (parser->lexer);
   40970                 :          77 :   name = cp_parser_id_expression (parser, /*template_p=*/false,
   40971                 :             :                                           /*check_dependency_p=*/true,
   40972                 :             :                                           /*template_p=*/NULL,
   40973                 :             :                                           /*declarator_p=*/false,
   40974                 :             :                                           /*optional_p=*/false);
   40975                 :          77 :   if (name == error_mark_node)
   40976                 :             :     decl = error_mark_node;
   40977                 :             :   else
   40978                 :             :     {
   40979                 :          73 :       if (identifier_p (name))
   40980                 :          73 :         decl = cp_parser_lookup_name_simple (parser, name, token->location);
   40981                 :             :       else
   40982                 :             :         decl = name;
   40983                 :          73 :       if (decl == error_mark_node)
   40984                 :           0 :         cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
   40985                 :             :                                      token->location);
   40986                 :             :     }
   40987                 :             : 
   40988                 :          77 :   if (decl == error_mark_node
   40989                 :         150 :       || !parens.require_close (parser))
   40990                 :           4 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   40991                 :             :                                            /*or_comma=*/false,
   40992                 :             :                                            /*consume_paren=*/true);
   40993                 :             : 
   40994                 :          77 :   tree u = build_omp_clause (token->location, OMP_CLAUSE_DETACH);
   40995                 :          77 :   OMP_CLAUSE_DECL (u) = decl;
   40996                 :          77 :   OMP_CLAUSE_CHAIN (u) = list;
   40997                 :             : 
   40998                 :          77 :   return u;
   40999                 :             : }
   41000                 :             : 
   41001                 :             : /* OpenMP 5.0:
   41002                 :             :    iterators ( iterators-definition )
   41003                 :             : 
   41004                 :             :    iterators-definition:
   41005                 :             :      iterator-specifier
   41006                 :             :      iterator-specifier , iterators-definition
   41007                 :             : 
   41008                 :             :    iterator-specifier:
   41009                 :             :      identifier = range-specification
   41010                 :             :      iterator-type identifier = range-specification
   41011                 :             : 
   41012                 :             :    range-specification:
   41013                 :             :      begin : end
   41014                 :             :      begin : end : step  */
   41015                 :             : 
   41016                 :             : static tree
   41017                 :         618 : cp_parser_omp_iterators (cp_parser *parser)
   41018                 :             : {
   41019                 :         618 :   tree ret = NULL_TREE, *last = &ret;
   41020                 :         618 :   cp_lexer_consume_token (parser->lexer);
   41021                 :             : 
   41022                 :         618 :   matching_parens parens;
   41023                 :         618 :   if (!parens.require_open (parser))
   41024                 :           8 :     return error_mark_node;
   41025                 :             : 
   41026                 :         610 :   bool saved_colon_corrects_to_scope_p
   41027                 :             :     = parser->colon_corrects_to_scope_p;
   41028                 :         610 :   bool saved_colon_doesnt_start_class_def_p
   41029                 :             :     = parser->colon_doesnt_start_class_def_p;
   41030                 :             : 
   41031                 :         884 :   do
   41032                 :             :     {
   41033                 :         747 :       tree iter_type;
   41034                 :         747 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   41035                 :         747 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_EQ))
   41036                 :         401 :         iter_type = integer_type_node;
   41037                 :             :       else
   41038                 :             :         {
   41039                 :         346 :           const char *saved_message
   41040                 :             :             = parser->type_definition_forbidden_message;
   41041                 :         346 :           parser->type_definition_forbidden_message
   41042                 :         346 :             = G_("types may not be defined in iterator type");
   41043                 :             : 
   41044                 :         346 :           iter_type = cp_parser_type_id (parser);
   41045                 :             : 
   41046                 :         346 :           parser->type_definition_forbidden_message = saved_message;
   41047                 :             :         }
   41048                 :             : 
   41049                 :         747 :       location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   41050                 :         747 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
   41051                 :             :         {
   41052                 :          60 :           cp_parser_error (parser, "expected identifier");
   41053                 :          60 :           break;
   41054                 :             :         }
   41055                 :             : 
   41056                 :         687 :       tree id = cp_parser_identifier (parser);
   41057                 :         687 :       if (id == error_mark_node)
   41058                 :             :         break;
   41059                 :             : 
   41060                 :         687 :       if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   41061                 :             :         break;
   41062                 :             : 
   41063                 :         687 :       parser->colon_corrects_to_scope_p = false;
   41064                 :         687 :       parser->colon_doesnt_start_class_def_p = true;
   41065                 :         687 :       tree begin = cp_parser_assignment_expression (parser);
   41066                 :             : 
   41067                 :         687 :       if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   41068                 :             :         break;
   41069                 :             : 
   41070                 :         675 :       tree end = cp_parser_assignment_expression (parser);
   41071                 :             : 
   41072                 :         675 :       tree step = integer_one_node;
   41073                 :         675 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   41074                 :             :         {
   41075                 :         338 :           cp_lexer_consume_token (parser->lexer);
   41076                 :         338 :           step = cp_parser_assignment_expression (parser);
   41077                 :             :         }
   41078                 :             : 
   41079                 :         675 :       tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
   41080                 :         675 :       DECL_ARTIFICIAL (iter_var) = 1;
   41081                 :         675 :       DECL_CONTEXT (iter_var) = current_function_decl;
   41082                 :         675 :       pushdecl (iter_var);
   41083                 :             : 
   41084                 :         675 :       *last = make_tree_vec (6);
   41085                 :         675 :       TREE_VEC_ELT (*last, 0) = iter_var;
   41086                 :         675 :       TREE_VEC_ELT (*last, 1) = begin;
   41087                 :         675 :       TREE_VEC_ELT (*last, 2) = end;
   41088                 :         675 :       TREE_VEC_ELT (*last, 3) = step;
   41089                 :         675 :       last = &TREE_CHAIN (*last);
   41090                 :             : 
   41091                 :         675 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   41092                 :             :         {
   41093                 :         137 :           cp_lexer_consume_token (parser->lexer);
   41094                 :         137 :           continue;
   41095                 :             :         }
   41096                 :             :       break;
   41097                 :         137 :     }
   41098                 :             :   while (1);
   41099                 :             : 
   41100                 :         610 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   41101                 :         610 :   parser->colon_doesnt_start_class_def_p
   41102                 :         610 :     = saved_colon_doesnt_start_class_def_p;
   41103                 :             : 
   41104                 :         610 :   if (!parens.require_close (parser))
   41105                 :          84 :     cp_parser_skip_to_closing_parenthesis (parser,
   41106                 :             :                                            /*recovering=*/true,
   41107                 :             :                                            /*or_comma=*/false,
   41108                 :             :                                            /*consume_paren=*/true);
   41109                 :             : 
   41110                 :         610 :   return ret ? ret : error_mark_node;
   41111                 :             : }
   41112                 :             : 
   41113                 :             : /* OpenMP 5.0:
   41114                 :             :    affinity ( [aff-modifier :] variable-list )
   41115                 :             :    aff-modifier:
   41116                 :             :      iterator ( iterators-definition )  */
   41117                 :             : 
   41118                 :             : static tree
   41119                 :         616 : cp_parser_omp_clause_affinity (cp_parser *parser, tree list)
   41120                 :             : {
   41121                 :         616 :   tree nlist, c, iterators = NULL_TREE;
   41122                 :             : 
   41123                 :         616 :   matching_parens parens;
   41124                 :         616 :   if (!parens.require_open (parser))
   41125                 :             :     return list;
   41126                 :             : 
   41127                 :         616 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   41128                 :             :     {
   41129                 :         584 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   41130                 :         584 :       const char *p = IDENTIFIER_POINTER (id);
   41131                 :         584 :       bool parse_iter = ((strcmp ("iterator", p) == 0)
   41132                 :         584 :                          && (cp_lexer_nth_token_is (parser->lexer, 2,
   41133                 :         208 :                                                     CPP_OPEN_PAREN)));
   41134                 :         208 :       if (parse_iter)
   41135                 :             :         {
   41136                 :         208 :           size_t n = cp_parser_skip_balanced_tokens (parser, 2);
   41137                 :         208 :           parse_iter = cp_lexer_nth_token_is (parser->lexer, n, CPP_COLON);
   41138                 :             :         }
   41139                 :         208 :       if (parse_iter)
   41140                 :             :         {
   41141                 :         196 :           begin_scope (sk_omp, NULL);
   41142                 :         196 :           iterators = cp_parser_omp_iterators (parser);
   41143                 :         196 :           if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   41144                 :             :             {
   41145                 :           0 :               if (iterators)
   41146                 :           0 :                 poplevel (0, 1, 0);
   41147                 :           0 :               cp_parser_skip_to_closing_parenthesis (parser,
   41148                 :             :                                                      /*recovering=*/true,
   41149                 :             :                                                      /*or_comma=*/false,
   41150                 :             :                                                      /*consume_paren=*/true);
   41151                 :           0 :               return list;
   41152                 :             :             }
   41153                 :             :         }
   41154                 :             :     }
   41155                 :         616 :   nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_AFFINITY,
   41156                 :             :                                           list, NULL);
   41157                 :         616 :   if (iterators)
   41158                 :             :     {
   41159                 :         196 :       tree block = poplevel (1, 1, 0);
   41160                 :         196 :       if (iterators != error_mark_node)
   41161                 :             :         {
   41162                 :         180 :           TREE_VEC_ELT (iterators, 5) = block;
   41163                 :         412 :           for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   41164                 :         464 :             OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
   41165                 :         232 :                                                    OMP_CLAUSE_DECL (c));
   41166                 :             :         }
   41167                 :             :     }
   41168                 :             :   return nlist;
   41169                 :             : }
   41170                 :             : 
   41171                 :             : /* OpenMP 4.0:
   41172                 :             :    depend ( depend-kind : variable-list )
   41173                 :             : 
   41174                 :             :    depend-kind:
   41175                 :             :      in | out | inout
   41176                 :             : 
   41177                 :             :    OpenMP 4.5:
   41178                 :             :    depend ( source )
   41179                 :             : 
   41180                 :             :    depend ( sink : vec )
   41181                 :             : 
   41182                 :             :    OpenMP 5.0:
   41183                 :             :    depend ( depend-modifier , depend-kind: variable-list )
   41184                 :             : 
   41185                 :             :    depend-kind:
   41186                 :             :      in | out | inout | mutexinoutset | depobj
   41187                 :             : 
   41188                 :             :    depend-modifier:
   41189                 :             :      iterator ( iterators-definition )  */
   41190                 :             : 
   41191                 :             : static tree
   41192                 :        2199 : cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
   41193                 :             : {
   41194                 :        2199 :   tree nlist, c, iterators = NULL_TREE;
   41195                 :        2199 :   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
   41196                 :        2199 :   enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
   41197                 :             : 
   41198                 :        2199 :   matching_parens parens;
   41199                 :        2199 :   if (!parens.require_open (parser))
   41200                 :             :     return list;
   41201                 :             : 
   41202                 :        3043 :   do
   41203                 :             :     {
   41204                 :        2621 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
   41205                 :           0 :         goto invalid_kind;
   41206                 :             : 
   41207                 :        2621 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   41208                 :        2621 :       const char *p = IDENTIFIER_POINTER (id);
   41209                 :             : 
   41210                 :        2621 :       if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
   41211                 :             :         {
   41212                 :         422 :           begin_scope (sk_omp, NULL);
   41213                 :         422 :           iterators = cp_parser_omp_iterators (parser);
   41214                 :         422 :           cp_parser_require (parser, CPP_COMMA, RT_COMMA);
   41215                 :         422 :           continue;
   41216                 :             :         }
   41217                 :        2199 :       if (strcmp ("in", p) == 0)
   41218                 :             :         kind = OMP_CLAUSE_DEPEND_IN;
   41219                 :        1540 :       else if (strcmp ("inout", p) == 0)
   41220                 :             :         kind = OMP_CLAUSE_DEPEND_INOUT;
   41221                 :         951 :       else if (strcmp ("inoutset", p) == 0)
   41222                 :             :         kind = OMP_CLAUSE_DEPEND_INOUTSET;
   41223                 :         931 :       else if (strcmp ("mutexinoutset", p) == 0)
   41224                 :             :         kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
   41225                 :         890 :       else if (strcmp ("out", p) == 0)
   41226                 :             :         kind = OMP_CLAUSE_DEPEND_OUT;
   41227                 :         594 :       else if (strcmp ("depobj", p) == 0)
   41228                 :             :         kind = OMP_CLAUSE_DEPEND_DEPOBJ;
   41229                 :         510 :       else if (strcmp ("sink", p) == 0)
   41230                 :             :         dkind = OMP_CLAUSE_DOACROSS_SINK;
   41231                 :         254 :       else if (strcmp ("source", p) == 0)
   41232                 :             :         dkind = OMP_CLAUSE_DOACROSS_SOURCE;
   41233                 :             :       else
   41234                 :          16 :         goto invalid_kind;
   41235                 :        2183 :       break;
   41236                 :         422 :     }
   41237                 :             :   while (1);
   41238                 :             : 
   41239                 :        2183 :   cp_lexer_consume_token (parser->lexer);
   41240                 :             : 
   41241                 :        2183 :   if (iterators
   41242                 :        2183 :       && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
   41243                 :        2183 :           || dkind == OMP_CLAUSE_DOACROSS_SINK))
   41244                 :             :     {
   41245                 :          16 :       poplevel (0, 1, 0);
   41246                 :          16 :       error_at (loc, "%<iterator%> modifier incompatible with %qs",
   41247                 :             :                 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
   41248                 :          16 :       iterators = NULL_TREE;
   41249                 :             :     }
   41250                 :             : 
   41251                 :        2183 :   if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
   41252                 :             :     {
   41253                 :         238 :       c = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
   41254                 :         238 :       OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
   41255                 :         238 :       OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
   41256                 :         238 :       OMP_CLAUSE_DECL (c) = NULL_TREE;
   41257                 :         238 :       OMP_CLAUSE_CHAIN (c) = list;
   41258                 :         238 :       if (!parens.require_close (parser))
   41259                 :           0 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41260                 :             :                                                /*or_comma=*/false,
   41261                 :             :                                                /*consume_paren=*/true);
   41262                 :         238 :       return c;
   41263                 :             :     }
   41264                 :             : 
   41265                 :        1945 :   if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   41266                 :           0 :     goto resync_fail;
   41267                 :             : 
   41268                 :        1945 :   if (dkind == OMP_CLAUSE_DOACROSS_SINK)
   41269                 :             :     {
   41270                 :         256 :       nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, true);
   41271                 :         256 :       if (!parens.require_close (parser))
   41272                 :           4 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41273                 :             :                                                /*or_comma=*/false,
   41274                 :             :                                                /*consume_paren=*/true);
   41275                 :             :     }
   41276                 :             :   else
   41277                 :             :     {
   41278                 :        1689 :       nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_DEPEND,
   41279                 :             :                                               list, NULL);
   41280                 :             : 
   41281                 :        1689 :       if (iterators)
   41282                 :             :         {
   41283                 :         390 :           tree block = poplevel (1, 1, 0);
   41284                 :         390 :           if (iterators == error_mark_node)
   41285                 :             :             iterators = NULL_TREE;
   41286                 :             :           else
   41287                 :         350 :             TREE_VEC_ELT (iterators, 5) = block;
   41288                 :             :         }
   41289                 :             : 
   41290                 :        3467 :       for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   41291                 :             :         {
   41292                 :        1778 :           OMP_CLAUSE_DEPEND_KIND (c) = kind;
   41293                 :        1778 :           if (iterators)
   41294                 :         802 :             OMP_CLAUSE_DECL (c)
   41295                 :         802 :               = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
   41296                 :             :         }
   41297                 :             :     }
   41298                 :             :   return nlist;
   41299                 :             : 
   41300                 :          16 :  invalid_kind:
   41301                 :          16 :   cp_parser_error (parser, "invalid depend kind");
   41302                 :          16 :  resync_fail:
   41303                 :          16 :   if (iterators)
   41304                 :          16 :     poplevel (0, 1, 0);
   41305                 :          16 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41306                 :             :                                          /*or_comma=*/false,
   41307                 :             :                                          /*consume_paren=*/true);
   41308                 :          16 :   return list;
   41309                 :             : }
   41310                 :             : 
   41311                 :             : /* OpenMP 5.2:
   41312                 :             :    doacross ( source : )
   41313                 :             :    doacross ( source : omp_cur_iteration )
   41314                 :             : 
   41315                 :             :    doacross ( sink : vec )
   41316                 :             :    doacross ( sink : omp_cur_iteration - logical_iteration )  */
   41317                 :             : 
   41318                 :             : static tree
   41319                 :         244 : cp_parser_omp_clause_doacross (cp_parser *parser, tree list, location_t loc)
   41320                 :             : {
   41321                 :         244 :   tree nlist;
   41322                 :         244 :   enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
   41323                 :             : 
   41324                 :         244 :   matching_parens parens;
   41325                 :         244 :   if (!parens.require_open (parser))
   41326                 :             :     return list;
   41327                 :             : 
   41328                 :         244 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
   41329                 :             :     {
   41330                 :           0 :     invalid_kind:
   41331                 :           0 :       cp_parser_error (parser, "invalid doacross kind");
   41332                 :          16 :     resync_fail:
   41333                 :          16 :       cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41334                 :             :                                              /*or_comma=*/false,
   41335                 :             :                                              /*consume_paren=*/true);
   41336                 :          16 :       return list;
   41337                 :             :     }
   41338                 :             : 
   41339                 :         244 :   tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   41340                 :         244 :   const char *p = IDENTIFIER_POINTER (id);
   41341                 :             : 
   41342                 :         244 :   if (strcmp ("sink", p) == 0)
   41343                 :             :     kind = OMP_CLAUSE_DOACROSS_SINK;
   41344                 :         108 :   else if (strcmp ("source", p) == 0)
   41345                 :             :     kind = OMP_CLAUSE_DOACROSS_SOURCE;
   41346                 :             :   else
   41347                 :           0 :     goto invalid_kind;
   41348                 :             : 
   41349                 :         244 :   cp_lexer_consume_token (parser->lexer);
   41350                 :             : 
   41351                 :         244 :   if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   41352                 :          16 :     goto resync_fail;
   41353                 :             : 
   41354                 :         228 :   if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
   41355                 :             :     {
   41356                 :         100 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   41357                 :             :         {
   41358                 :          44 :           id = cp_lexer_peek_token (parser->lexer)->u.value;
   41359                 :          44 :           p = IDENTIFIER_POINTER (id);
   41360                 :          44 :           if (strcmp (p, "omp_cur_iteration") == 0)
   41361                 :          36 :             cp_lexer_consume_token (parser->lexer);
   41362                 :             :         }
   41363                 :         100 :       nlist = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
   41364                 :         100 :       OMP_CLAUSE_DOACROSS_KIND (nlist) = OMP_CLAUSE_DOACROSS_SOURCE;
   41365                 :         100 :       OMP_CLAUSE_DECL (nlist) = NULL_TREE;
   41366                 :         100 :       OMP_CLAUSE_CHAIN (nlist) = list;
   41367                 :             :     }
   41368                 :             :   else
   41369                 :         128 :     nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, false);
   41370                 :             : 
   41371                 :         228 :   if (!parens.require_close (parser))
   41372                 :          12 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41373                 :             :                                            /*or_comma=*/false,
   41374                 :             :                                            /*consume_paren=*/true);
   41375                 :             :   return nlist;
   41376                 :             : }
   41377                 :             : 
   41378                 :             : /* OpenMP 4.0:
   41379                 :             :    from ( variable-list )
   41380                 :             :    to ( variable-list )
   41381                 :             : 
   41382                 :             :    OpenMP 5.1:
   41383                 :             :    from ( [present :] variable-list )
   41384                 :             :    to ( [present :] variable-list ) */
   41385                 :             : 
   41386                 :             : static tree
   41387                 :        2990 : cp_parser_omp_clause_from_to (cp_parser *parser, enum omp_clause_code kind,
   41388                 :             :                               tree list)
   41389                 :             : {
   41390                 :        2990 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   41391                 :             :     return list;
   41392                 :             : 
   41393                 :        2990 :   bool present = false;
   41394                 :        2990 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   41395                 :             : 
   41396                 :        2990 :   if (token->type == CPP_NAME
   41397                 :        2956 :       && strcmp (IDENTIFIER_POINTER (token->u.value), "present") == 0
   41398                 :        3001 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
   41399                 :             :     {
   41400                 :          11 :       present = true;
   41401                 :          11 :       cp_lexer_consume_token (parser->lexer);
   41402                 :          11 :       cp_lexer_consume_token (parser->lexer);
   41403                 :             :     }
   41404                 :             : 
   41405                 :        2990 :   tree nl = cp_parser_omp_var_list_no_open (parser, kind, list, NULL, true);
   41406                 :        2990 :   if (present)
   41407                 :          22 :     for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   41408                 :          11 :       OMP_CLAUSE_MOTION_PRESENT (c) = 1;
   41409                 :             : 
   41410                 :             :   return nl;
   41411                 :             : }
   41412                 :             : 
   41413                 :             : /* OpenMP 4.0:
   41414                 :             :    map ( map-kind : variable-list )
   41415                 :             :    map ( variable-list )
   41416                 :             : 
   41417                 :             :    map-kind:
   41418                 :             :      alloc | to | from | tofrom
   41419                 :             : 
   41420                 :             :    OpenMP 4.5:
   41421                 :             :    map-kind:
   41422                 :             :      alloc | to | from | tofrom | release | delete
   41423                 :             : 
   41424                 :             :    map ( always [,] map-kind: variable-list )
   41425                 :             : 
   41426                 :             :    OpenMP 5.0:
   41427                 :             :    map ( [map-type-modifier[,] ...] map-kind: variable-list )
   41428                 :             : 
   41429                 :             :    map-type-modifier:
   41430                 :             :      always | close */
   41431                 :             : 
   41432                 :             : static tree
   41433                 :        4485 : cp_parser_omp_clause_map (cp_parser *parser, tree list)
   41434                 :             : {
   41435                 :        4485 :   tree nlist, c;
   41436                 :        4485 :   enum gomp_map_kind kind = GOMP_MAP_TOFROM;
   41437                 :             : 
   41438                 :        4485 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   41439                 :             :     return list;
   41440                 :             : 
   41441                 :             :   int pos = 1;
   41442                 :        6849 :   int map_kind_pos = 0;
   41443                 :       13698 :   while (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_NAME
   41444                 :        6849 :          || cp_lexer_peek_nth_token (parser->lexer, pos)->keyword == RID_DELETE)
   41445                 :             :     {
   41446                 :        5246 :       if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COLON)
   41447                 :             :         {
   41448                 :             :           map_kind_pos = pos;
   41449                 :             :           break;
   41450                 :             :         }
   41451                 :             : 
   41452                 :        2364 :       if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COMMA)
   41453                 :         599 :         pos++;
   41454                 :        2364 :       pos++;
   41455                 :             :     }
   41456                 :             : 
   41457                 :        4485 :   bool always_modifier = false;
   41458                 :        4485 :   bool close_modifier = false;
   41459                 :        4485 :   bool present_modifier = false;
   41460                 :        5616 :   for (int pos = 1; pos < map_kind_pos; ++pos)
   41461                 :             :     {
   41462                 :        1199 :       cp_token *tok = cp_lexer_peek_token (parser->lexer);
   41463                 :        1199 :       if (tok->type == CPP_COMMA)
   41464                 :             :         {
   41465                 :         483 :           cp_lexer_consume_token (parser->lexer);
   41466                 :         483 :           continue;
   41467                 :             :         }
   41468                 :             : 
   41469                 :         716 :       const char *p = IDENTIFIER_POINTER (tok->u.value);
   41470                 :         716 :       if (strcmp ("always", p) == 0)
   41471                 :             :         {
   41472                 :         266 :           if (always_modifier)
   41473                 :             :             {
   41474                 :          16 :               cp_parser_error (parser, "too many %<always%> modifiers");
   41475                 :          16 :               cp_parser_skip_to_closing_parenthesis (parser,
   41476                 :             :                                                      /*recovering=*/true,
   41477                 :             :                                                      /*or_comma=*/false,
   41478                 :             :                                                      /*consume_paren=*/true);
   41479                 :          16 :               return list;
   41480                 :             :             }
   41481                 :             :           always_modifier = true;
   41482                 :             :         }
   41483                 :         450 :       else if (strcmp ("close", p) == 0)
   41484                 :             :         {
   41485                 :         244 :           if (close_modifier)
   41486                 :             :             {
   41487                 :          16 :               cp_parser_error (parser, "too many %<close%> modifiers");
   41488                 :          16 :               cp_parser_skip_to_closing_parenthesis (parser,
   41489                 :             :                                                      /*recovering=*/true,
   41490                 :             :                                                      /*or_comma=*/false,
   41491                 :             :                                                      /*consume_paren=*/true);
   41492                 :          16 :               return list;
   41493                 :             :             }
   41494                 :             :           close_modifier = true;
   41495                 :             :         }
   41496                 :         206 :       else if (strcmp ("present", p) == 0)
   41497                 :             :         {
   41498                 :         186 :           if (present_modifier)
   41499                 :             :             {
   41500                 :          16 :               cp_parser_error (parser, "too many %<present%> modifiers");
   41501                 :          16 :               cp_parser_skip_to_closing_parenthesis (parser,
   41502                 :             :                                                      /*recovering=*/true,
   41503                 :             :                                                      /*or_comma=*/false,
   41504                 :             :                                                      /*consume_paren=*/true);
   41505                 :          16 :               return list;
   41506                 :             :             }
   41507                 :             :           present_modifier = true;
   41508                 :             :        }
   41509                 :             :       else
   41510                 :             :         {
   41511                 :          20 :           cp_parser_error (parser, "%<map%> clause with map-type modifier other"
   41512                 :             :                                    " than %<always%>, %<close%> or %<present%>");
   41513                 :          20 :           cp_parser_skip_to_closing_parenthesis (parser,
   41514                 :             :                                                  /*recovering=*/true,
   41515                 :             :                                                  /*or_comma=*/false,
   41516                 :             :                                                  /*consume_paren=*/true);
   41517                 :          20 :           return list;
   41518                 :             :         }
   41519                 :             : 
   41520                 :         648 :         cp_lexer_consume_token (parser->lexer);
   41521                 :             :     }
   41522                 :             : 
   41523                 :        4417 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   41524                 :        4417 :       && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
   41525                 :             :     {
   41526                 :        2764 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   41527                 :        2764 :       const char *p = IDENTIFIER_POINTER (id);
   41528                 :        2764 :       int always_present_modifier = always_modifier && present_modifier;
   41529                 :             : 
   41530                 :        2764 :       if (strcmp ("alloc", p) == 0)
   41531                 :         328 :         kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
   41532                 :        2436 :       else if (strcmp ("to", p) == 0)
   41533                 :         932 :         kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
   41534                 :         923 :                 : present_modifier ? GOMP_MAP_PRESENT_TO
   41535                 :         897 :                 : always_modifier ? GOMP_MAP_ALWAYS_TO
   41536                 :             :                 : GOMP_MAP_TO);
   41537                 :        1504 :       else if (strcmp ("from", p) == 0)
   41538                 :         600 :         kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
   41539                 :         583 :                 : present_modifier ? GOMP_MAP_PRESENT_FROM
   41540                 :         571 :                 : always_modifier ? GOMP_MAP_ALWAYS_FROM
   41541                 :             :                 : GOMP_MAP_FROM);
   41542                 :         904 :       else if (strcmp ("tofrom", p) == 0)
   41543                 :         731 :         kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
   41544                 :         715 :                 : present_modifier ? GOMP_MAP_PRESENT_TOFROM
   41545                 :         694 :                 : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
   41546                 :             :                 : GOMP_MAP_TOFROM);
   41547                 :         173 :       else if (strcmp ("release", p) == 0)
   41548                 :             :         kind = GOMP_MAP_RELEASE;
   41549                 :             :       else
   41550                 :             :         {
   41551                 :           0 :           cp_parser_error (parser, "invalid map kind");
   41552                 :           0 :           cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41553                 :             :                                                  /*or_comma=*/false,
   41554                 :             :                                                  /*consume_paren=*/true);
   41555                 :           0 :           return list;
   41556                 :             :         }
   41557                 :        2764 :       cp_lexer_consume_token (parser->lexer);
   41558                 :        2764 :       cp_lexer_consume_token (parser->lexer);
   41559                 :             :     }
   41560                 :        1653 :   else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DELETE)
   41561                 :        1653 :            && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
   41562                 :             :     {
   41563                 :          50 :       kind = GOMP_MAP_DELETE;
   41564                 :          50 :       cp_lexer_consume_token (parser->lexer);
   41565                 :          50 :       cp_lexer_consume_token (parser->lexer);
   41566                 :             :     }
   41567                 :             : 
   41568                 :             :   /* We introduce a scope here so that errors parsing e.g. "always", "close"
   41569                 :             :      tokens do not propagate to later directives that might use them
   41570                 :             :      legally.  */
   41571                 :        4417 :   begin_scope (sk_omp, NULL);
   41572                 :        4417 :   nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list,
   41573                 :             :                                           NULL, true);
   41574                 :        4417 :   finish_scope ();
   41575                 :             : 
   41576                 :       14320 :   for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   41577                 :        5486 :     OMP_CLAUSE_SET_MAP_KIND (c, kind);
   41578                 :             : 
   41579                 :             :   return nlist;
   41580                 :             : }
   41581                 :             : 
   41582                 :             : /* OpenMP 4.0:
   41583                 :             :    device ( expression )
   41584                 :             : 
   41585                 :             :    OpenMP 5.0:
   41586                 :             :    device ( [device-modifier :] integer-expression )
   41587                 :             : 
   41588                 :             :    device-modifier:
   41589                 :             :      ancestor | device_num */
   41590                 :             : 
   41591                 :             : static tree
   41592                 :         675 : cp_parser_omp_clause_device (cp_parser *parser, tree list,
   41593                 :             :                              location_t location)
   41594                 :             : {
   41595                 :         675 :   tree t, c;
   41596                 :         675 :   bool ancestor = false;
   41597                 :             : 
   41598                 :         675 :   matching_parens parens;
   41599                 :         675 :   if (!parens.require_open (parser))
   41600                 :             :     return list;
   41601                 :             : 
   41602                 :         675 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   41603                 :         675 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
   41604                 :             :     {
   41605                 :         139 :       cp_token *tok = cp_lexer_peek_token (parser->lexer);
   41606                 :         139 :       const char *p = IDENTIFIER_POINTER (tok->u.value);
   41607                 :         139 :       if (strcmp ("ancestor", p) == 0)
   41608                 :             :         {
   41609                 :          91 :           ancestor = true;
   41610                 :             : 
   41611                 :             :           /* A requires directive with the reverse_offload clause must be
   41612                 :             :           specified.  */
   41613                 :          91 :           if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
   41614                 :             :             {
   41615                 :           4 :               error_at (tok->location, "%<ancestor%> device modifier not "
   41616                 :             :                                        "preceded by %<requires%> directive "
   41617                 :             :                                        "with %<reverse_offload%> clause");
   41618                 :           4 :               cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
   41619                 :           4 :               return list;
   41620                 :             :             }
   41621                 :             :         }
   41622                 :          48 :       else if (strcmp ("device_num", p) == 0)
   41623                 :             :         ;
   41624                 :             :       else
   41625                 :             :         {
   41626                 :           4 :           error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
   41627                 :           4 :           cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
   41628                 :           4 :           return list;
   41629                 :             :         }
   41630                 :         131 :       cp_lexer_consume_token (parser->lexer);
   41631                 :         131 :       cp_lexer_consume_token (parser->lexer);
   41632                 :             :     }
   41633                 :             : 
   41634                 :         667 :   t = cp_parser_assignment_expression (parser);
   41635                 :             : 
   41636                 :         667 :   if (t == error_mark_node
   41637                 :        1334 :       || !parens.require_close (parser))
   41638                 :           8 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41639                 :             :                                            /*or_comma=*/false,
   41640                 :             :                                            /*consume_paren=*/true);
   41641                 :             : 
   41642                 :         667 :   check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE,
   41643                 :             :                              "device", location);
   41644                 :             : 
   41645                 :         667 :   c = build_omp_clause (location, OMP_CLAUSE_DEVICE);
   41646                 :         667 :   OMP_CLAUSE_DEVICE_ID (c) = t;
   41647                 :         667 :   OMP_CLAUSE_CHAIN (c) = list;
   41648                 :         667 :   OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
   41649                 :             : 
   41650                 :         667 :   return c;
   41651                 :             : }
   41652                 :             : 
   41653                 :             : /* OpenMP 4.0:
   41654                 :             :    dist_schedule ( static )
   41655                 :             :    dist_schedule ( static , expression )  */
   41656                 :             : 
   41657                 :             : static tree
   41658                 :        1927 : cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
   41659                 :             :                                     location_t location)
   41660                 :             : {
   41661                 :        1927 :   tree c, t;
   41662                 :             : 
   41663                 :        1927 :   matching_parens parens;
   41664                 :        1927 :   if (!parens.require_open (parser))
   41665                 :             :     return list;
   41666                 :             : 
   41667                 :        1927 :   c = build_omp_clause (location, OMP_CLAUSE_DIST_SCHEDULE);
   41668                 :             : 
   41669                 :        1927 :   if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC))
   41670                 :           0 :     goto invalid_kind;
   41671                 :        1927 :   cp_lexer_consume_token (parser->lexer);
   41672                 :             : 
   41673                 :        1927 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   41674                 :             :     {
   41675                 :        1899 :       cp_lexer_consume_token (parser->lexer);
   41676                 :             : 
   41677                 :        1899 :       t = cp_parser_assignment_expression (parser);
   41678                 :             : 
   41679                 :        1899 :       if (t == error_mark_node)
   41680                 :           0 :         goto resync_fail;
   41681                 :        1899 :       OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
   41682                 :             : 
   41683                 :        1899 :       if (!parens.require_close (parser))
   41684                 :           4 :         goto resync_fail;
   41685                 :             :     }
   41686                 :          28 :   else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
   41687                 :           0 :     goto resync_fail;
   41688                 :             : 
   41689                 :             :   /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
   41690                 :             :                                 "dist_schedule", location); */
   41691                 :        1923 :   if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
   41692                 :           8 :     warning_at (location, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
   41693                 :        1923 :   OMP_CLAUSE_CHAIN (c) = list;
   41694                 :        1923 :   return c;
   41695                 :             : 
   41696                 :           0 :  invalid_kind:
   41697                 :           0 :   cp_parser_error (parser, "invalid dist_schedule kind");
   41698                 :           4 :  resync_fail:
   41699                 :           4 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41700                 :             :                                          /*or_comma=*/false,
   41701                 :             :                                          /*consume_paren=*/true);
   41702                 :           4 :   return list;
   41703                 :             : }
   41704                 :             : 
   41705                 :             : /* OpenMP 4.0:
   41706                 :             :    proc_bind ( proc-bind-kind )
   41707                 :             : 
   41708                 :             :    proc-bind-kind:
   41709                 :             :      primary | master | close | spread
   41710                 :             :    where OpenMP 5.1 added 'primary' and deprecated the alias 'master'.  */
   41711                 :             : 
   41712                 :             : static tree
   41713                 :         619 : cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
   41714                 :             :                                 location_t location)
   41715                 :             : {
   41716                 :         619 :   tree c;
   41717                 :         619 :   enum omp_clause_proc_bind_kind kind;
   41718                 :             : 
   41719                 :         619 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   41720                 :             :     return list;
   41721                 :             : 
   41722                 :         619 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   41723                 :             :     {
   41724                 :         619 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   41725                 :         619 :       const char *p = IDENTIFIER_POINTER (id);
   41726                 :             : 
   41727                 :         619 :       if (strcmp ("primary", p) == 0)
   41728                 :             :         kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
   41729                 :         615 :       else if (strcmp ("master", p) == 0)
   41730                 :             :         kind = OMP_CLAUSE_PROC_BIND_MASTER;
   41731                 :         569 :       else if (strcmp ("close", p) == 0)
   41732                 :             :         kind = OMP_CLAUSE_PROC_BIND_CLOSE;
   41733                 :         554 :       else if (strcmp ("spread", p) == 0)
   41734                 :             :         kind = OMP_CLAUSE_PROC_BIND_SPREAD;
   41735                 :             :       else
   41736                 :           0 :         goto invalid_kind;
   41737                 :             :     }
   41738                 :             :   else
   41739                 :           0 :     goto invalid_kind;
   41740                 :             : 
   41741                 :         619 :   cp_lexer_consume_token (parser->lexer);
   41742                 :         619 :   if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
   41743                 :           0 :     goto resync_fail;
   41744                 :             : 
   41745                 :         619 :   c = build_omp_clause (location, OMP_CLAUSE_PROC_BIND);
   41746                 :         619 :   check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind",
   41747                 :             :                              location);
   41748                 :         619 :   OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
   41749                 :         619 :   OMP_CLAUSE_CHAIN (c) = list;
   41750                 :         619 :   return c;
   41751                 :             : 
   41752                 :           0 :  invalid_kind:
   41753                 :           0 :   cp_parser_error (parser, "invalid depend kind");
   41754                 :           0 :  resync_fail:
   41755                 :           0 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41756                 :             :                                          /*or_comma=*/false,
   41757                 :             :                                          /*consume_paren=*/true);
   41758                 :           0 :   return list;
   41759                 :             : }
   41760                 :             : 
   41761                 :             : /* OpenMP 5.0:
   41762                 :             :    device_type ( host | nohost | any )  */
   41763                 :             : 
   41764                 :             : static tree
   41765                 :         149 : cp_parser_omp_clause_device_type (cp_parser *parser, tree list,
   41766                 :             :                                   location_t location)
   41767                 :             : {
   41768                 :         149 :   tree c;
   41769                 :         149 :   enum omp_clause_device_type_kind kind;
   41770                 :             : 
   41771                 :         149 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   41772                 :             :     return list;
   41773                 :             : 
   41774                 :         149 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   41775                 :             :     {
   41776                 :         149 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   41777                 :         149 :       const char *p = IDENTIFIER_POINTER (id);
   41778                 :             : 
   41779                 :         149 :       if (strcmp ("host", p) == 0)
   41780                 :             :         kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
   41781                 :          92 :       else if (strcmp ("nohost", p) == 0)
   41782                 :             :         kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
   41783                 :          62 :       else if (strcmp ("any", p) == 0)
   41784                 :             :         kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
   41785                 :             :       else
   41786                 :           0 :         goto invalid_kind;
   41787                 :             :     }
   41788                 :             :   else
   41789                 :           0 :     goto invalid_kind;
   41790                 :             : 
   41791                 :         149 :   cp_lexer_consume_token (parser->lexer);
   41792                 :         149 :   if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
   41793                 :           0 :     goto resync_fail;
   41794                 :             : 
   41795                 :         149 :   c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE);
   41796                 :         149 :   check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type",
   41797                 :             :                              location);
   41798                 :         149 :   OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
   41799                 :         149 :   OMP_CLAUSE_CHAIN (c) = list;
   41800                 :         149 :   return c;
   41801                 :             : 
   41802                 :           0 :  invalid_kind:
   41803                 :           0 :   cp_parser_error (parser, "invalid depend kind");
   41804                 :           0 :  resync_fail:
   41805                 :           0 :   cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41806                 :             :                                          /*or_comma=*/false,
   41807                 :             :                                          /*consume_paren=*/true);
   41808                 :           0 :   return list;
   41809                 :             : }
   41810                 :             : 
   41811                 :             : /* OpenACC:
   41812                 :             :    async [( int-expr )] */
   41813                 :             : 
   41814                 :             : static tree
   41815                 :         423 : cp_parser_oacc_clause_async (cp_parser *parser, tree list)
   41816                 :             : {
   41817                 :         423 :   tree c, t;
   41818                 :         423 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   41819                 :             : 
   41820                 :         423 :   t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
   41821                 :             : 
   41822                 :         423 :   if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
   41823                 :             :     {
   41824                 :         301 :       matching_parens parens;
   41825                 :         301 :       parens.consume_open (parser);
   41826                 :             : 
   41827                 :         301 :       t = cp_parser_assignment_expression (parser);
   41828                 :         301 :       if (t == error_mark_node
   41829                 :         582 :           || !parens.require_close (parser))
   41830                 :          76 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41831                 :             :                                                 /*or_comma=*/false,
   41832                 :             :                                                 /*consume_paren=*/true);
   41833                 :             :     }
   41834                 :             : 
   41835                 :         423 :   check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async", loc);
   41836                 :             : 
   41837                 :         423 :   c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
   41838                 :         423 :   OMP_CLAUSE_ASYNC_EXPR (c) = t;
   41839                 :         423 :   OMP_CLAUSE_CHAIN (c) = list;
   41840                 :         423 :   list = c;
   41841                 :             : 
   41842                 :         423 :   return list;
   41843                 :             : }
   41844                 :             : 
   41845                 :             : /* OpenACC 2.7:
   41846                 :             :    self [( expression )] */
   41847                 :             : 
   41848                 :             : static tree
   41849                 :         111 : cp_parser_oacc_compute_clause_self (cp_parser *parser, tree list)
   41850                 :             : {
   41851                 :         111 :   tree t;
   41852                 :         111 :   location_t location = cp_lexer_peek_token (parser->lexer)->location;
   41853                 :         111 :   if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
   41854                 :             :     {
   41855                 :          87 :       matching_parens parens;
   41856                 :          87 :       parens.consume_open (parser);
   41857                 :          87 :       t = cp_parser_assignment_expression (parser);
   41858                 :          87 :       if (t == error_mark_node
   41859                 :         174 :           || !parens.require_close (parser))
   41860                 :             :         {
   41861                 :           0 :           cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   41862                 :             :                                                  /*or_comma=*/false,
   41863                 :             :                                                  /*consume_paren=*/true);
   41864                 :           0 :           return list;
   41865                 :             :         }
   41866                 :             :     }
   41867                 :             :   else
   41868                 :          24 :     t = truthvalue_true_node;
   41869                 :             : 
   41870                 :         141 :   for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
   41871                 :          54 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
   41872                 :             :       {
   41873                 :          24 :         error_at (location, "too many %<self%> clauses");
   41874                 :          24 :         return list;
   41875                 :             :       }
   41876                 :             : 
   41877                 :          87 :   tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
   41878                 :          87 :   OMP_CLAUSE_SELF_EXPR (c) = t;
   41879                 :          87 :   OMP_CLAUSE_CHAIN (c) = list;
   41880                 :          87 :   return c;
   41881                 :             : }
   41882                 :             : 
   41883                 :             : /* Parse all OpenACC clauses.  The set clauses allowed by the directive
   41884                 :             :    is a bitmask in MASK.  Return the list of clauses found.  */
   41885                 :             : 
   41886                 :             : static tree
   41887                 :       12818 : cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
   41888                 :             :                             const char *where, cp_token *pragma_tok,
   41889                 :             :                             bool finish_p = true, bool target_p = false)
   41890                 :             : {
   41891                 :       12818 :   tree clauses = NULL;
   41892                 :       12818 :   bool first = true;
   41893                 :             : 
   41894                 :             :   /* Don't create location wrapper nodes within OpenACC clauses.  */
   41895                 :       12818 :   auto_suppress_location_wrappers sentinel;
   41896                 :             : 
   41897                 :       28992 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   41898                 :             :     {
   41899                 :       16210 :       location_t here;
   41900                 :       16210 :       pragma_omp_clause c_kind;
   41901                 :       16210 :       omp_clause_code code;
   41902                 :       16210 :       const char *c_name;
   41903                 :       16210 :       tree prev = clauses;
   41904                 :             : 
   41905                 :       16210 :       if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   41906                 :           0 :         cp_lexer_consume_token (parser->lexer);
   41907                 :             : 
   41908                 :       16210 :       here = cp_lexer_peek_token (parser->lexer)->location;
   41909                 :       16210 :       c_kind = cp_parser_omp_clause_name (parser);
   41910                 :             : 
   41911                 :       16210 :       switch (c_kind)
   41912                 :             :         {
   41913                 :         423 :         case PRAGMA_OACC_CLAUSE_ASYNC:
   41914                 :         423 :           clauses = cp_parser_oacc_clause_async (parser, clauses);
   41915                 :         423 :           c_name = "async";
   41916                 :         423 :           break;
   41917                 :         337 :         case PRAGMA_OACC_CLAUSE_AUTO:
   41918                 :         337 :           clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
   41919                 :             :                                                   clauses);
   41920                 :         337 :           c_name = "auto";
   41921                 :         337 :           break;
   41922                 :         130 :         case PRAGMA_OACC_CLAUSE_ATTACH:
   41923                 :         130 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41924                 :         130 :           c_name = "attach";
   41925                 :         130 :           break;
   41926                 :         125 :         case PRAGMA_OACC_CLAUSE_COLLAPSE:
   41927                 :         125 :           clauses = cp_parser_omp_clause_collapse (parser, clauses, here);
   41928                 :         125 :           c_name = "collapse";
   41929                 :         125 :           break;
   41930                 :        1382 :         case PRAGMA_OACC_CLAUSE_COPY:
   41931                 :        1382 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41932                 :        1382 :           c_name = "copy";
   41933                 :        1382 :           break;
   41934                 :         921 :         case PRAGMA_OACC_CLAUSE_COPYIN:
   41935                 :         921 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41936                 :         921 :           c_name = "copyin";
   41937                 :         921 :           break;
   41938                 :        1086 :         case PRAGMA_OACC_CLAUSE_COPYOUT:
   41939                 :        1086 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41940                 :        1086 :           c_name = "copyout";
   41941                 :        1086 :           break;
   41942                 :         302 :         case PRAGMA_OACC_CLAUSE_CREATE:
   41943                 :         302 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41944                 :         302 :           c_name = "create";
   41945                 :         302 :           break;
   41946                 :         175 :         case PRAGMA_OACC_CLAUSE_DELETE:
   41947                 :         175 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41948                 :         175 :           c_name = "delete";
   41949                 :         175 :           break;
   41950                 :         213 :         case PRAGMA_OMP_CLAUSE_DEFAULT:
   41951                 :         213 :           clauses = cp_parser_omp_clause_default (parser, clauses, here, true);
   41952                 :         213 :           c_name = "default";
   41953                 :         213 :           break;
   41954                 :         116 :         case PRAGMA_OACC_CLAUSE_DETACH:
   41955                 :         116 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41956                 :         116 :           c_name = "detach";
   41957                 :         116 :           break;
   41958                 :          82 :         case PRAGMA_OACC_CLAUSE_DEVICE:
   41959                 :          82 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41960                 :          82 :           c_name = "device";
   41961                 :          82 :           break;
   41962                 :         112 :         case PRAGMA_OACC_CLAUSE_DEVICEPTR:
   41963                 :         112 :           clauses = cp_parser_oacc_data_clause_deviceptr (parser, clauses);
   41964                 :         112 :           c_name = "deviceptr";
   41965                 :         112 :           break;
   41966                 :          57 :         case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
   41967                 :          57 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41968                 :          57 :           c_name = "device_resident";
   41969                 :          57 :           break;
   41970                 :          46 :         case PRAGMA_OACC_CLAUSE_FINALIZE:
   41971                 :          46 :           clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
   41972                 :             :                                                   clauses);
   41973                 :          46 :           c_name = "finalize";
   41974                 :          46 :           break;
   41975                 :         428 :         case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
   41976                 :         428 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
   41977                 :             :                                             clauses);
   41978                 :         428 :           c_name = "firstprivate";
   41979                 :         428 :           break;
   41980                 :        1476 :         case PRAGMA_OACC_CLAUSE_GANG:
   41981                 :        1476 :           c_name = "gang";
   41982                 :        1476 :           clauses = cp_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
   41983                 :             :                                                  c_name, clauses);
   41984                 :        1476 :           break;
   41985                 :         111 :         case PRAGMA_OACC_CLAUSE_HOST:
   41986                 :         111 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   41987                 :         111 :           c_name = "host";
   41988                 :         111 :           break;
   41989                 :         187 :         case PRAGMA_OACC_CLAUSE_IF:
   41990                 :         187 :           clauses = cp_parser_omp_clause_if (parser, clauses, here, false);
   41991                 :         187 :           c_name = "if";
   41992                 :         187 :           break;
   41993                 :          66 :         case PRAGMA_OACC_CLAUSE_IF_PRESENT:
   41994                 :          66 :           clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
   41995                 :             :                                                   clauses);
   41996                 :          66 :           c_name = "if_present";
   41997                 :          66 :           break;
   41998                 :          97 :         case PRAGMA_OACC_CLAUSE_INDEPENDENT:
   41999                 :          97 :           clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
   42000                 :             :                                                   clauses);
   42001                 :          97 :           c_name = "independent";
   42002                 :          97 :           break;
   42003                 :          52 :         case PRAGMA_OACC_CLAUSE_LINK:
   42004                 :          52 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   42005                 :          52 :           c_name = "link";
   42006                 :          52 :           break;
   42007                 :          16 :         case PRAGMA_OACC_CLAUSE_NO_CREATE:
   42008                 :          16 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   42009                 :          16 :           c_name = "no_create";
   42010                 :          16 :           break;
   42011                 :          98 :         case PRAGMA_OACC_CLAUSE_NOHOST:
   42012                 :          98 :           clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
   42013                 :             :                                                   clauses);
   42014                 :          98 :           c_name = "nohost";
   42015                 :          98 :           break;
   42016                 :         494 :         case PRAGMA_OACC_CLAUSE_NUM_GANGS:
   42017                 :         494 :           code = OMP_CLAUSE_NUM_GANGS;
   42018                 :         494 :           c_name = "num_gangs";
   42019                 :         494 :           clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
   42020                 :             :                                                       clauses);
   42021                 :         494 :           break;
   42022                 :         374 :         case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
   42023                 :         374 :           c_name = "num_workers";
   42024                 :         374 :           code = OMP_CLAUSE_NUM_WORKERS;
   42025                 :         374 :           clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
   42026                 :             :                                                       clauses);
   42027                 :         374 :           break;
   42028                 :         249 :         case PRAGMA_OACC_CLAUSE_PRESENT:
   42029                 :         249 :           clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   42030                 :         249 :           c_name = "present";
   42031                 :         249 :           break;
   42032                 :         120 :         case PRAGMA_OACC_CLAUSE_PRIVATE:
   42033                 :         120 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE,
   42034                 :             :                                             clauses);
   42035                 :         120 :           c_name = "private";
   42036                 :         120 :           break;
   42037                 :        2061 :         case PRAGMA_OACC_CLAUSE_REDUCTION:
   42038                 :        2061 :           clauses
   42039                 :        2061 :             = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
   42040                 :             :                                               false, clauses);
   42041                 :        2061 :           c_name = "reduction";
   42042                 :        2061 :           break;
   42043                 :         167 :         case PRAGMA_OACC_CLAUSE_SELF:
   42044                 :         167 :           if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
   42045                 :             :             /* OpenACC compute construct */
   42046                 :         111 :             clauses = cp_parser_oacc_compute_clause_self (parser, clauses);
   42047                 :             :           else
   42048                 :             :             /* OpenACC 'update' directive */
   42049                 :          56 :             clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
   42050                 :             :           c_name = "self";
   42051                 :             :           break;
   42052                 :         930 :         case PRAGMA_OACC_CLAUSE_SEQ:
   42053                 :         930 :           clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
   42054                 :             :                                                   clauses);
   42055                 :         930 :           c_name = "seq";
   42056                 :         930 :           break;
   42057                 :         421 :         case PRAGMA_OACC_CLAUSE_TILE:
   42058                 :         421 :           clauses = cp_parser_oacc_clause_tile (parser, here, clauses);
   42059                 :         421 :           c_name = "tile";
   42060                 :         421 :           break;
   42061                 :          72 :         case PRAGMA_OACC_CLAUSE_USE_DEVICE:
   42062                 :          72 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_PTR,
   42063                 :             :                                             clauses);
   42064                 :          72 :           c_name = "use_device";
   42065                 :          72 :           break;
   42066                 :        1402 :         case PRAGMA_OACC_CLAUSE_VECTOR:
   42067                 :        1402 :           c_name = "vector";
   42068                 :        1402 :           clauses = cp_parser_oacc_shape_clause (parser, here,
   42069                 :             :                                                  OMP_CLAUSE_VECTOR,
   42070                 :             :                                                  c_name, clauses);
   42071                 :        1402 :           break;
   42072                 :         380 :         case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
   42073                 :         380 :           c_name = "vector_length";
   42074                 :         380 :           code = OMP_CLAUSE_VECTOR_LENGTH;
   42075                 :         380 :           clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
   42076                 :             :                                                       clauses);
   42077                 :         380 :           break;
   42078                 :         220 :         case PRAGMA_OACC_CLAUSE_WAIT:
   42079                 :         220 :           clauses = cp_parser_oacc_clause_wait (parser, clauses);
   42080                 :         220 :           c_name = "wait";
   42081                 :         220 :           break;
   42082                 :        1246 :         case PRAGMA_OACC_CLAUSE_WORKER:
   42083                 :        1246 :           c_name = "worker";
   42084                 :        1246 :           clauses = cp_parser_oacc_shape_clause (parser, here,
   42085                 :             :                                                  OMP_CLAUSE_WORKER,
   42086                 :             :                                                  c_name, clauses);
   42087                 :        1246 :           break;
   42088                 :          36 :         default:
   42089                 :          36 :           cp_parser_error (parser, "expected an OpenACC clause");
   42090                 :          36 :           goto saw_error;
   42091                 :             :         }
   42092                 :             : 
   42093                 :       16174 :       first = false;
   42094                 :             : 
   42095                 :       16174 :       if (((mask >> c_kind) & 1) == 0)
   42096                 :             :         {
   42097                 :             :           /* Remove the invalid clause(s) from the list to avoid
   42098                 :             :              confusing the rest of the compiler.  */
   42099                 :          88 :           clauses = prev;
   42100                 :          88 :           error_at (here, "%qs is not valid for %qs", c_name, where);
   42101                 :             :         }
   42102                 :             :     }
   42103                 :             : 
   42104                 :       12782 :  saw_error:
   42105                 :       12818 :   cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   42106                 :             : 
   42107                 :       12818 :   if (finish_p)
   42108                 :       19447 :     return finish_omp_clauses (clauses, target_p ? C_ORT_ACC_TARGET
   42109                 :       11545 :                                                  : C_ORT_ACC);
   42110                 :             : 
   42111                 :             :   return clauses;
   42112                 :             : }
   42113                 :             : 
   42114                 :             : /* Parse all OpenMP clauses.  The set clauses allowed by the directive
   42115                 :             :    is a bitmask in MASK.  Return the list of clauses found.
   42116                 :             :    FINISH_P set if finish_omp_clauses should be called.
   42117                 :             :    NESTED non-zero if clauses should be terminated by closing paren instead
   42118                 :             :    of end of pragma.  If it is 2, additionally commas are required in between
   42119                 :             :    the clauses.  */
   42120                 :             : 
   42121                 :             : static tree
   42122                 :       36980 : cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
   42123                 :             :                            const char *where, cp_token *pragma_tok,
   42124                 :             :                            bool finish_p = true, int nested = 0)
   42125                 :             : {
   42126                 :       36980 :   tree clauses = NULL;
   42127                 :       36980 :   bool first = true;
   42128                 :       36980 :   cp_token *token = NULL;
   42129                 :             : 
   42130                 :             :   /* Don't create location wrapper nodes within OpenMP clauses.  */
   42131                 :       36980 :   auto_suppress_location_wrappers sentinel;
   42132                 :             : 
   42133                 :       94749 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   42134                 :             :     {
   42135                 :       57911 :       pragma_omp_clause c_kind;
   42136                 :       57911 :       const char *c_name;
   42137                 :       57911 :       tree prev = clauses;
   42138                 :             : 
   42139                 :       57911 :       if (nested && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
   42140                 :             :         break;
   42141                 :             : 
   42142                 :       57847 :       if (!first || nested != 2)
   42143                 :             :         {
   42144                 :       57779 :           if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   42145                 :        9140 :             cp_lexer_consume_token (parser->lexer);
   42146                 :       48639 :           else if (nested == 2)
   42147                 :          12 :             error_at (cp_lexer_peek_token (parser->lexer)->location,
   42148                 :             :                       "clauses in %<simd%> trait should be separated "
   42149                 :             :                       "by %<,%>");
   42150                 :             :         }
   42151                 :             : 
   42152                 :       57847 :       token = cp_lexer_peek_token (parser->lexer);
   42153                 :       57847 :       c_kind = cp_parser_omp_clause_name (parser);
   42154                 :             : 
   42155                 :       57847 :       switch (c_kind)
   42156                 :             :         {
   42157                 :         449 :         case PRAGMA_OMP_CLAUSE_BIND:
   42158                 :         449 :           clauses = cp_parser_omp_clause_bind (parser, clauses,
   42159                 :             :                                                token->location);
   42160                 :         449 :           c_name = "bind";
   42161                 :         449 :           break;
   42162                 :        4335 :         case PRAGMA_OMP_CLAUSE_COLLAPSE:
   42163                 :        4335 :           clauses = cp_parser_omp_clause_collapse (parser, clauses,
   42164                 :             :                                                    token->location);
   42165                 :        4335 :           c_name = "collapse";
   42166                 :        4335 :           break;
   42167                 :         338 :         case PRAGMA_OMP_CLAUSE_COPYIN:
   42168                 :         338 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_COPYIN, clauses);
   42169                 :         338 :           c_name = "copyin";
   42170                 :         338 :           break;
   42171                 :          84 :         case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
   42172                 :          84 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_COPYPRIVATE,
   42173                 :             :                                             clauses);
   42174                 :          84 :           c_name = "copyprivate";
   42175                 :          84 :           break;
   42176                 :        2251 :         case PRAGMA_OMP_CLAUSE_DEFAULT:
   42177                 :        2251 :           clauses = cp_parser_omp_clause_default (parser, clauses,
   42178                 :             :                                                   token->location, false);
   42179                 :        2251 :           c_name = "default";
   42180                 :        2251 :           break;
   42181                 :         214 :         case PRAGMA_OMP_CLAUSE_FILTER:
   42182                 :         214 :           clauses = cp_parser_omp_clause_filter (parser, clauses,
   42183                 :             :                                                  token->location);
   42184                 :         214 :           c_name = "filter";
   42185                 :         214 :           break;
   42186                 :         330 :         case PRAGMA_OMP_CLAUSE_FINAL:
   42187                 :         330 :           clauses = cp_parser_omp_clause_final (parser, clauses, token->location);
   42188                 :         330 :           c_name = "final";
   42189                 :         330 :           break;
   42190                 :        2052 :         case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
   42191                 :        2052 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
   42192                 :             :                                             clauses);
   42193                 :        2052 :           c_name = "firstprivate";
   42194                 :        2052 :           break;
   42195                 :         192 :         case PRAGMA_OMP_CLAUSE_GRAINSIZE:
   42196                 :         192 :           clauses = cp_parser_omp_clause_grainsize (parser, clauses,
   42197                 :             :                                                     token->location);
   42198                 :         192 :           c_name = "grainsize";
   42199                 :         192 :           break;
   42200                 :          75 :         case PRAGMA_OMP_CLAUSE_HINT:
   42201                 :          75 :           clauses = cp_parser_omp_clause_hint (parser, clauses,
   42202                 :             :                                                token->location);
   42203                 :          75 :           c_name = "hint";
   42204                 :          75 :           break;
   42205                 :         816 :         case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
   42206                 :         816 :           clauses = cp_parser_omp_clause_defaultmap (parser, clauses,
   42207                 :             :                                                      token->location);
   42208                 :         816 :           c_name = "defaultmap";
   42209                 :         816 :           break;
   42210                 :          30 :         case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
   42211                 :          30 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_PTR,
   42212                 :             :                                             clauses);
   42213                 :          30 :           c_name = "use_device_ptr";
   42214                 :          30 :           break;
   42215                 :          82 :         case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
   42216                 :          82 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
   42217                 :             :                                             clauses);
   42218                 :          82 :           c_name = "use_device_addr";
   42219                 :          82 :           break;
   42220                 :         279 :         case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
   42221                 :         279 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_IS_DEVICE_PTR,
   42222                 :             :                                             clauses);
   42223                 :         279 :           c_name = "is_device_ptr";
   42224                 :         279 :           break;
   42225                 :         301 :         case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
   42226                 :         301 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
   42227                 :             :                                             clauses);
   42228                 :         301 :           c_name = "has_device_addr";
   42229                 :         301 :           break;
   42230                 :        2214 :         case PRAGMA_OMP_CLAUSE_IF:
   42231                 :        2214 :           clauses = cp_parser_omp_clause_if (parser, clauses, token->location,
   42232                 :             :                                              true);
   42233                 :        2214 :           c_name = "if";
   42234                 :        2214 :           break;
   42235                 :         850 :         case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
   42236                 :         850 :           clauses
   42237                 :         850 :             = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
   42238                 :             :                                               true, clauses);
   42239                 :         850 :           c_name = "in_reduction";
   42240                 :         850 :           break;
   42241                 :         114 :         case PRAGMA_OMP_CLAUSE_INDIRECT:
   42242                 :         114 :           clauses = cp_parser_omp_clause_indirect (parser, clauses,
   42243                 :             :                                                    token->location);
   42244                 :         114 :           c_name = "indirect";
   42245                 :         114 :           break;
   42246                 :        1773 :         case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
   42247                 :        1773 :           clauses = cp_parser_omp_clause_lastprivate (parser, clauses);
   42248                 :        1773 :           c_name = "lastprivate";
   42249                 :        1773 :           break;
   42250                 :         264 :         case PRAGMA_OMP_CLAUSE_MERGEABLE:
   42251                 :         264 :           clauses = cp_parser_omp_clause_mergeable (parser, clauses,
   42252                 :             :                                                     token->location);
   42253                 :         264 :           c_name = "mergeable";
   42254                 :         264 :           break;
   42255                 :         636 :         case PRAGMA_OMP_CLAUSE_NOWAIT:
   42256                 :         636 :           clauses = cp_parser_omp_clause_nowait (parser, clauses,
   42257                 :             :                                                  token->location);
   42258                 :         636 :           c_name = "nowait";
   42259                 :         636 :           break;
   42260                 :         156 :         case PRAGMA_OMP_CLAUSE_NUM_TASKS:
   42261                 :         156 :           clauses = cp_parser_omp_clause_num_tasks (parser, clauses,
   42262                 :             :                                                     token->location);
   42263                 :         156 :           c_name = "num_tasks";
   42264                 :         156 :           break;
   42265                 :         856 :         case PRAGMA_OMP_CLAUSE_NUM_THREADS:
   42266                 :         856 :           clauses = cp_parser_omp_clause_num_threads (parser, clauses,
   42267                 :             :                                                       token->location);
   42268                 :         856 :           c_name = "num_threads";
   42269                 :         856 :           break;
   42270                 :        1379 :         case PRAGMA_OMP_CLAUSE_ORDER:
   42271                 :        1379 :           clauses = cp_parser_omp_clause_order (parser, clauses,
   42272                 :             :                                                 token->location);
   42273                 :        1379 :           c_name = "order";
   42274                 :        1379 :           break;
   42275                 :         744 :         case PRAGMA_OMP_CLAUSE_ORDERED:
   42276                 :         744 :           clauses = cp_parser_omp_clause_ordered (parser, clauses,
   42277                 :             :                                                   token->location);
   42278                 :         744 :           c_name = "ordered";
   42279                 :         744 :           break;
   42280                 :         322 :         case PRAGMA_OMP_CLAUSE_PRIORITY:
   42281                 :         322 :           clauses = cp_parser_omp_clause_priority (parser, clauses,
   42282                 :             :                                                    token->location);
   42283                 :         322 :           c_name = "priority";
   42284                 :         322 :           break;
   42285                 :        1986 :         case PRAGMA_OMP_CLAUSE_PRIVATE:
   42286                 :        1986 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE,
   42287                 :             :                                             clauses);
   42288                 :        1986 :           c_name = "private";
   42289                 :        1986 :           break;
   42290                 :        3695 :         case PRAGMA_OMP_CLAUSE_REDUCTION:
   42291                 :        3695 :           clauses
   42292                 :        3695 :             = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
   42293                 :             :                                               true, clauses);
   42294                 :        3695 :           c_name = "reduction";
   42295                 :        3695 :           break;
   42296                 :        4006 :         case PRAGMA_OMP_CLAUSE_SCHEDULE:
   42297                 :        4006 :           clauses = cp_parser_omp_clause_schedule (parser, clauses,
   42298                 :             :                                                    token->location);
   42299                 :        4006 :           c_name = "schedule";
   42300                 :        4006 :           break;
   42301                 :        1541 :         case PRAGMA_OMP_CLAUSE_SHARED:
   42302                 :        1541 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_SHARED,
   42303                 :             :                                             clauses);
   42304                 :        1541 :           c_name = "shared";
   42305                 :        1541 :           break;
   42306                 :         253 :         case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
   42307                 :         253 :           clauses
   42308                 :         253 :             = cp_parser_omp_clause_reduction (parser,
   42309                 :             :                                               OMP_CLAUSE_TASK_REDUCTION,
   42310                 :             :                                               true, clauses);
   42311                 :         253 :           c_name = "task_reduction";
   42312                 :         253 :           break;
   42313                 :         276 :         case PRAGMA_OMP_CLAUSE_UNTIED:
   42314                 :         276 :           clauses = cp_parser_omp_clause_untied (parser, clauses,
   42315                 :             :                                                  token->location);
   42316                 :         276 :           c_name = "untied";
   42317                 :         276 :           break;
   42318                 :         149 :         case PRAGMA_OMP_CLAUSE_INBRANCH:
   42319                 :         149 :           clauses = cp_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
   42320                 :             :                                                  clauses, token->location);
   42321                 :         149 :           c_name = "inbranch";
   42322                 :         149 :           break;
   42323                 :         418 :         case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
   42324                 :         418 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_NONTEMPORAL,
   42325                 :             :                                             clauses);
   42326                 :         418 :           c_name = "nontemporal";
   42327                 :         418 :           break;
   42328                 :         566 :         case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
   42329                 :         566 :           clauses = cp_parser_omp_clause_branch (parser,
   42330                 :             :                                                  OMP_CLAUSE_NOTINBRANCH,
   42331                 :             :                                                  clauses, token->location);
   42332                 :         566 :           c_name = "notinbranch";
   42333                 :         566 :           break;
   42334                 :         399 :         case PRAGMA_OMP_CLAUSE_PARALLEL:
   42335                 :         399 :           clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
   42336                 :             :                                                      clauses, token->location);
   42337                 :         399 :           c_name = "parallel";
   42338                 :         399 :           if (!first)
   42339                 :             :             {
   42340                 :           0 :              clause_not_first:
   42341                 :           0 :               error_at (token->location, "%qs must be the first clause of %qs",
   42342                 :             :                         c_name, where);
   42343                 :           0 :               clauses = prev;
   42344                 :             :             }
   42345                 :             :           break;
   42346                 :         309 :         case PRAGMA_OMP_CLAUSE_FOR:
   42347                 :         309 :           clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
   42348                 :             :                                                      clauses, token->location);
   42349                 :         309 :           c_name = "for";
   42350                 :         309 :           if (!first)
   42351                 :           0 :             goto clause_not_first;
   42352                 :             :           break;
   42353                 :         300 :         case PRAGMA_OMP_CLAUSE_SECTIONS:
   42354                 :         300 :           clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
   42355                 :             :                                                      clauses, token->location);
   42356                 :         300 :           c_name = "sections";
   42357                 :         300 :           if (!first)
   42358                 :           0 :             goto clause_not_first;
   42359                 :             :           break;
   42360                 :         419 :         case PRAGMA_OMP_CLAUSE_TASKGROUP:
   42361                 :         419 :           clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
   42362                 :             :                                                      clauses, token->location);
   42363                 :         419 :           c_name = "taskgroup";
   42364                 :         419 :           if (!first)
   42365                 :           0 :             goto clause_not_first;
   42366                 :             :           break;
   42367                 :          89 :         case PRAGMA_OMP_CLAUSE_LINK:
   42368                 :          89 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINK, clauses);
   42369                 :          89 :           c_name = "link";
   42370                 :          89 :           break;
   42371                 :         806 :         case PRAGMA_OMP_CLAUSE_TO:
   42372                 :         806 :           if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
   42373                 :             :             {
   42374                 :         301 :               tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER,
   42375                 :             :                                                 clauses);
   42376                 :         662 :               for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
   42377                 :         361 :                 OMP_CLAUSE_ENTER_TO (c) = 1;
   42378                 :             :               clauses = nl;
   42379                 :             :             }
   42380                 :             :           else
   42381                 :         505 :             clauses = cp_parser_omp_clause_from_to (parser, OMP_CLAUSE_TO,
   42382                 :             :                                                     clauses);
   42383                 :             :           c_name = "to";
   42384                 :             :           break;
   42385                 :        2485 :         case PRAGMA_OMP_CLAUSE_FROM:
   42386                 :        2485 :           clauses = cp_parser_omp_clause_from_to (parser, OMP_CLAUSE_FROM,
   42387                 :             :                                                   clauses);
   42388                 :        2485 :           c_name = "from";
   42389                 :        2485 :           break;
   42390                 :         440 :         case PRAGMA_OMP_CLAUSE_UNIFORM:
   42391                 :         440 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_UNIFORM,
   42392                 :             :                                             clauses);
   42393                 :         440 :           c_name = "uniform";
   42394                 :         440 :           break;
   42395                 :         751 :         case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
   42396                 :         751 :           clauses = cp_parser_omp_clause_num_teams (parser, clauses,
   42397                 :             :                                                     token->location);
   42398                 :         751 :           c_name = "num_teams";
   42399                 :         751 :           break;
   42400                 :         508 :         case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
   42401                 :         508 :           clauses = cp_parser_omp_clause_thread_limit (parser, clauses,
   42402                 :             :                                                        token->location);
   42403                 :         508 :           c_name = "thread_limit";
   42404                 :         508 :           break;
   42405                 :         859 :         case PRAGMA_OMP_CLAUSE_ALIGNED:
   42406                 :         859 :           clauses = cp_parser_omp_clause_aligned (parser, clauses);
   42407                 :         859 :           c_name = "aligned";
   42408                 :         859 :           break;
   42409                 :        1727 :         case PRAGMA_OMP_CLAUSE_ALLOCATE:
   42410                 :        1727 :           clauses = cp_parser_omp_clause_allocate (parser, clauses);
   42411                 :        1727 :           c_name = "allocate";
   42412                 :        1727 :           break;
   42413                 :        1828 :         case PRAGMA_OMP_CLAUSE_LINEAR:
   42414                 :        1828 :           {
   42415                 :        1828 :             bool declare_simd = false;
   42416                 :        1828 :             if (((mask >> PRAGMA_OMP_CLAUSE_UNIFORM) & 1) != 0)
   42417                 :             :               declare_simd = true;
   42418                 :        1828 :             clauses = cp_parser_omp_clause_linear (parser, clauses, declare_simd);
   42419                 :             :           }
   42420                 :        1828 :           c_name = "linear";
   42421                 :        1828 :           break;
   42422                 :         616 :         case PRAGMA_OMP_CLAUSE_AFFINITY:
   42423                 :         616 :           clauses = cp_parser_omp_clause_affinity (parser, clauses);
   42424                 :         616 :           c_name = "affinity";
   42425                 :         616 :           break;
   42426                 :        2013 :         case PRAGMA_OMP_CLAUSE_DEPEND:
   42427                 :        2013 :           clauses = cp_parser_omp_clause_depend (parser, clauses,
   42428                 :             :                                                  token->location);
   42429                 :        2013 :           c_name = "depend";
   42430                 :        2013 :           break;
   42431                 :         244 :         case PRAGMA_OMP_CLAUSE_DOACROSS:
   42432                 :         244 :           clauses = cp_parser_omp_clause_doacross (parser, clauses,
   42433                 :             :                                                    token->location);
   42434                 :         244 :           c_name = "doacross";
   42435                 :         244 :           break;
   42436                 :          77 :         case PRAGMA_OMP_CLAUSE_DETACH:
   42437                 :          77 :           clauses = cp_parser_omp_clause_detach (parser, clauses);
   42438                 :          77 :           c_name = "detach";
   42439                 :          77 :           break;
   42440                 :        4485 :         case PRAGMA_OMP_CLAUSE_MAP:
   42441                 :        4485 :           clauses = cp_parser_omp_clause_map (parser, clauses);
   42442                 :        4485 :           c_name = "map";
   42443                 :        4485 :           break;
   42444                 :         675 :         case PRAGMA_OMP_CLAUSE_DEVICE:
   42445                 :         675 :           clauses = cp_parser_omp_clause_device (parser, clauses,
   42446                 :             :                                                  token->location);
   42447                 :         675 :           c_name = "device";
   42448                 :         675 :           break;
   42449                 :        1927 :         case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
   42450                 :        1927 :           clauses = cp_parser_omp_clause_dist_schedule (parser, clauses,
   42451                 :             :                                                         token->location);
   42452                 :        1927 :           c_name = "dist_schedule";
   42453                 :        1927 :           break;
   42454                 :         619 :         case PRAGMA_OMP_CLAUSE_PROC_BIND:
   42455                 :         619 :           clauses = cp_parser_omp_clause_proc_bind (parser, clauses,
   42456                 :             :                                                     token->location);
   42457                 :         619 :           c_name = "proc_bind";
   42458                 :         619 :           break;
   42459                 :         149 :         case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
   42460                 :         149 :           clauses = cp_parser_omp_clause_device_type (parser, clauses,
   42461                 :             :                                                       token->location);
   42462                 :         149 :           c_name = "device_type";
   42463                 :         149 :           break;
   42464                 :         561 :         case PRAGMA_OMP_CLAUSE_SAFELEN:
   42465                 :         561 :           clauses = cp_parser_omp_clause_safelen (parser, clauses,
   42466                 :             :                                                   token->location);
   42467                 :         561 :           c_name = "safelen";
   42468                 :         561 :           break;
   42469                 :         909 :         case PRAGMA_OMP_CLAUSE_SIMDLEN:
   42470                 :         909 :           clauses = cp_parser_omp_clause_simdlen (parser, clauses,
   42471                 :             :                                                   token->location);
   42472                 :         909 :           c_name = "simdlen";
   42473                 :         909 :           break;
   42474                 :          47 :         case PRAGMA_OMP_CLAUSE_NOGROUP:
   42475                 :          47 :           clauses = cp_parser_omp_clause_nogroup (parser, clauses,
   42476                 :             :                                                   token->location);
   42477                 :          47 :           c_name = "nogroup";
   42478                 :          47 :           break;
   42479                 :         156 :         case PRAGMA_OMP_CLAUSE_THREADS:
   42480                 :         156 :           clauses
   42481                 :         156 :             = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
   42482                 :             :                                                 clauses, token->location);
   42483                 :         156 :           c_name = "threads";
   42484                 :         156 :           break;
   42485                 :         214 :         case PRAGMA_OMP_CLAUSE_SIMD:
   42486                 :         214 :           clauses
   42487                 :         214 :             = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
   42488                 :             :                                                 clauses, token->location);
   42489                 :         214 :           c_name = "simd";
   42490                 :         214 :           break;
   42491                 :         131 :         case PRAGMA_OMP_CLAUSE_ENTER:
   42492                 :         131 :           clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER,
   42493                 :             :                                             clauses);
   42494                 :         131 :           c_name = "enter";
   42495                 :         131 :           break;
   42496                 :          78 :         default:
   42497                 :          78 :           cp_parser_error (parser, "expected an OpenMP clause");
   42498                 :          78 :           goto saw_error;
   42499                 :             :         }
   42500                 :             : 
   42501                 :       57769 :       first = false;
   42502                 :             : 
   42503                 :       57769 :       if (((mask >> c_kind) & 1) == 0)
   42504                 :             :         {
   42505                 :             :           /* Remove the invalid clause(s) from the list to avoid
   42506                 :             :              confusing the rest of the compiler.  */
   42507                 :         108 :           clauses = prev;
   42508                 :         108 :           error_at (token->location, "%qs is not valid for %qs", c_name, where);
   42509                 :             :         }
   42510                 :             :     }
   42511                 :       36838 :  saw_error:
   42512                 :       36980 :   if (!nested)
   42513                 :       36912 :     cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   42514                 :       36980 :   if (finish_p)
   42515                 :             :     {
   42516                 :       22937 :       if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
   42517                 :        1379 :         return finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
   42518                 :             :       else
   42519                 :       21558 :         return finish_omp_clauses (clauses, C_ORT_OMP);
   42520                 :             :     }
   42521                 :             :   return clauses;
   42522                 :             : }
   42523                 :             : 
   42524                 :             : /* OpenMP 2.5:
   42525                 :             :    structured-block:
   42526                 :             :      statement
   42527                 :             : 
   42528                 :             :    In practice, we're also interested in adding the statement to an
   42529                 :             :    outer node.  So it is convenient if we work around the fact that
   42530                 :             :    cp_parser_statement calls add_stmt.  */
   42531                 :             : 
   42532                 :             : static unsigned
   42533                 :       60370 : cp_parser_begin_omp_structured_block (cp_parser *parser)
   42534                 :             : {
   42535                 :       60370 :   unsigned save = parser->in_statement;
   42536                 :             : 
   42537                 :             :   /* Only move the values to IN_OMP_BLOCK if they weren't false.
   42538                 :             :      This preserves the "not within loop or switch" style error messages
   42539                 :             :      for nonsense cases like
   42540                 :             :         void foo() {
   42541                 :             :         #pragma omp single
   42542                 :             :           break;
   42543                 :             :         }
   42544                 :             :   */
   42545                 :           0 :   if (parser->in_statement)
   42546                 :        5092 :     parser->in_statement = IN_OMP_BLOCK;
   42547                 :             : 
   42548                 :       60370 :   return save;
   42549                 :             : }
   42550                 :             : 
   42551                 :             : static void
   42552                 :       60370 : cp_parser_end_omp_structured_block (cp_parser *parser, unsigned save)
   42553                 :             : {
   42554                 :       60370 :   parser->in_statement = save;
   42555                 :           0 : }
   42556                 :             : 
   42557                 :             : static tree
   42558                 :        8866 : cp_parser_omp_structured_block (cp_parser *parser, bool *if_p)
   42559                 :             : {
   42560                 :        8866 :   tree stmt = begin_omp_structured_block ();
   42561                 :        8866 :   unsigned int save = cp_parser_begin_omp_structured_block (parser);
   42562                 :             : 
   42563                 :        8866 :   parser->omp_attrs_forbidden_p = true;
   42564                 :        8866 :   cp_parser_statement (parser, NULL_TREE, false, if_p);
   42565                 :             : 
   42566                 :        8866 :   cp_parser_end_omp_structured_block (parser, save);
   42567                 :        8866 :   return finish_omp_structured_block (stmt);
   42568                 :             : }
   42569                 :             : 
   42570                 :             : /* OpenMP 5.x:
   42571                 :             :    # pragma omp allocate (list)  clauses
   42572                 :             : 
   42573                 :             :    OpenMP 5.0 clause:
   42574                 :             :    allocator (omp_allocator_handle_t expression)
   42575                 :             : 
   42576                 :             :    OpenMP 5.1 additional clause:
   42577                 :             :    align (constant-expression)]  */
   42578                 :             : 
   42579                 :             : static void
   42580                 :         128 : cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
   42581                 :             : {
   42582                 :         128 :   tree allocator = NULL_TREE;
   42583                 :         128 :   tree alignment = NULL_TREE;
   42584                 :         128 :   location_t loc = pragma_tok->location;
   42585                 :         128 :   tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
   42586                 :             : 
   42587                 :         416 :   do
   42588                 :             :     {
   42589                 :         272 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   42590                 :         272 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   42591                 :          20 :         cp_lexer_consume_token (parser->lexer);
   42592                 :             : 
   42593                 :         272 :       if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   42594                 :             :         break;
   42595                 :         156 :       matching_parens parens;
   42596                 :         156 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   42597                 :         156 :       const char *p = IDENTIFIER_POINTER (id);
   42598                 :         156 :       location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
   42599                 :         156 :       cp_lexer_consume_token (parser->lexer);
   42600                 :         156 :       if (strcmp (p, "allocator") != 0 && strcmp (p, "align") != 0)
   42601                 :             :         {
   42602                 :           4 :           error_at (cloc, "expected %<allocator%> or %<align%>");
   42603                 :           4 :           break;
   42604                 :             :         }
   42605                 :         152 :       if (!parens.require_open (parser))
   42606                 :             :         break;
   42607                 :         152 :       tree expr = cp_parser_assignment_expression (parser);
   42608                 :         152 :       if (p[2] == 'i' && alignment)
   42609                 :             :         {
   42610                 :           4 :           error_at (cloc, "too many %qs clauses", "align");
   42611                 :           4 :           break;
   42612                 :             :         }
   42613                 :         148 :       else if (p[2] == 'i')
   42614                 :             :         {
   42615                 :          72 :           if (expr != error_mark_node)
   42616                 :          72 :             alignment = expr;
   42617                 :             :           /* FIXME: Remove when adding check to semantics.cc; cf FIXME below. */
   42618                 :          72 :           if (alignment
   42619                 :          72 :               && !type_dependent_expression_p (alignment)
   42620                 :         144 :               && !INTEGRAL_TYPE_P (TREE_TYPE (alignment)))
   42621                 :             :             {
   42622                 :           4 :               error_at (cloc, "%<align%> clause argument needs to be "
   42623                 :             :                               "positive constant power of two integer "
   42624                 :             :                               "expression");
   42625                 :           4 :               alignment = NULL_TREE;
   42626                 :             :             }
   42627                 :          68 :           else if (alignment)
   42628                 :             :             {
   42629                 :          68 :               alignment = mark_rvalue_use (alignment);
   42630                 :          68 :               if (!processing_template_decl)
   42631                 :             :                 {
   42632                 :          68 :                   alignment = maybe_constant_value (alignment);
   42633                 :          68 :                   if (TREE_CODE (alignment) != INTEGER_CST
   42634                 :          68 :                       || !tree_fits_uhwi_p (alignment)
   42635                 :         132 :                       || !integer_pow2p (alignment))
   42636                 :             :                     {
   42637                 :          12 :                       error_at (cloc, "%<align%> clause argument needs to be "
   42638                 :             :                                       "positive constant power of two integer "
   42639                 :             :                                       "expression");
   42640                 :          12 :                       alignment = NULL_TREE;
   42641                 :             :                     }
   42642                 :             :                 }
   42643                 :             :             }
   42644                 :             :         }
   42645                 :          76 :       else if (allocator)
   42646                 :             :         {
   42647                 :           4 :           error_at (cloc, "too many %qs clauses", "allocator");
   42648                 :           4 :           break;
   42649                 :             :         }
   42650                 :             :       else
   42651                 :             :         {
   42652                 :          72 :           if (expr != error_mark_node)
   42653                 :          68 :             allocator = expr;
   42654                 :             :         }
   42655                 :         144 :       parens.require_close (parser);
   42656                 :         144 :     } while (true);
   42657                 :         128 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   42658                 :             : 
   42659                 :         128 :   if (allocator || alignment)
   42660                 :         156 :     for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
   42661                 :             :       {
   42662                 :          76 :         OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
   42663                 :          76 :         OMP_CLAUSE_ALLOCATE_ALIGN (c) = alignment;
   42664                 :             :       }
   42665                 :             : 
   42666                 :             :   /* FIXME: When implementing properly, delete the align/allocate expr error
   42667                 :             :      check above and add one in semantics.cc (to properly handle templates).
   42668                 :             :      Base this on the allocator/align modifiers check for the 'allocate' clause
   42669                 :             :      in semantics.cc's finish_omp_clauses.  */
   42670                 :         128 :   sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
   42671                 :         128 : }
   42672                 :             : 
   42673                 :             : /* OpenMP 2.5:
   42674                 :             :    # pragma omp atomic new-line
   42675                 :             :      expression-stmt
   42676                 :             : 
   42677                 :             :    expression-stmt:
   42678                 :             :      x binop= expr | x++ | ++x | x-- | --x
   42679                 :             :    binop:
   42680                 :             :      +, *, -, /, &, ^, |, <<, >>
   42681                 :             : 
   42682                 :             :   where x is an lvalue expression with scalar type.
   42683                 :             : 
   42684                 :             :    OpenMP 3.1:
   42685                 :             :    # pragma omp atomic new-line
   42686                 :             :      update-stmt
   42687                 :             : 
   42688                 :             :    # pragma omp atomic read new-line
   42689                 :             :      read-stmt
   42690                 :             : 
   42691                 :             :    # pragma omp atomic write new-line
   42692                 :             :      write-stmt
   42693                 :             : 
   42694                 :             :    # pragma omp atomic update new-line
   42695                 :             :      update-stmt
   42696                 :             : 
   42697                 :             :    # pragma omp atomic capture new-line
   42698                 :             :      capture-stmt
   42699                 :             : 
   42700                 :             :    # pragma omp atomic capture new-line
   42701                 :             :      capture-block
   42702                 :             : 
   42703                 :             :    read-stmt:
   42704                 :             :      v = x
   42705                 :             :    write-stmt:
   42706                 :             :      x = expr
   42707                 :             :    update-stmt:
   42708                 :             :      expression-stmt | x = x binop expr
   42709                 :             :    capture-stmt:
   42710                 :             :      v = expression-stmt
   42711                 :             :    capture-block:
   42712                 :             :      { v = x; update-stmt; } | { update-stmt; v = x; }
   42713                 :             : 
   42714                 :             :    OpenMP 4.0:
   42715                 :             :    update-stmt:
   42716                 :             :      expression-stmt | x = x binop expr | x = expr binop x
   42717                 :             :    capture-stmt:
   42718                 :             :      v = update-stmt
   42719                 :             :    capture-block:
   42720                 :             :      { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
   42721                 :             : 
   42722                 :             :    OpenMP 5.1:
   42723                 :             :    # pragma omp atomic compare new-line
   42724                 :             :      conditional-update-atomic
   42725                 :             : 
   42726                 :             :    # pragma omp atomic compare capture new-line
   42727                 :             :      conditional-update-capture-atomic
   42728                 :             : 
   42729                 :             :    conditional-update-atomic:
   42730                 :             :      cond-expr-stmt | cond-update-stmt
   42731                 :             :    cond-expr-stmt:
   42732                 :             :      x = expr ordop x ? expr : x;
   42733                 :             :      x = x ordop expr ? expr : x;
   42734                 :             :      x = x == e ? d : x;
   42735                 :             :    cond-update-stmt:
   42736                 :             :      if (expr ordop x) { x = expr; }
   42737                 :             :      if (x ordop expr) { x = expr; }
   42738                 :             :      if (x == e) { x = d; }
   42739                 :             :    ordop:
   42740                 :             :      <, >
   42741                 :             :    conditional-update-capture-atomic:
   42742                 :             :      v = cond-expr-stmt
   42743                 :             :      { v = x; cond-expr-stmt }
   42744                 :             :      { cond-expr-stmt v = x; }
   42745                 :             :      { v = x; cond-update-stmt }
   42746                 :             :      { cond-update-stmt v = x; }
   42747                 :             :      if (x == e) { x = d; } else { v = x; }
   42748                 :             :      { r = x == e; if (r) { x = d; } }
   42749                 :             :      { r = x == e; if (r) { x = d; } else { v = x; } }
   42750                 :             : 
   42751                 :             :   where x, r and v are lvalue expressions with scalar type,
   42752                 :             :   expr, e and d are expressions with scalar type and e might be
   42753                 :             :   the same as v.  */
   42754                 :             : 
   42755                 :             : static void
   42756                 :        3660 : cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok, bool openacc)
   42757                 :             : {
   42758                 :        3660 :   tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, lhs1 = NULL_TREE;
   42759                 :        3660 :   tree rhs1 = NULL_TREE, orig_lhs, r = NULL_TREE;
   42760                 :        3660 :   location_t loc = pragma_tok->location;
   42761                 :        3660 :   enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
   42762                 :        3660 :   enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
   42763                 :        3660 :   bool structured_block = false;
   42764                 :        3660 :   tree clauses = NULL_TREE;
   42765                 :        3660 :   bool capture = false;
   42766                 :        3660 :   bool compare = false;
   42767                 :        3660 :   bool weak = false;
   42768                 :        3660 :   enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
   42769                 :        3660 :   bool no_semicolon = false;
   42770                 :        3660 :   bool extra_scope = false;
   42771                 :             : 
   42772                 :        7547 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   42773                 :             :     {
   42774                 :        3919 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   42775                 :        3919 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   42776                 :         340 :         cp_lexer_consume_token (parser->lexer);
   42777                 :             : 
   42778                 :        3919 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   42779                 :             :         {
   42780                 :        3911 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   42781                 :        3911 :           location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
   42782                 :        3911 :           const char *p = IDENTIFIER_POINTER (id);
   42783                 :        3911 :           enum tree_code new_code = ERROR_MARK;
   42784                 :        3911 :           enum omp_memory_order new_memory_order
   42785                 :             :             = OMP_MEMORY_ORDER_UNSPECIFIED;
   42786                 :        3911 :           bool new_capture = false;
   42787                 :        3911 :           bool new_compare = false;
   42788                 :        3911 :           bool new_weak = false;
   42789                 :        3911 :           enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
   42790                 :             : 
   42791                 :        3911 :           if (!strcmp (p, "read"))
   42792                 :             :             new_code = OMP_ATOMIC_READ;
   42793                 :        3431 :           else if (!strcmp (p, "write"))
   42794                 :             :             new_code = NOP_EXPR;
   42795                 :        3146 :           else if (!strcmp (p, "update"))
   42796                 :             :             new_code = OMP_ATOMIC;
   42797                 :        2799 :           else if (openacc && !strcmp (p, "capture"))
   42798                 :             :             new_code = OMP_ATOMIC_CAPTURE_NEW;
   42799                 :          16 :           else if (openacc)
   42800                 :             :             {
   42801                 :          16 :               p = NULL;
   42802                 :          16 :               error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
   42803                 :             :                               "or %<capture%> clause");
   42804                 :             :             }
   42805                 :        2527 :           else if (!strcmp (p, "capture"))
   42806                 :             :             new_capture = true;
   42807                 :        1788 :           else if (!strcmp (p, "compare"))
   42808                 :             :             new_compare = true;
   42809                 :        1002 :           else if (!strcmp (p, "weak"))
   42810                 :             :             new_weak = true;
   42811                 :         944 :           else if (!strcmp (p, "fail"))
   42812                 :             :             {
   42813                 :         146 :               matching_parens parens;
   42814                 :             : 
   42815                 :         146 :               cp_lexer_consume_token (parser->lexer);
   42816                 :         146 :               if (!parens.require_open (parser))
   42817                 :           4 :                 continue;
   42818                 :             : 
   42819                 :         142 :               if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   42820                 :             :                 {
   42821                 :         134 :                   id = cp_lexer_peek_token (parser->lexer)->u.value;
   42822                 :         134 :                   const char *q = IDENTIFIER_POINTER (id);
   42823                 :             : 
   42824                 :         134 :                   if (!strcmp (q, "seq_cst"))
   42825                 :             :                     new_fail = OMP_MEMORY_ORDER_SEQ_CST;
   42826                 :         102 :                   else if (!strcmp (q, "acquire"))
   42827                 :             :                     new_fail = OMP_MEMORY_ORDER_ACQUIRE;
   42828                 :          70 :                   else if (!strcmp (q, "relaxed"))
   42829                 :             :                     new_fail = OMP_MEMORY_ORDER_RELAXED;
   42830                 :             :                 }
   42831                 :             : 
   42832                 :             :               if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
   42833                 :             :                 {
   42834                 :         122 :                   cp_lexer_consume_token (parser->lexer);
   42835                 :         122 :                   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
   42836                 :           8 :                     error_at (cloc, "too many %qs clauses", "fail");
   42837                 :             :                   else
   42838                 :             :                     fail = new_fail;
   42839                 :             :                 }
   42840                 :             :               else
   42841                 :          20 :                 cp_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
   42842                 :             :                                          "or %<relaxed%>");
   42843                 :         142 :               if (new_fail == OMP_MEMORY_ORDER_UNSPECIFIED
   42844                 :         264 :                   || !parens.require_close (parser))
   42845                 :          24 :                 cp_parser_skip_to_closing_parenthesis (parser,
   42846                 :             :                                                        /*recovering=*/true,
   42847                 :             :                                                        /*or_comma=*/false,
   42848                 :             :                                                        /*consume_paren=*/true);
   42849                 :         142 :               continue;
   42850                 :         142 :             }
   42851                 :         798 :           else if (!strcmp (p, "seq_cst"))
   42852                 :             :             new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   42853                 :         526 :           else if (!strcmp (p, "acq_rel"))
   42854                 :             :             new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
   42855                 :         470 :           else if (!strcmp (p, "release"))
   42856                 :             :             new_memory_order = OMP_MEMORY_ORDER_RELEASE;
   42857                 :         336 :           else if (!strcmp (p, "acquire"))
   42858                 :             :             new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   42859                 :         276 :           else if (!strcmp (p, "relaxed"))
   42860                 :             :             new_memory_order = OMP_MEMORY_ORDER_RELAXED;
   42861                 :         158 :           else if (!strcmp (p, "hint"))
   42862                 :             :             {
   42863                 :         150 :               cp_lexer_consume_token (parser->lexer);
   42864                 :         150 :               clauses = cp_parser_omp_clause_hint (parser, clauses, cloc);
   42865                 :         150 :               continue;
   42866                 :             :             }
   42867                 :             :           else
   42868                 :             :             {
   42869                 :           8 :               p = NULL;
   42870                 :           8 :               error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
   42871                 :             :                               "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
   42872                 :             :                               "%<seq_cst%>, %<acq_rel%>, %<release%>, "
   42873                 :             :                               "%<relaxed%> or %<hint%> clause");
   42874                 :             :             }
   42875                 :        3615 :           if (p)
   42876                 :             :             {
   42877                 :        3591 :               if (new_code != ERROR_MARK)
   42878                 :             :                 {
   42879                 :             :                   /* OpenACC permits 'update capture'.  */
   42880                 :        1368 :                   if (openacc
   42881                 :        1368 :                       && code == OMP_ATOMIC
   42882                 :          16 :                       && new_code == OMP_ATOMIC_CAPTURE_NEW)
   42883                 :             :                     code = new_code;
   42884                 :        1356 :                   else if (code != ERROR_MARK)
   42885                 :          20 :                     error_at (cloc, "too many atomic clauses");
   42886                 :             :                   else
   42887                 :             :                     code = new_code;
   42888                 :             :                 }
   42889                 :        2223 :               else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
   42890                 :             :                 {
   42891                 :         640 :                   if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
   42892                 :         140 :                     error_at (cloc, "too many memory order clauses");
   42893                 :             :                   else
   42894                 :             :                     memory_order = new_memory_order;
   42895                 :             :                 }
   42896                 :        1583 :               else if (new_capture)
   42897                 :             :                 {
   42898                 :         739 :                   if (capture)
   42899                 :           4 :                     error_at (cloc, "too many %qs clauses", "capture");
   42900                 :             :                   else
   42901                 :             :                     capture = true;
   42902                 :             :                 }
   42903                 :         844 :               else if (new_compare)
   42904                 :             :                 {
   42905                 :         786 :                   if (compare)
   42906                 :           4 :                     error_at (cloc, "too many %qs clauses", "compare");
   42907                 :             :                   else
   42908                 :             :                     compare = true;
   42909                 :             :                 }
   42910                 :          58 :               else if (new_weak)
   42911                 :             :                 {
   42912                 :          58 :                   if (weak)
   42913                 :           4 :                     error_at (cloc, "too many %qs clauses", "weak");
   42914                 :             :                   else
   42915                 :             :                     weak = true;
   42916                 :             :                 }
   42917                 :        3591 :               cp_lexer_consume_token (parser->lexer);
   42918                 :        3591 :               continue;
   42919                 :             :             }
   42920                 :             :         }
   42921                 :             :       break;
   42922                 :             :     }
   42923                 :        3660 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   42924                 :             : 
   42925                 :        3660 :   if (code == ERROR_MARK)
   42926                 :        2324 :     code = OMP_ATOMIC;
   42927                 :        3660 :   if (capture)
   42928                 :             :     {
   42929                 :         735 :       if (code != OMP_ATOMIC)
   42930                 :           8 :         error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
   42931                 :             :                        "clauses", "capture");
   42932                 :             :       else
   42933                 :             :         code = OMP_ATOMIC_CAPTURE_NEW;
   42934                 :             :     }
   42935                 :        3660 :   if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
   42936                 :             :     {
   42937                 :           8 :       error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
   42938                 :             :                      "clauses", "compare");
   42939                 :           8 :       compare = false;
   42940                 :             :     }
   42941                 :        3660 :   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
   42942                 :             :     {
   42943                 :          20 :       error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
   42944                 :          20 :       fail = OMP_MEMORY_ORDER_UNSPECIFIED;
   42945                 :             :     }
   42946                 :        3660 :   if (weak && !compare)
   42947                 :             :     {
   42948                 :          20 :       error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
   42949                 :          20 :       weak = false;
   42950                 :             :     }
   42951                 :        3660 :   if (openacc)
   42952                 :             :     memory_order = OMP_MEMORY_ORDER_RELAXED;
   42953                 :        3272 :   else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
   42954                 :             :     {
   42955                 :        2772 :       omp_requires_mask
   42956                 :        2772 :         = (enum omp_requires) (omp_requires_mask
   42957                 :             :                                | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
   42958                 :        2772 :       switch ((enum omp_memory_order)
   42959                 :             :               (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
   42960                 :             :         {
   42961                 :             :         case OMP_MEMORY_ORDER_UNSPECIFIED:
   42962                 :             :         case OMP_MEMORY_ORDER_RELAXED:
   42963                 :             :           memory_order = OMP_MEMORY_ORDER_RELAXED;
   42964                 :             :           break;
   42965                 :             :         case OMP_MEMORY_ORDER_SEQ_CST:
   42966                 :          36 :           memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   42967                 :             :           break;
   42968                 :          16 :         case OMP_MEMORY_ORDER_ACQUIRE:
   42969                 :          16 :           if (code == NOP_EXPR)  /* atomic write */
   42970                 :             :             {
   42971                 :           4 :               error_at (loc, "%<#pragma omp atomic write%> incompatible with "
   42972                 :             :                              "%<acquire%> clause implicitly provided by a "
   42973                 :             :                              "%<requires%> directive");
   42974                 :           4 :               memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   42975                 :             :             }
   42976                 :             :           else
   42977                 :             :             memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   42978                 :             :           break;
   42979                 :          12 :         case OMP_MEMORY_ORDER_RELEASE:
   42980                 :          12 :           if (code == OMP_ATOMIC_READ)
   42981                 :             :             {
   42982                 :           4 :               error_at (loc, "%<#pragma omp atomic read%> incompatible with "
   42983                 :             :                              "%<release%> clause implicitly provided by a "
   42984                 :             :                              "%<requires%> directive");
   42985                 :           4 :               memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   42986                 :             :             }
   42987                 :             :           else
   42988                 :             :             memory_order = OMP_MEMORY_ORDER_RELEASE;
   42989                 :             :           break;
   42990                 :          44 :         case OMP_MEMORY_ORDER_ACQ_REL:
   42991                 :          44 :           switch (code)
   42992                 :             :             {
   42993                 :             :             case OMP_ATOMIC_READ:
   42994                 :             :               memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   42995                 :             :               break;
   42996                 :             :             case NOP_EXPR: /* atomic write */
   42997                 :          20 :               memory_order = OMP_MEMORY_ORDER_RELEASE;
   42998                 :             :               break;
   42999                 :             :             default:
   43000                 :        3660 :               memory_order = OMP_MEMORY_ORDER_ACQ_REL;
   43001                 :             :               break;
   43002                 :             :             }
   43003                 :             :           break;
   43004                 :           0 :         default:
   43005                 :           0 :           gcc_unreachable ();
   43006                 :             :         }
   43007                 :             :     }
   43008                 :             :   else
   43009                 :         500 :     switch (code)
   43010                 :             :       {
   43011                 :          82 :       case OMP_ATOMIC_READ:
   43012                 :          82 :         if (memory_order == OMP_MEMORY_ORDER_RELEASE)
   43013                 :             :           {
   43014                 :           4 :             error_at (loc, "%<#pragma omp atomic read%> incompatible with "
   43015                 :             :                            "%<release%> clause");
   43016                 :           4 :             memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   43017                 :             :           }
   43018                 :          78 :         else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
   43019                 :          24 :           memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   43020                 :             :         break;
   43021                 :          66 :       case NOP_EXPR: /* atomic write */
   43022                 :          66 :         if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
   43023                 :             :           {
   43024                 :           4 :             error_at (loc, "%<#pragma omp atomic write%> incompatible with "
   43025                 :             :                            "%<acquire%> clause");
   43026                 :           4 :             memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   43027                 :             :           }
   43028                 :          62 :         else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
   43029                 :          20 :           memory_order = OMP_MEMORY_ORDER_RELEASE;
   43030                 :             :         break;
   43031                 :             :       default:
   43032                 :             :         break;
   43033                 :             :       }
   43034                 :        3660 :   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
   43035                 :          94 :     memory_order
   43036                 :          94 :       = (enum omp_memory_order) (memory_order
   43037                 :             :                                  | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
   43038                 :             : 
   43039                 :        3660 :   switch (code)
   43040                 :             :     {
   43041                 :         761 :     case OMP_ATOMIC_READ:
   43042                 :         761 :     case NOP_EXPR: /* atomic write */
   43043                 :         761 :       v = cp_parser_unary_expression (parser);
   43044                 :         761 :       if (v == error_mark_node)
   43045                 :           0 :         goto saw_error;
   43046                 :         761 :       if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   43047                 :           0 :         goto saw_error;
   43048                 :         761 :       if (code == NOP_EXPR)
   43049                 :         281 :         lhs = cp_parser_expression (parser);
   43050                 :             :       else
   43051                 :         480 :         lhs = cp_parser_unary_expression (parser);
   43052                 :         761 :       if (lhs == error_mark_node)
   43053                 :           0 :         goto saw_error;
   43054                 :         761 :       if (code == NOP_EXPR)
   43055                 :             :         {
   43056                 :             :           /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
   43057                 :             :              opcode.  */
   43058                 :         281 :           code = OMP_ATOMIC;
   43059                 :         281 :           rhs = lhs;
   43060                 :         281 :           lhs = v;
   43061                 :         281 :           v = NULL_TREE;
   43062                 :             :         }
   43063                 :         761 :       goto done;
   43064                 :         975 :     case OMP_ATOMIC_CAPTURE_NEW:
   43065                 :         975 :       if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   43066                 :             :         {
   43067                 :         586 :           cp_lexer_consume_token (parser->lexer);
   43068                 :         586 :           structured_block = true;
   43069                 :             :         }
   43070                 :         389 :       else if (compare
   43071                 :         389 :                && cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
   43072                 :             :         break;
   43073                 :             :       else
   43074                 :             :         {
   43075                 :         319 :           v = cp_parser_unary_expression (parser);
   43076                 :         319 :           if (v == error_mark_node)
   43077                 :           0 :             goto saw_error;
   43078                 :         319 :           if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   43079                 :           0 :             goto saw_error;
   43080                 :         319 :           if (compare
   43081                 :         319 :               && cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
   43082                 :             :             {
   43083                 :           4 :               location_t eloc = cp_lexer_peek_token (parser->lexer)->location;
   43084                 :           4 :               error_at (eloc, "expected expression");
   43085                 :           4 :               goto saw_error;
   43086                 :             :             }
   43087                 :             :         }
   43088                 :             :     default:
   43089                 :             :       break;
   43090                 :             :     }
   43091                 :             : 
   43092                 :        2895 : restart:
   43093                 :        3249 :   if (compare && cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
   43094                 :             :     {
   43095                 :         361 :       cp_lexer_consume_token (parser->lexer);
   43096                 :             : 
   43097                 :         361 :       matching_parens parens;
   43098                 :         361 :       if (!parens.require_open (parser))
   43099                 :         112 :         goto saw_error;
   43100                 :         357 :       location_t eloc = cp_lexer_peek_token (parser->lexer)->location;
   43101                 :         357 :       tree cmp_expr;
   43102                 :         357 :       if (r)
   43103                 :          74 :         cmp_expr = cp_parser_unary_expression (parser);
   43104                 :             :       else
   43105                 :         283 :         cmp_expr = cp_parser_binary_expression (parser, false, true,
   43106                 :             :                                                 PREC_NOT_OPERATOR, NULL);
   43107                 :         357 :       if (!parens.require_close (parser))
   43108                 :           0 :         cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
   43109                 :         357 :       if (cmp_expr == error_mark_node)
   43110                 :           0 :         goto saw_error;
   43111                 :         357 :       if (r)
   43112                 :             :         {
   43113                 :          74 :           if (!cp_tree_equal (cmp_expr, r))
   43114                 :           4 :             goto bad_if;
   43115                 :          70 :           cmp_expr = rhs;
   43116                 :          70 :           rhs = NULL_TREE;
   43117                 :          70 :           gcc_assert (TREE_CODE (cmp_expr) == EQ_EXPR);
   43118                 :             :         }
   43119                 :         353 :       if (TREE_CODE (cmp_expr) == EQ_EXPR)
   43120                 :             :         ;
   43121                 :         141 :       else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
   43122                 :             :         {
   43123                 :           8 :           error_at (EXPR_LOC_OR_LOC (cmp_expr, eloc),
   43124                 :             :                     "expected %<==%> comparison in %<if%> condition");
   43125                 :           8 :           goto saw_error;
   43126                 :             :         }
   43127                 :         133 :       else if (TREE_CODE (cmp_expr) != GT_EXPR
   43128                 :          77 :                && TREE_CODE (cmp_expr) != LT_EXPR)
   43129                 :             :         {
   43130                 :          16 :           error_at (EXPR_LOC_OR_LOC (cmp_expr, eloc),
   43131                 :             :                     "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
   43132                 :             :                     "condition");
   43133                 :          16 :           goto saw_error;
   43134                 :             :         }
   43135                 :         329 :       if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
   43136                 :           8 :         goto saw_error;
   43137                 :             : 
   43138                 :         321 :       extra_scope = true;
   43139                 :         321 :       eloc = cp_lexer_peek_token (parser->lexer)->location;
   43140                 :         321 :       lhs = cp_parser_unary_expression (parser);
   43141                 :         321 :       orig_lhs = lhs;
   43142                 :         321 :       if (lhs == error_mark_node)
   43143                 :           0 :         goto saw_error;
   43144                 :         321 :       if (!cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   43145                 :             :         {
   43146                 :           4 :           cp_parser_error (parser, "expected %<=%>");
   43147                 :           4 :           goto saw_error;
   43148                 :             :         }
   43149                 :         317 :       cp_lexer_consume_token (parser->lexer);
   43150                 :         317 :       eloc = cp_lexer_peek_token (parser->lexer)->location;
   43151                 :         317 :       if (TREE_CODE (cmp_expr) == EQ_EXPR)
   43152                 :         208 :         rhs1 = cp_parser_expression (parser);
   43153                 :             :       else
   43154                 :         109 :         rhs1 = cp_parser_simple_cast_expression (parser);
   43155                 :             : 
   43156                 :         317 :       if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
   43157                 :           4 :         goto saw_error;
   43158                 :             : 
   43159                 :         313 :       if (!cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE))
   43160                 :           4 :         goto saw_error;
   43161                 :             : 
   43162                 :         309 :       extra_scope = false;
   43163                 :         309 :       no_semicolon = true;
   43164                 :             : 
   43165                 :         309 :       if (cp_tree_equal (TREE_OPERAND (cmp_expr, 0), lhs))
   43166                 :             :         {
   43167                 :         266 :           if (TREE_CODE (cmp_expr) == EQ_EXPR)
   43168                 :             :             {
   43169                 :         200 :               opcode = COND_EXPR;
   43170                 :         200 :               rhs = TREE_OPERAND (cmp_expr, 1);
   43171                 :             :             }
   43172                 :          66 :           else if (cp_tree_equal (TREE_OPERAND (cmp_expr, 1), rhs1))
   43173                 :             :             {
   43174                 :         116 :               opcode = (TREE_CODE (cmp_expr) == GT_EXPR
   43175                 :          58 :                         ? MIN_EXPR : MAX_EXPR);
   43176                 :          58 :               rhs = rhs1;
   43177                 :          58 :               rhs1 = TREE_OPERAND (cmp_expr, 0);
   43178                 :             :             }
   43179                 :             :           else
   43180                 :           8 :             goto bad_if;
   43181                 :             :         }
   43182                 :          43 :       else if (TREE_CODE (cmp_expr) == EQ_EXPR)
   43183                 :           8 :         goto bad_if;
   43184                 :          35 :       else if (cp_tree_equal (TREE_OPERAND (cmp_expr, 1), lhs)
   43185                 :          35 :                && cp_tree_equal (TREE_OPERAND (cmp_expr, 0), rhs1))
   43186                 :             :         {
   43187                 :          54 :           opcode = (TREE_CODE (cmp_expr) == GT_EXPR
   43188                 :          27 :                     ? MAX_EXPR : MIN_EXPR);
   43189                 :          27 :           rhs = rhs1;
   43190                 :          27 :           rhs1 = TREE_OPERAND (cmp_expr, 1);
   43191                 :             :         }
   43192                 :             :       else
   43193                 :             :         {
   43194                 :          32 :         bad_if:
   43195                 :          32 :           cp_parser_error (parser,
   43196                 :             :                            "invalid form of %<#pragma omp atomic compare%>");
   43197                 :          32 :           goto saw_error;
   43198                 :             :         }
   43199                 :             : 
   43200                 :         285 :       if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
   43201                 :             :         {
   43202                 :         100 :           if (code != OMP_ATOMIC_CAPTURE_NEW
   43203                 :          92 :               || (structured_block && r == NULL_TREE)
   43204                 :          88 :               || TREE_CODE (cmp_expr) != EQ_EXPR)
   43205                 :             :             {
   43206                 :          12 :               eloc = cp_lexer_peek_token (parser->lexer)->location;
   43207                 :          12 :               error_at (eloc, "unexpected %<else%>");
   43208                 :          12 :               goto saw_error;
   43209                 :             :             }
   43210                 :             : 
   43211                 :          88 :           cp_lexer_consume_token (parser->lexer);
   43212                 :             : 
   43213                 :          88 :           if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
   43214                 :           4 :             goto saw_error;
   43215                 :             : 
   43216                 :          84 :           extra_scope = true;
   43217                 :          84 :           v = cp_parser_unary_expression (parser);
   43218                 :          84 :           if (v == error_mark_node)
   43219                 :           0 :             goto saw_error;
   43220                 :          84 :           if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   43221                 :           4 :             goto saw_error;
   43222                 :             : 
   43223                 :          80 :           tree expr = cp_parser_simple_cast_expression (parser);
   43224                 :             : 
   43225                 :          80 :           if (!cp_tree_equal (expr, lhs))
   43226                 :           4 :             goto bad_if;
   43227                 :             : 
   43228                 :          76 :           if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
   43229                 :           4 :             goto saw_error;
   43230                 :             : 
   43231                 :          72 :           if (!cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE))
   43232                 :           0 :             goto saw_error;
   43233                 :             : 
   43234                 :          72 :           extra_scope = false;
   43235                 :          72 :           code = OMP_ATOMIC_CAPTURE_OLD;
   43236                 :          72 :           if (r == NULL_TREE)
   43237                 :             :             /* Signal to c_finish_omp_atomic that in
   43238                 :             :                if (x == e) { x = d; } else { v = x; }
   43239                 :             :                case the store to v should be conditional.  */
   43240                 :          42 :             r = void_list_node;
   43241                 :             :         }
   43242                 :         185 :       else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
   43243                 :             :         {
   43244                 :           4 :           cp_parser_error (parser, "expected %<else%>");
   43245                 :           4 :           goto saw_error;
   43246                 :             :         }
   43247                 :         181 :       else if (code == OMP_ATOMIC_CAPTURE_NEW
   43248                 :         181 :                && r != NULL_TREE
   43249                 :          40 :                && v == NULL_TREE)
   43250                 :         253 :         code = OMP_ATOMIC;
   43251                 :         253 :       goto stmt_done;
   43252                 :             :     }
   43253                 :        2888 :   lhs = cp_parser_unary_expression (parser);
   43254                 :        2888 :   orig_lhs = lhs;
   43255                 :        2888 :   switch (TREE_CODE (lhs))
   43256                 :             :     {
   43257                 :          24 :     case ERROR_MARK:
   43258                 :          24 :       goto saw_error;
   43259                 :             : 
   43260                 :         439 :     case POSTINCREMENT_EXPR:
   43261                 :         439 :       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
   43262                 :          59 :         code = OMP_ATOMIC_CAPTURE_OLD;
   43263                 :             :       /* FALLTHROUGH */
   43264                 :         526 :     case PREINCREMENT_EXPR:
   43265                 :         526 :       lhs = TREE_OPERAND (lhs, 0);
   43266                 :         526 :       opcode = PLUS_EXPR;
   43267                 :         526 :       rhs = integer_one_node;
   43268                 :         526 :       if (compare)
   43269                 :           8 :         goto invalid_compare;
   43270                 :             :       break;
   43271                 :             : 
   43272                 :          60 :     case POSTDECREMENT_EXPR:
   43273                 :          60 :       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
   43274                 :           2 :         code = OMP_ATOMIC_CAPTURE_OLD;
   43275                 :             :       /* FALLTHROUGH */
   43276                 :         111 :     case PREDECREMENT_EXPR:
   43277                 :         111 :       lhs = TREE_OPERAND (lhs, 0);
   43278                 :         111 :       opcode = MINUS_EXPR;
   43279                 :         111 :       rhs = integer_one_node;
   43280                 :         111 :       if (compare)
   43281                 :           8 :         goto invalid_compare;
   43282                 :             :       break;
   43283                 :             : 
   43284                 :           9 :     case COMPOUND_EXPR:
   43285                 :           9 :       if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
   43286                 :           9 :          && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
   43287                 :           9 :          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
   43288                 :           9 :          && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
   43289                 :          18 :          && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
   43290                 :             :                                              (TREE_OPERAND (lhs, 1), 0), 0)))
   43291                 :             :             == BOOLEAN_TYPE)
   43292                 :             :        /* Undo effects of boolean_increment for post {in,de}crement.  */
   43293                 :           9 :        lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
   43294                 :             :       /* FALLTHRU */
   43295                 :          18 :     case MODIFY_EXPR:
   43296                 :          18 :       if (TREE_CODE (lhs) == MODIFY_EXPR
   43297                 :          18 :          && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
   43298                 :             :         {
   43299                 :             :           /* Undo effects of boolean_increment.  */
   43300                 :          18 :           if (integer_onep (TREE_OPERAND (lhs, 1)))
   43301                 :             :             {
   43302                 :             :               /* This is pre or post increment.  */
   43303                 :          18 :               rhs = TREE_OPERAND (lhs, 1);
   43304                 :          18 :               lhs = TREE_OPERAND (lhs, 0);
   43305                 :          18 :               opcode = NOP_EXPR;
   43306                 :          18 :               if (code == OMP_ATOMIC_CAPTURE_NEW
   43307                 :          18 :                   && !structured_block
   43308                 :           2 :                   && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
   43309                 :           1 :                 code = OMP_ATOMIC_CAPTURE_OLD;
   43310                 :          18 :               if (compare)
   43311                 :           0 :                 goto invalid_compare;
   43312                 :             :               break;
   43313                 :             :             }
   43314                 :             :         }
   43315                 :             :       /* FALLTHRU */
   43316                 :        2209 :     default:
   43317                 :        2209 :       if (compare && !cp_lexer_next_token_is (parser->lexer, CPP_EQ))
   43318                 :             :         {
   43319                 :          28 :           cp_parser_error (parser, "expected %<=%>");
   43320                 :          28 :           goto saw_error;
   43321                 :             :         }
   43322                 :        2181 :       switch (cp_lexer_peek_token (parser->lexer)->type)
   43323                 :             :         {
   43324                 :             :         case CPP_MULT_EQ:
   43325                 :             :           opcode = MULT_EXPR;
   43326                 :             :           break;
   43327                 :             :         case CPP_DIV_EQ:
   43328                 :             :           opcode = TRUNC_DIV_EXPR;
   43329                 :             :           break;
   43330                 :             :         case CPP_PLUS_EQ:
   43331                 :             :           opcode = PLUS_EXPR;
   43332                 :             :           break;
   43333                 :             :         case CPP_MINUS_EQ:
   43334                 :             :           opcode = MINUS_EXPR;
   43335                 :             :           break;
   43336                 :             :         case CPP_LSHIFT_EQ:
   43337                 :             :           opcode = LSHIFT_EXPR;
   43338                 :             :           break;
   43339                 :             :         case CPP_RSHIFT_EQ:
   43340                 :             :           opcode = RSHIFT_EXPR;
   43341                 :             :           break;
   43342                 :             :         case CPP_AND_EQ:
   43343                 :             :           opcode = BIT_AND_EXPR;
   43344                 :             :           break;
   43345                 :             :         case CPP_OR_EQ:
   43346                 :             :           opcode = BIT_IOR_EXPR;
   43347                 :             :           break;
   43348                 :             :         case CPP_XOR_EQ:
   43349                 :             :           opcode = BIT_XOR_EXPR;
   43350                 :             :           break;
   43351                 :        1299 :         case CPP_EQ:
   43352                 :        1299 :           enum cp_parser_prec oprec;
   43353                 :        1299 :           cp_token *token;
   43354                 :        1299 :           cp_lexer_consume_token (parser->lexer);
   43355                 :        1299 :           cp_parser_parse_tentatively (parser);
   43356                 :        1299 :           rhs1 = cp_parser_simple_cast_expression (parser);
   43357                 :        1299 :           if (rhs1 == error_mark_node)
   43358                 :             :             {
   43359                 :           0 :               cp_parser_abort_tentative_parse (parser);
   43360                 :           0 :               cp_parser_simple_cast_expression (parser);
   43361                 :           0 :               goto saw_error;
   43362                 :             :             }
   43363                 :        1299 :           token = cp_lexer_peek_token (parser->lexer);
   43364                 :        1299 :           if (token->type != CPP_SEMICOLON
   43365                 :        1001 :               && (!compare || token->type != CPP_QUERY)
   43366                 :        2288 :               && !cp_tree_equal (lhs, rhs1))
   43367                 :             :             {
   43368                 :         370 :               cp_parser_abort_tentative_parse (parser);
   43369                 :         370 :               cp_parser_parse_tentatively (parser);
   43370                 :         370 :               rhs = cp_parser_binary_expression (parser, false, true,
   43371                 :             :                                                  PREC_NOT_OPERATOR, NULL);
   43372                 :         370 :               if (rhs == error_mark_node)
   43373                 :             :                 {
   43374                 :           0 :                   cp_parser_abort_tentative_parse (parser);
   43375                 :           0 :                   cp_parser_binary_expression (parser, false, true,
   43376                 :             :                                                PREC_NOT_OPERATOR, NULL);
   43377                 :           0 :                   goto saw_error;
   43378                 :             :                 }
   43379                 :         370 :               switch (TREE_CODE (rhs))
   43380                 :             :                 {
   43381                 :         167 :                 case MULT_EXPR:
   43382                 :         167 :                 case TRUNC_DIV_EXPR:
   43383                 :         167 :                 case RDIV_EXPR:
   43384                 :         167 :                 case PLUS_EXPR:
   43385                 :         167 :                 case MINUS_EXPR:
   43386                 :         167 :                 case LSHIFT_EXPR:
   43387                 :         167 :                 case RSHIFT_EXPR:
   43388                 :         167 :                 case BIT_AND_EXPR:
   43389                 :         167 :                 case BIT_IOR_EXPR:
   43390                 :         167 :                 case BIT_XOR_EXPR:
   43391                 :         167 :                   if (compare)
   43392                 :             :                     break;
   43393                 :         155 :                   if (cp_tree_equal (lhs, TREE_OPERAND (rhs, 1)))
   43394                 :             :                     {
   43395                 :         139 :                       if (cp_parser_parse_definitely (parser))
   43396                 :             :                         {
   43397                 :         139 :                           opcode = TREE_CODE (rhs);
   43398                 :         139 :                           rhs1 = TREE_OPERAND (rhs, 0);
   43399                 :         139 :                           rhs = TREE_OPERAND (rhs, 1);
   43400                 :         139 :                           goto stmt_done;
   43401                 :             :                         }
   43402                 :             :                       else
   43403                 :           0 :                         goto saw_error;
   43404                 :             :                     }
   43405                 :             :                   break;
   43406                 :          82 :                 case EQ_EXPR:
   43407                 :          82 :                   if (!compare
   43408                 :          82 :                       || code != OMP_ATOMIC_CAPTURE_NEW
   43409                 :          74 :                       || !structured_block
   43410                 :          74 :                       || v
   43411                 :          74 :                       || r)
   43412                 :             :                     break;
   43413                 :          74 :                   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
   43414                 :          74 :                       && cp_lexer_nth_token_is_keyword (parser->lexer,
   43415                 :             :                                                         2, RID_IF))
   43416                 :             :                     {
   43417                 :          74 :                       if (cp_parser_parse_definitely (parser))
   43418                 :             :                         {
   43419                 :          74 :                           r = lhs;
   43420                 :          74 :                           lhs = NULL_TREE;
   43421                 :          74 :                           rhs1 = NULL_TREE;
   43422                 :          74 :                           cp_lexer_consume_token (parser->lexer);
   43423                 :          74 :                           goto restart;
   43424                 :             :                         }
   43425                 :             :                     }
   43426                 :             :                   break;
   43427                 :          99 :                 case GT_EXPR:
   43428                 :          99 :                 case LT_EXPR:
   43429                 :          99 :                   if (compare
   43430                 :          99 :                       && cp_lexer_next_token_is (parser->lexer, CPP_QUERY)
   43431                 :          91 :                       && cp_tree_equal (lhs, TREE_OPERAND (rhs, 1))
   43432                 :         190 :                       && cp_parser_parse_definitely (parser))
   43433                 :             :                     {
   43434                 :          91 :                       opcode = TREE_CODE (rhs);
   43435                 :          91 :                       rhs1 = TREE_OPERAND (rhs, 0);
   43436                 :          91 :                       rhs = TREE_OPERAND (rhs, 1);
   43437                 :         281 :                      cond_expr:
   43438                 :         281 :                       cp_lexer_consume_token (parser->lexer);
   43439                 :         281 :                       bool saved_colon_corrects_to_scope_p
   43440                 :             :                         = parser->colon_corrects_to_scope_p;
   43441                 :         281 :                       parser->colon_corrects_to_scope_p = false;
   43442                 :         281 :                       tree e1 = cp_parser_expression (parser);
   43443                 :         281 :                       parser->colon_corrects_to_scope_p
   43444                 :         281 :                         = saved_colon_corrects_to_scope_p;
   43445                 :         281 :                       cp_parser_require (parser, CPP_COLON, RT_COLON);
   43446                 :         281 :                       tree e2 = cp_parser_simple_cast_expression (parser);
   43447                 :         281 :                       if (cp_tree_equal (lhs, e2))
   43448                 :             :                         {
   43449                 :         265 :                           if (cp_tree_equal (lhs, rhs1))
   43450                 :             :                             {
   43451                 :         174 :                               if (opcode == EQ_EXPR)
   43452                 :             :                                 {
   43453                 :         104 :                                   opcode = COND_EXPR;
   43454                 :         104 :                                   rhs1 = e1;
   43455                 :         104 :                                   goto stmt_done;
   43456                 :             :                                 }
   43457                 :          70 :                               if (cp_tree_equal (rhs, e1))
   43458                 :             :                                 {
   43459                 :          62 :                                   opcode
   43460                 :          62 :                                     = opcode == GT_EXPR ? MIN_EXPR : MAX_EXPR;
   43461                 :          62 :                                   rhs = e1;
   43462                 :          62 :                                   goto stmt_done;
   43463                 :             :                                 }
   43464                 :             :                             }
   43465                 :             :                           else
   43466                 :             :                             {
   43467                 :          91 :                               gcc_assert (opcode != EQ_EXPR);
   43468                 :          91 :                               if (cp_tree_equal (rhs1, e1))
   43469                 :             :                                 {
   43470                 :          91 :                                   opcode
   43471                 :          91 :                                     = opcode == GT_EXPR ? MAX_EXPR : MIN_EXPR;
   43472                 :          91 :                                   rhs1 = rhs;
   43473                 :          91 :                                   rhs = e1;
   43474                 :          91 :                                   goto stmt_done;
   43475                 :             :                                 }
   43476                 :             :                             }
   43477                 :             :                         }
   43478                 :          24 :                       cp_parser_error (parser,
   43479                 :             :                                        "invalid form of "
   43480                 :             :                                        "%<#pragma omp atomic compare%>");
   43481                 :          24 :                       goto saw_error;
   43482                 :             :                     }
   43483                 :             :                   break;
   43484                 :             :                 default:
   43485                 :             :                   break;
   43486                 :             :                 }
   43487                 :          66 :               cp_parser_abort_tentative_parse (parser);
   43488                 :          66 :               if (structured_block
   43489                 :          66 :                   && code == OMP_ATOMIC_CAPTURE_OLD
   43490                 :          22 :                   && !compare)
   43491                 :             :                 {
   43492                 :          18 :                   rhs = cp_parser_expression (parser);
   43493                 :          18 :                   if (rhs == error_mark_node)
   43494                 :           0 :                     goto saw_error;
   43495                 :          18 :                   opcode = NOP_EXPR;
   43496                 :          18 :                   rhs1 = NULL_TREE;
   43497                 :          18 :                   goto stmt_done;
   43498                 :             :                 }
   43499                 :          48 :               cp_parser_error (parser,
   43500                 :             :                                "invalid form of %<#pragma omp atomic%>");
   43501                 :          48 :               goto saw_error;
   43502                 :             :             }
   43503                 :         929 :           if (!cp_parser_parse_definitely (parser))
   43504                 :           0 :             goto saw_error;
   43505                 :         929 :           switch (token->type)
   43506                 :             :             {
   43507                 :         298 :             case CPP_SEMICOLON:
   43508                 :         298 :               if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
   43509                 :             :                 {
   43510                 :         280 :                   code = OMP_ATOMIC_CAPTURE_OLD;
   43511                 :         280 :                   v = lhs;
   43512                 :         280 :                   lhs = NULL_TREE;
   43513                 :         280 :                   lhs1 = rhs1;
   43514                 :         280 :                   rhs1 = NULL_TREE;
   43515                 :         280 :                   cp_lexer_consume_token (parser->lexer);
   43516                 :         280 :                   goto restart;
   43517                 :             :                 }
   43518                 :          18 :               else if (structured_block && !compare)
   43519                 :             :                 {
   43520                 :          10 :                   opcode = NOP_EXPR;
   43521                 :          10 :                   rhs = rhs1;
   43522                 :          10 :                   rhs1 = NULL_TREE;
   43523                 :          10 :                   goto stmt_done;
   43524                 :             :                 }
   43525                 :           8 :               cp_parser_error (parser,
   43526                 :             :                                "invalid form of %<#pragma omp atomic%>");
   43527                 :           8 :               goto saw_error;
   43528                 :             :             case CPP_MULT:
   43529                 :             :               opcode = MULT_EXPR;
   43530                 :             :               break;
   43531                 :             :             case CPP_DIV:
   43532                 :             :               opcode = TRUNC_DIV_EXPR;
   43533                 :             :               break;
   43534                 :             :             case CPP_PLUS:
   43535                 :             :               opcode = PLUS_EXPR;
   43536                 :             :               break;
   43537                 :             :             case CPP_MINUS:
   43538                 :             :               opcode = MINUS_EXPR;
   43539                 :             :               break;
   43540                 :             :             case CPP_LSHIFT:
   43541                 :             :               opcode = LSHIFT_EXPR;
   43542                 :             :               break;
   43543                 :             :             case CPP_RSHIFT:
   43544                 :             :               opcode = RSHIFT_EXPR;
   43545                 :             :               break;
   43546                 :             :             case CPP_AND:
   43547                 :             :               opcode = BIT_AND_EXPR;
   43548                 :             :               break;
   43549                 :             :             case CPP_OR:
   43550                 :             :               opcode = BIT_IOR_EXPR;
   43551                 :             :               break;
   43552                 :             :             case CPP_XOR:
   43553                 :             :               opcode = BIT_XOR_EXPR;
   43554                 :             :               break;
   43555                 :             :             case CPP_EQ_EQ:
   43556                 :             :               opcode = EQ_EXPR;
   43557                 :             :               break;
   43558                 :             :             case CPP_GREATER:
   43559                 :             :               opcode = GT_EXPR;
   43560                 :             :               break;
   43561                 :             :             case CPP_LESS:
   43562                 :             :               opcode = LT_EXPR;
   43563                 :             :               break;
   43564                 :          24 :             default:
   43565                 :          24 :               cp_parser_error (parser,
   43566                 :             :                                "invalid operator for %<#pragma omp atomic%>");
   43567                 :          24 :               goto saw_error;
   43568                 :             :             }
   43569                 :         607 :           if (compare
   43570                 :         206 :               && TREE_CODE_CLASS (opcode) != tcc_comparison)
   43571                 :             :             {
   43572                 :          16 :               cp_parser_error (parser,
   43573                 :             :                                "invalid form of "
   43574                 :             :                                "%<#pragma omp atomic compare%>");
   43575                 :          16 :               goto saw_error;
   43576                 :             :             }
   43577                 :         591 :           oprec = TOKEN_PRECEDENCE (token);
   43578                 :         591 :           gcc_assert (oprec != PREC_NOT_OPERATOR);
   43579                 :         591 :           if (commutative_tree_code (opcode))
   43580                 :         435 :             oprec = (enum cp_parser_prec) (oprec - 1);
   43581                 :         591 :           cp_lexer_consume_token (parser->lexer);
   43582                 :         591 :           rhs = cp_parser_binary_expression (parser, false, false,
   43583                 :             :                                              oprec, NULL);
   43584                 :         591 :           if (rhs == error_mark_node)
   43585                 :           0 :             goto saw_error;
   43586                 :         591 :           if (compare)
   43587                 :             :             {
   43588                 :         190 :               if (!cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
   43589                 :             :                 {
   43590                 :           0 :                   cp_parser_error (parser,
   43591                 :             :                                    "invalid form of "
   43592                 :             :                                    "%<#pragma omp atomic compare%>");
   43593                 :           0 :                   goto saw_error;
   43594                 :             :                 }
   43595                 :         190 :               goto cond_expr;
   43596                 :             :             }
   43597                 :         401 :           goto stmt_done;
   43598                 :          12 :         default:
   43599                 :          12 :           cp_parser_error (parser,
   43600                 :             :                            "invalid operator for %<#pragma omp atomic%>");
   43601                 :          12 :           goto saw_error;
   43602                 :             :         }
   43603                 :         870 :       cp_lexer_consume_token (parser->lexer);
   43604                 :             : 
   43605                 :         870 :       rhs = cp_parser_expression (parser);
   43606                 :         870 :       if (rhs == error_mark_node)
   43607                 :           0 :         goto saw_error;
   43608                 :             :       break;
   43609                 :             :     }
   43610                 :        2587 : stmt_done:
   43611                 :        2587 :   if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
   43612                 :             :     {
   43613                 :         204 :       if (!no_semicolon
   43614                 :         204 :           && !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
   43615                 :          16 :         goto saw_error;
   43616                 :         188 :       no_semicolon = false;
   43617                 :         188 :       v = cp_parser_unary_expression (parser);
   43618                 :         188 :       if (v == error_mark_node)
   43619                 :           0 :         goto saw_error;
   43620                 :         188 :       if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   43621                 :           0 :         goto saw_error;
   43622                 :         188 :       lhs1 = cp_parser_unary_expression (parser);
   43623                 :         188 :       if (lhs1 == error_mark_node)
   43624                 :           0 :         goto saw_error;
   43625                 :             :     }
   43626                 :        2571 :   if (structured_block)
   43627                 :             :     {
   43628                 :         530 :       if (!no_semicolon)
   43629                 :         418 :         cp_parser_consume_semicolon_at_end_of_statement (parser);
   43630                 :         530 :       cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
   43631                 :             :     }
   43632                 :        2041 : done:
   43633                 :        3332 :   if (weak && opcode != COND_EXPR)
   43634                 :             :     {
   43635                 :           4 :       error_at (loc, "%<weak%> clause requires atomic equality comparison");
   43636                 :           4 :       weak = false;
   43637                 :             :     }
   43638                 :        3332 :   clauses = finish_omp_clauses (clauses, C_ORT_OMP);
   43639                 :        3332 :   finish_omp_atomic (pragma_tok->location, code, opcode, lhs, rhs, v, lhs1,
   43640                 :             :                      rhs1, r, clauses, memory_order, weak);
   43641                 :        3332 :   if (!structured_block && !no_semicolon)
   43642                 :        2706 :     cp_parser_consume_semicolon_at_end_of_statement (parser);
   43643                 :             :   return;
   43644                 :             : 
   43645                 :          16 :  invalid_compare:
   43646                 :          16 :   error ("invalid form of %<pragma omp atomic compare%>");
   43647                 :             :   /* FALLTHRU */
   43648                 :         328 :  saw_error:
   43649                 :         328 :   cp_parser_skip_to_end_of_block_or_statement (parser);
   43650                 :         328 :   if (extra_scope && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   43651                 :          24 :     cp_lexer_consume_token (parser->lexer);
   43652                 :         328 :   if (structured_block)
   43653                 :             :     {
   43654                 :          56 :       if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   43655                 :          12 :         cp_lexer_consume_token (parser->lexer);
   43656                 :          44 :       else if (code == OMP_ATOMIC_CAPTURE_NEW)
   43657                 :             :         {
   43658                 :          44 :           cp_parser_skip_to_end_of_block_or_statement (parser);
   43659                 :          44 :           if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   43660                 :          44 :             cp_lexer_consume_token (parser->lexer);
   43661                 :             :         }
   43662                 :             :     }
   43663                 :             : }
   43664                 :             : 
   43665                 :             : 
   43666                 :             : /* OpenMP 2.5:
   43667                 :             :    # pragma omp barrier new-line  */
   43668                 :             : 
   43669                 :             : static void
   43670                 :         558 : cp_parser_omp_barrier (cp_parser *parser, cp_token *pragma_tok)
   43671                 :             : {
   43672                 :           0 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   43673                 :           0 :   finish_omp_barrier ();
   43674                 :           0 : }
   43675                 :             : 
   43676                 :             : /* OpenMP 2.5:
   43677                 :             :    # pragma omp critical [(name)] new-line
   43678                 :             :      structured-block
   43679                 :             : 
   43680                 :             :    OpenMP 4.5:
   43681                 :             :    # pragma omp critical [(name) [hint(expression)]] new-line
   43682                 :             :      structured-block  */
   43683                 :             : 
   43684                 :             : #define OMP_CRITICAL_CLAUSE_MASK                \
   43685                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
   43686                 :             : 
   43687                 :             : static tree
   43688                 :         330 : cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   43689                 :             : {
   43690                 :         330 :   tree stmt, name = NULL_TREE, clauses = NULL_TREE;
   43691                 :             : 
   43692                 :         330 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   43693                 :             :     {
   43694                 :          92 :       matching_parens parens;
   43695                 :          92 :       parens.consume_open (parser);
   43696                 :             : 
   43697                 :          92 :       name = cp_parser_identifier (parser);
   43698                 :             : 
   43699                 :          92 :       if (name == error_mark_node
   43700                 :         180 :           || !parens.require_close (parser))
   43701                 :          12 :         cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   43702                 :             :                                                /*or_comma=*/false,
   43703                 :             :                                                /*consume_paren=*/true);
   43704                 :          92 :       if (name == error_mark_node)
   43705                 :           4 :         name = NULL;
   43706                 :             : 
   43707                 :          92 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   43708                 :          92 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   43709                 :          27 :         cp_lexer_consume_token (parser->lexer);
   43710                 :             :     }
   43711                 :             : 
   43712                 :         330 :   clauses = cp_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
   43713                 :             :                                        "#pragma omp critical", pragma_tok);
   43714                 :             : 
   43715                 :         330 :   stmt = cp_parser_omp_structured_block (parser, if_p);
   43716                 :         330 :   return c_finish_omp_critical (input_location, stmt, name, clauses);
   43717                 :             : }
   43718                 :             : 
   43719                 :             : /* OpenMP 5.0:
   43720                 :             :    # pragma omp depobj ( depobj ) depobj-clause new-line
   43721                 :             : 
   43722                 :             :    depobj-clause:
   43723                 :             :      depend (dependence-type : locator)
   43724                 :             :      destroy
   43725                 :             :      update (dependence-type)
   43726                 :             : 
   43727                 :             :    OpenMP 5.2 additionally:
   43728                 :             :      destroy ( depobj )
   43729                 :             : 
   43730                 :             :    dependence-type:
   43731                 :             :      in
   43732                 :             :      out
   43733                 :             :      inout
   43734                 :             :      mutexinout  */
   43735                 :             : 
   43736                 :             : static void
   43737                 :         375 : cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
   43738                 :             : {
   43739                 :         375 :   location_t loc = pragma_tok->location;
   43740                 :         375 :   matching_parens parens;
   43741                 :         375 :   if (!parens.require_open (parser))
   43742                 :             :     {
   43743                 :          20 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   43744                 :          20 :       return;
   43745                 :             :     }
   43746                 :             : 
   43747                 :         355 :   tree depobj = cp_parser_assignment_expression (parser);
   43748                 :             : 
   43749                 :         355 :   if (!parens.require_close (parser))
   43750                 :           0 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   43751                 :             :                                            /*or_comma=*/false,
   43752                 :             :                                            /*consume_paren=*/true);
   43753                 :             : 
   43754                 :         355 :   tree clause = NULL_TREE;
   43755                 :         355 :   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
   43756                 :         355 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   43757                 :          10 :     cp_lexer_consume_token (parser->lexer);
   43758                 :         355 :   location_t c_loc = cp_lexer_peek_token (parser->lexer)->location;
   43759                 :         355 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   43760                 :             :     {
   43761                 :         347 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   43762                 :         347 :       const char *p = IDENTIFIER_POINTER (id);
   43763                 :             : 
   43764                 :         347 :       cp_lexer_consume_token (parser->lexer);
   43765                 :         347 :       if (!strcmp ("depend", p))
   43766                 :             :         {
   43767                 :             :           /* Don't create location wrapper nodes within the depend clause.  */
   43768                 :         186 :           auto_suppress_location_wrappers sentinel;
   43769                 :         186 :           clause = cp_parser_omp_clause_depend (parser, NULL_TREE, c_loc);
   43770                 :         186 :           if (clause)
   43771                 :         186 :             clause = finish_omp_clauses (clause, C_ORT_OMP);
   43772                 :         186 :           if (!clause)
   43773                 :          12 :             clause = error_mark_node;
   43774                 :             :         }
   43775                 :         161 :       else if (!strcmp ("destroy", p))
   43776                 :             :         {
   43777                 :          93 :           kind = OMP_CLAUSE_DEPEND_LAST;
   43778                 :          93 :           matching_parens c_parens;
   43779                 :          93 :           if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
   43780                 :          93 :               && c_parens.require_open (parser))
   43781                 :             :             {
   43782                 :          28 :               tree destobj = cp_parser_assignment_expression (parser);
   43783                 :          28 :               if (depobj != error_mark_node
   43784                 :          24 :                   && destobj != error_mark_node
   43785                 :          52 :                   && !operand_equal_p (destobj, depobj, OEP_MATCH_SIDE_EFFECTS
   43786                 :             :                                                         | OEP_LEXICOGRAPHIC))
   43787                 :          12 :                 warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
   43788                 :             :                             "the %<destroy%> expression %qE should be the same "
   43789                 :             :                             "as the %<depobj%> argument %qE", destobj, depobj);
   43790                 :          28 :               if (!c_parens.require_close (parser))
   43791                 :           0 :                 cp_parser_skip_to_closing_parenthesis (parser,
   43792                 :             :                                                        /*recovering=*/true,
   43793                 :             :                                                        /*or_comma=*/false,
   43794                 :             :                                                        /*consume_paren=*/true);
   43795                 :             :             }
   43796                 :             :         }
   43797                 :          68 :       else if (!strcmp ("update", p))
   43798                 :             :         {
   43799                 :          60 :           matching_parens c_parens;
   43800                 :          60 :           if (c_parens.require_open (parser))
   43801                 :             :             {
   43802                 :          60 :               location_t c2_loc
   43803                 :          60 :                 = cp_lexer_peek_token (parser->lexer)->location;
   43804                 :          60 :               if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   43805                 :             :                 {
   43806                 :          60 :                   tree id2 = cp_lexer_peek_token (parser->lexer)->u.value;
   43807                 :          60 :                   const char *p2 = IDENTIFIER_POINTER (id2);
   43808                 :             : 
   43809                 :          60 :                   cp_lexer_consume_token (parser->lexer);
   43810                 :          60 :                   if (!strcmp ("in", p2))
   43811                 :             :                     kind = OMP_CLAUSE_DEPEND_IN;
   43812                 :          50 :                   else if (!strcmp ("out", p2))
   43813                 :             :                     kind = OMP_CLAUSE_DEPEND_OUT;
   43814                 :          48 :                   else if (!strcmp ("inout", p2))
   43815                 :             :                     kind = OMP_CLAUSE_DEPEND_INOUT;
   43816                 :          17 :                   else if (!strcmp ("mutexinoutset", p2))
   43817                 :             :                     kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
   43818                 :          13 :                   else if (!strcmp ("inoutset", p2))
   43819                 :             :                     kind = OMP_CLAUSE_DEPEND_INOUTSET;
   43820                 :             :                 }
   43821                 :             :               if (kind == OMP_CLAUSE_DEPEND_INVALID)
   43822                 :             :                 {
   43823                 :           8 :                   clause = error_mark_node;
   43824                 :           8 :                   error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
   43825                 :             :                                     "%<mutexinoutset%> or %<inoutset%>");
   43826                 :             :                 }
   43827                 :          60 :               if (!c_parens.require_close (parser))
   43828                 :           0 :                 cp_parser_skip_to_closing_parenthesis (parser,
   43829                 :             :                                                        /*recovering=*/true,
   43830                 :             :                                                        /*or_comma=*/false,
   43831                 :             :                                                        /*consume_paren=*/true);
   43832                 :             :             }
   43833                 :             :           else
   43834                 :           0 :             clause = error_mark_node;
   43835                 :             :         }
   43836                 :             :     }
   43837                 :         355 :   if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
   43838                 :             :     {
   43839                 :          16 :       clause = error_mark_node;
   43840                 :          16 :       error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
   43841                 :             :     }
   43842                 :         355 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   43843                 :             : 
   43844                 :         355 :   finish_omp_depobj (loc, depobj, kind, clause);
   43845                 :             : }
   43846                 :             : 
   43847                 :             : 
   43848                 :             : /* OpenMP 2.5:
   43849                 :             :    # pragma omp flush flush-vars[opt] new-line
   43850                 :             : 
   43851                 :             :    flush-vars:
   43852                 :             :      ( variable-list )
   43853                 :             : 
   43854                 :             :    OpenMP 5.0:
   43855                 :             :    # pragma omp flush memory-order-clause new-line  */
   43856                 :             : 
   43857                 :             : static void
   43858                 :         188 : cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
   43859                 :             : {
   43860                 :         188 :   enum memmodel mo = MEMMODEL_LAST;
   43861                 :         188 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   43862                 :         188 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   43863                 :          28 :     cp_lexer_consume_token (parser->lexer);
   43864                 :         188 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   43865                 :             :     {
   43866                 :         100 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   43867                 :         100 :       const char *p = IDENTIFIER_POINTER (id);
   43868                 :         100 :       if (!strcmp (p, "seq_cst"))
   43869                 :             :         mo = MEMMODEL_SEQ_CST;
   43870                 :          78 :       else if (!strcmp (p, "acq_rel"))
   43871                 :             :         mo = MEMMODEL_ACQ_REL;
   43872                 :          56 :       else if (!strcmp (p, "release"))
   43873                 :             :         mo = MEMMODEL_RELEASE;
   43874                 :          34 :       else if (!strcmp (p, "acquire"))
   43875                 :             :         mo = MEMMODEL_ACQUIRE;
   43876                 :             :       else
   43877                 :          12 :         error_at (cp_lexer_peek_token (parser->lexer)->location,
   43878                 :             :                   "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
   43879                 :             :                   "%<acquire%>");
   43880                 :         100 :       cp_lexer_consume_token (parser->lexer);
   43881                 :             :     }
   43882                 :         188 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   43883                 :             :     {
   43884                 :          54 :       if (mo != MEMMODEL_LAST)
   43885                 :          16 :         error_at (cp_lexer_peek_token (parser->lexer)->location,
   43886                 :             :                   "%<flush%> list specified together with memory order "
   43887                 :             :                   "clause");
   43888                 :          54 :       (void) cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
   43889                 :             :     }
   43890                 :         188 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   43891                 :             : 
   43892                 :         188 :   finish_omp_flush (mo);
   43893                 :         188 : }
   43894                 :             : 
   43895                 :             : /* Helper function, to parse omp for increment expression.  */
   43896                 :             : 
   43897                 :             : static tree
   43898                 :       26108 : cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
   43899                 :             : {
   43900                 :       26108 :   tree cond = cp_parser_binary_expression (parser, false, true,
   43901                 :             :                                            PREC_NOT_OPERATOR, NULL);
   43902                 :       26108 :   if (cond == error_mark_node
   43903                 :       26108 :       || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   43904                 :             :     {
   43905                 :          16 :       cp_parser_skip_to_end_of_statement (parser);
   43906                 :          16 :       return error_mark_node;
   43907                 :             :     }
   43908                 :             : 
   43909                 :       26092 :   switch (TREE_CODE (cond))
   43910                 :             :     {
   43911                 :             :     case GT_EXPR:
   43912                 :             :     case GE_EXPR:
   43913                 :             :     case LT_EXPR:
   43914                 :             :     case LE_EXPR:
   43915                 :             :       break;
   43916                 :        2730 :     case NE_EXPR:
   43917                 :        2730 :       if (code != OACC_LOOP)
   43918                 :             :         break;
   43919                 :             :       gcc_fallthrough ();
   43920                 :             :     default:
   43921                 :             :       return error_mark_node;
   43922                 :             :     }
   43923                 :             : 
   43924                 :             :   /* If decl is an iterator, preserve LHS and RHS of the relational
   43925                 :             :      expr until finish_omp_for.  */
   43926                 :       26064 :   if (decl
   43927                 :       26064 :       && (type_dependent_expression_p (decl)
   43928                 :        7767 :           || CLASS_TYPE_P (TREE_TYPE (decl))))
   43929                 :             :     return cond;
   43930                 :             : 
   43931                 :       24978 :   return build_x_binary_op (cp_expr_loc_or_input_loc (cond),
   43932                 :       24978 :                             TREE_CODE (cond),
   43933                 :       24978 :                             TREE_OPERAND (cond, 0), ERROR_MARK,
   43934                 :       24978 :                             TREE_OPERAND (cond, 1), ERROR_MARK,
   43935                 :             :                             NULL_TREE, /*overload=*/NULL, tf_warning_or_error);
   43936                 :             : }
   43937                 :             : 
   43938                 :             : /* Helper function, to parse omp for increment expression.  */
   43939                 :             : 
   43940                 :             : static tree
   43941                 :        2079 : cp_parser_omp_for_incr (cp_parser *parser, tree decl)
   43942                 :             : {
   43943                 :        2079 :   cp_token *token = cp_lexer_peek_token (parser->lexer);
   43944                 :        2079 :   enum tree_code op;
   43945                 :        2079 :   tree lhs, rhs;
   43946                 :        2079 :   cp_id_kind idk;
   43947                 :        2079 :   bool decl_first;
   43948                 :             : 
   43949                 :        2079 :   if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
   43950                 :             :     {
   43951                 :         550 :       op = (token->type == CPP_PLUS_PLUS
   43952                 :         275 :             ? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
   43953                 :         275 :       cp_lexer_consume_token (parser->lexer);
   43954                 :         275 :       lhs = cp_parser_simple_cast_expression (parser);
   43955                 :         275 :       if (lhs != decl
   43956                 :         275 :           && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
   43957                 :           0 :         return error_mark_node;
   43958                 :         275 :       return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
   43959                 :             :     }
   43960                 :             : 
   43961                 :        1804 :   lhs = cp_parser_primary_expression (parser, false, false, false, &idk);
   43962                 :        1804 :   if (lhs != decl
   43963                 :        1804 :       && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
   43964                 :           4 :     return error_mark_node;
   43965                 :             : 
   43966                 :        1800 :   token = cp_lexer_peek_token (parser->lexer);
   43967                 :        1800 :   if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
   43968                 :             :     {
   43969                 :        2218 :       op = (token->type == CPP_PLUS_PLUS
   43970                 :        1109 :             ? POSTINCREMENT_EXPR : POSTDECREMENT_EXPR);
   43971                 :        1109 :       cp_lexer_consume_token (parser->lexer);
   43972                 :        1109 :       return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
   43973                 :             :     }
   43974                 :             : 
   43975                 :         691 :   op = cp_parser_assignment_operator_opt (parser);
   43976                 :         691 :   if (op == ERROR_MARK)
   43977                 :           0 :     return error_mark_node;
   43978                 :             : 
   43979                 :         691 :   if (op != NOP_EXPR)
   43980                 :             :     {
   43981                 :         281 :       rhs = cp_parser_assignment_expression (parser);
   43982                 :         281 :       rhs = build2 (op, TREE_TYPE (decl), decl, rhs);
   43983                 :         281 :       return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
   43984                 :             :     }
   43985                 :             : 
   43986                 :         410 :   lhs = cp_parser_binary_expression (parser, false, false,
   43987                 :             :                                      PREC_ADDITIVE_EXPRESSION, NULL);
   43988                 :         410 :   token = cp_lexer_peek_token (parser->lexer);
   43989                 :         410 :   decl_first = (lhs == decl
   43990                 :         410 :                 || (processing_template_decl && cp_tree_equal (lhs, decl)));
   43991                 :             :   if (decl_first)
   43992                 :             :     lhs = NULL_TREE;
   43993                 :         410 :   if (token->type != CPP_PLUS
   43994                 :         410 :       && token->type != CPP_MINUS)
   43995                 :           0 :     return error_mark_node;
   43996                 :             : 
   43997                 :         468 :   do
   43998                 :             :     {
   43999                 :         468 :       op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
   44000                 :         468 :       cp_lexer_consume_token (parser->lexer);
   44001                 :         468 :       rhs = cp_parser_binary_expression (parser, false, false,
   44002                 :             :                                          PREC_ADDITIVE_EXPRESSION, NULL);
   44003                 :         468 :       token = cp_lexer_peek_token (parser->lexer);
   44004                 :         468 :       if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
   44005                 :             :         {
   44006                 :         322 :           if (lhs == NULL_TREE)
   44007                 :             :             {
   44008                 :         264 :               if (op == PLUS_EXPR)
   44009                 :             :                 lhs = rhs;
   44010                 :             :               else
   44011                 :          48 :                 lhs = build_x_unary_op (input_location, NEGATE_EXPR, rhs,
   44012                 :             :                                         NULL_TREE, tf_warning_or_error);
   44013                 :             :             }
   44014                 :             :           else
   44015                 :          58 :             lhs = build_x_binary_op (input_location, op,
   44016                 :             :                                      lhs, ERROR_MARK,
   44017                 :             :                                      rhs, ERROR_MARK,
   44018                 :             :                                      NULL_TREE, NULL, tf_warning_or_error);
   44019                 :             :         }
   44020                 :             :     }
   44021                 :         468 :   while (token->type == CPP_PLUS || token->type == CPP_MINUS);
   44022                 :             : 
   44023                 :         410 :   if (!decl_first)
   44024                 :             :     {
   44025                 :         146 :       if ((rhs != decl
   44026                 :           0 :            && (!processing_template_decl || !cp_tree_equal (rhs, decl)))
   44027                 :         146 :           || op == MINUS_EXPR)
   44028                 :           0 :         return error_mark_node;
   44029                 :         146 :       rhs = build2 (op, TREE_TYPE (decl), lhs, decl);
   44030                 :             :     }
   44031                 :             :   else
   44032                 :         264 :     rhs = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, lhs);
   44033                 :             : 
   44034                 :         410 :   return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
   44035                 :             : }
   44036                 :             : 
   44037                 :             : /* Parse the initialization statement of an OpenMP for loop.  Range-for
   44038                 :             :    is handled separately in cp_convert_omp_range_for.
   44039                 :             : 
   44040                 :             :    On entry SL is the current statement list.  Parsing of some forms
   44041                 :             :    of initialization pops this list and stores its contents in either INIT
   44042                 :             :    or THIS_PRE_BODY, and sets SL to null.  Initialization for class
   44043                 :             :    iterators is added directly to SL and it is not popped until later.
   44044                 :             : 
   44045                 :             :    On return, DECL is set if the initialization is by binding the
   44046                 :             :    iteration variable.  If the initialization is by assignment, REAL_DECL
   44047                 :             :    is set to point to a variable in an outer scope.  ORIG_INIT is set
   44048                 :             :    if the iteration variable is of class type; this is a copy saved for
   44049                 :             :    error checking in finish_omp_for.
   44050                 :             : 
   44051                 :             :    Return true if the resulting construct should have an
   44052                 :             :    OMP_CLAUSE_PRIVATE added to it.  */
   44053                 :             : 
   44054                 :             : static tree
   44055                 :       26124 : cp_parser_omp_for_loop_init (cp_parser *parser,
   44056                 :             :                              tree &this_pre_body,
   44057                 :             :                              tree &sl,
   44058                 :             :                              tree &init,
   44059                 :             :                              tree &orig_init,
   44060                 :             :                              tree &decl,
   44061                 :             :                              tree &real_decl)
   44062                 :             : {
   44063                 :       26124 :   if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
   44064                 :             :     return NULL_TREE;
   44065                 :             : 
   44066                 :       26120 :   tree add_private_clause = NULL_TREE;
   44067                 :             : 
   44068                 :             :   /* See 2.5.1 (in OpenMP 3.0, similar wording is in 2.5 standard too):
   44069                 :             : 
   44070                 :             :      init-expr:
   44071                 :             :      var = lb
   44072                 :             :      integer-type var = lb
   44073                 :             :      random-access-iterator-type var = lb
   44074                 :             :      pointer-type var = lb
   44075                 :             :   */
   44076                 :       26120 :   cp_decl_specifier_seq type_specifiers;
   44077                 :             : 
   44078                 :             :   /* First, try to parse as an initialized declaration.  See
   44079                 :             :      cp_parser_condition, from whence the bulk of this is copied.  */
   44080                 :             : 
   44081                 :       26120 :   cp_parser_parse_tentatively (parser);
   44082                 :       26120 :   cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
   44083                 :             :                                 /*is_declaration=*/true,
   44084                 :             :                                 /*is_trailing_return=*/false,
   44085                 :             :                                 &type_specifiers);
   44086                 :       26120 :   if (cp_parser_parse_definitely (parser))
   44087                 :             :     {
   44088                 :             :       /* If parsing a type specifier seq succeeded, then this
   44089                 :             :          MUST be a initialized declaration.  */
   44090                 :        7559 :       tree asm_specification, attributes;
   44091                 :        7559 :       cp_declarator *declarator;
   44092                 :             : 
   44093                 :        7559 :       declarator = cp_parser_declarator (parser,
   44094                 :             :                                          CP_PARSER_DECLARATOR_NAMED,
   44095                 :             :                                          CP_PARSER_FLAGS_NONE,
   44096                 :             :                                          /*ctor_dtor_or_conv_p=*/NULL,
   44097                 :             :                                          /*parenthesized_p=*/NULL,
   44098                 :             :                                          /*member_p=*/false,
   44099                 :             :                                          /*friend_p=*/false,
   44100                 :             :                                          /*static_p=*/false);
   44101                 :        7559 :       attributes = cp_parser_attributes_opt (parser);
   44102                 :        7559 :       asm_specification = cp_parser_asm_specification_opt (parser);
   44103                 :             : 
   44104                 :        7559 :       if (declarator == cp_error_declarator)
   44105                 :           0 :         cp_parser_skip_to_end_of_statement (parser);
   44106                 :             : 
   44107                 :             :       else
   44108                 :             :         {
   44109                 :        7559 :           tree pushed_scope, auto_node;
   44110                 :             : 
   44111                 :        7559 :           decl = start_decl (declarator, &type_specifiers,
   44112                 :             :                              SD_INITIALIZED, attributes,
   44113                 :             :                              /*prefix_attributes=*/NULL_TREE,
   44114                 :             :                              &pushed_scope);
   44115                 :             : 
   44116                 :        7559 :           auto_node = type_uses_auto (TREE_TYPE (decl));
   44117                 :        7559 :           if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
   44118                 :             :             {
   44119                 :           8 :               if (cp_lexer_next_token_is (parser->lexer,
   44120                 :             :                                           CPP_OPEN_PAREN))
   44121                 :           4 :                 error ("parenthesized initialization is not allowed in "
   44122                 :             :                        "OpenMP %<for%> loop");
   44123                 :             :               else
   44124                 :             :                 /* Trigger an error.  */
   44125                 :           4 :                 cp_parser_require (parser, CPP_EQ, RT_EQ);
   44126                 :             : 
   44127                 :           8 :               init = error_mark_node;
   44128                 :           8 :               cp_parser_skip_to_end_of_statement (parser);
   44129                 :             :             }
   44130                 :       15102 :           else if (CLASS_TYPE_P (TREE_TYPE (decl))
   44131                 :        7275 :                    || type_dependent_expression_p (decl)
   44132                 :       14547 :                    || auto_node)
   44133                 :             :             {
   44134                 :         570 :               bool is_non_constant_init;
   44135                 :             : 
   44136                 :         570 :               init = cp_parser_initializer (parser,
   44137                 :             :                                             /*is_direct_init=*/nullptr,
   44138                 :             :                                             &is_non_constant_init);
   44139                 :             : 
   44140                 :         570 :               if (auto_node)
   44141                 :             :                 {
   44142                 :          22 :                   TREE_TYPE (decl)
   44143                 :          22 :                     = do_auto_deduction (TREE_TYPE (decl), init,
   44144                 :             :                                          auto_node);
   44145                 :             : 
   44146                 :          44 :                   if (!CLASS_TYPE_P (TREE_TYPE (decl))
   44147                 :          31 :                       && !type_dependent_expression_p (decl))
   44148                 :           4 :                     goto non_class;
   44149                 :             :                 }
   44150                 :             : 
   44151                 :         566 :               cp_finish_decl (decl, init, !is_non_constant_init,
   44152                 :             :                               asm_specification,
   44153                 :             :                               LOOKUP_ONLYCONVERTING);
   44154                 :         566 :               orig_init = init;
   44155                 :             : 
   44156                 :             :               /* In the case of a class iterator, do not pop sl here.
   44157                 :             :                  Both class initialization and finalization must happen in
   44158                 :             :                  the enclosing init block scope.  For now set the init
   44159                 :             :                  expression to null; it'll be filled in properly in
   44160                 :             :                  finish_omp_for before stuffing it in the OMP_FOR.  */
   44161                 :         566 :               if (CLASS_TYPE_P (TREE_TYPE (decl)))
   44162                 :         289 :                 init = NULL_TREE;
   44163                 :             :               else  /* It is a parameterized type.  */
   44164                 :             :                 {
   44165                 :         277 :                   init = pop_stmt_list (sl);
   44166                 :         277 :                   sl = NULL_TREE;
   44167                 :         277 :                   if (init && TREE_CODE (init) == STATEMENT_LIST)
   44168                 :             :                     {
   44169                 :           2 :                       tree_stmt_iterator i = tsi_start (init);
   44170                 :             :                       /* Move lambda DECL_EXPRs to the enclosing block.  */
   44171                 :           7 :                       while (!tsi_end_p (i))
   44172                 :             :                         {
   44173                 :           5 :                           tree t = tsi_stmt (i);
   44174                 :           8 :                           if (TREE_CODE (t) == DECL_EXPR
   44175                 :           5 :                               && TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
   44176                 :             :                             {
   44177                 :           3 :                               tsi_delink (&i);
   44178                 :           3 :                               add_stmt (t);
   44179                 :           3 :                               continue;
   44180                 :             :                             }
   44181                 :             :                           break;
   44182                 :             :                         }
   44183                 :           4 :                       if (tsi_one_before_end_p (i))
   44184                 :             :                         {
   44185                 :           2 :                           tree t = tsi_stmt (i);
   44186                 :           2 :                           tsi_delink (&i);
   44187                 :           2 :                           free_stmt_list (init);
   44188                 :           2 :                           init = t;
   44189                 :             :                         }
   44190                 :             :                     }
   44191                 :             :                 }
   44192                 :             :             }
   44193                 :             :           else
   44194                 :             :             /* This is an initialized declaration of non-class,
   44195                 :             :                non-parameterized type iteration variable.  */
   44196                 :             :             {
   44197                 :             :               /* Consume '='.  */
   44198                 :        6981 :               cp_lexer_consume_token (parser->lexer);
   44199                 :        6981 :               init = cp_parser_assignment_expression (parser);
   44200                 :             : 
   44201                 :        6985 :             non_class:
   44202                 :        6985 :               if (TYPE_REF_P (TREE_TYPE (decl)))
   44203                 :           8 :                 init = error_mark_node;
   44204                 :             :               else
   44205                 :        6977 :                 cp_finish_decl (decl, NULL_TREE,
   44206                 :             :                                 /*init_const_expr_p=*/false,
   44207                 :             :                                 asm_specification,
   44208                 :             :                                 LOOKUP_ONLYCONVERTING);
   44209                 :        6985 :               this_pre_body = pop_stmt_list (sl);
   44210                 :        6985 :               sl = NULL_TREE;
   44211                 :             :             }
   44212                 :             : 
   44213                 :        7559 :           if (pushed_scope)
   44214                 :           0 :             pop_scope (pushed_scope);
   44215                 :             :         }
   44216                 :             :     }
   44217                 :             :   else
   44218                 :             :     {
   44219                 :       18561 :       cp_id_kind idk;
   44220                 :             :       /* If parsing a type specifier sequence failed, then
   44221                 :             :          this MUST be a simple expression.  */
   44222                 :       18561 :       cp_parser_parse_tentatively (parser);
   44223                 :       18561 :       decl = cp_parser_primary_expression (parser, false, false,
   44224                 :             :                                            false, &idk);
   44225                 :       18561 :       cp_token *last_tok = cp_lexer_peek_token (parser->lexer);
   44226                 :       18561 :       if (!cp_parser_error_occurred (parser)
   44227                 :       18561 :           && decl
   44228                 :       18561 :           && (TREE_CODE (decl) == COMPONENT_REF
   44229                 :       18546 :               || (TREE_CODE (decl) == SCOPE_REF && TREE_TYPE (decl))))
   44230                 :             :         {
   44231                 :          19 :           cp_parser_abort_tentative_parse (parser);
   44232                 :          19 :           cp_parser_parse_tentatively (parser);
   44233                 :          19 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   44234                 :          19 :           tree name = cp_parser_id_expression (parser, /*template_p=*/false,
   44235                 :             :                                                /*check_dependency_p=*/true,
   44236                 :             :                                                /*template_p=*/NULL,
   44237                 :             :                                                /*declarator_p=*/false,
   44238                 :             :                                                /*optional_p=*/false);
   44239                 :          19 :           if (name != error_mark_node
   44240                 :          19 :               && last_tok == cp_lexer_peek_token (parser->lexer))
   44241                 :             :             {
   44242                 :          19 :               decl = cp_parser_lookup_name_simple (parser, name,
   44243                 :             :                                                    token->location);
   44244                 :          19 :               if (TREE_CODE (decl) == FIELD_DECL)
   44245                 :          19 :                 add_private_clause = omp_privatize_field (decl, false);
   44246                 :             :             }
   44247                 :          19 :           cp_parser_abort_tentative_parse (parser);
   44248                 :          19 :           cp_parser_parse_tentatively (parser);
   44249                 :          19 :           decl = cp_parser_primary_expression (parser, false, false,
   44250                 :             :                                                false, &idk);
   44251                 :             :         }
   44252                 :       18561 :       if (!cp_parser_error_occurred (parser)
   44253                 :       18561 :           && decl
   44254                 :       18561 :           && DECL_P (decl)
   44255                 :       18527 :           && CLASS_TYPE_P (TREE_TYPE (decl)))
   44256                 :             :         {
   44257                 :         532 :           tree rhs;
   44258                 :             : 
   44259                 :         532 :           cp_parser_parse_definitely (parser);
   44260                 :         532 :           cp_parser_require (parser, CPP_EQ, RT_EQ);
   44261                 :         532 :           rhs = cp_parser_assignment_expression (parser);
   44262                 :         532 :           orig_init = rhs;
   44263                 :         532 :           finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs),
   44264                 :             :                                                  decl, NOP_EXPR,
   44265                 :             :                                                  rhs, NULL_TREE,
   44266                 :             :                                                  tf_warning_or_error));
   44267                 :         532 :           if (!add_private_clause)
   44268                 :         527 :             add_private_clause = decl;
   44269                 :             :         }
   44270                 :             :       else
   44271                 :             :         {
   44272                 :       18029 :           decl = NULL;
   44273                 :       18029 :           cp_parser_abort_tentative_parse (parser);
   44274                 :       18029 :           init = cp_parser_expression (parser);
   44275                 :       18029 :           if (init)
   44276                 :             :             {
   44277                 :       18029 :               if (TREE_CODE (init) == MODIFY_EXPR
   44278                 :         529 :                   || TREE_CODE (init) == MODOP_EXPR)
   44279                 :       17997 :                 real_decl = TREE_OPERAND (init, 0);
   44280                 :             :             }
   44281                 :             :         }
   44282                 :       18561 :       this_pre_body = pop_stmt_list (sl);
   44283                 :       18561 :       sl = NULL_TREE;
   44284                 :             :     }
   44285                 :             :   return add_private_clause;
   44286                 :             : }
   44287                 :             : 
   44288                 :             : /* Helper for cp_parser_omp_loop_nest, handle one range-for loop
   44289                 :             :    including introducing new temporaries for the range start and end,
   44290                 :             :    doing auto deduction, and processing decomposition variables.
   44291                 :             : 
   44292                 :             :    This function is also called from pt.cc during template instantiation.
   44293                 :             :    In that case SL is NULL_TREE, otherwise it is the current statement
   44294                 :             :    list.  */
   44295                 :             : void
   44296                 :         221 : cp_convert_omp_range_for (tree &this_pre_body, tree &sl,
   44297                 :             :                           tree &decl, tree &orig_decl, tree &init,
   44298                 :             :                           tree &orig_init, tree &cond, tree &incr)
   44299                 :             : {
   44300                 :         221 :   tree begin, end, range_temp_decl = NULL_TREE;
   44301                 :         221 :   tree iter_type, begin_expr, end_expr;
   44302                 :         221 :   bool clear_has_value_expr = false;
   44303                 :             : 
   44304                 :         221 :   if (processing_template_decl)
   44305                 :             :     {
   44306                 :          80 :       if (check_for_bare_parameter_packs (init))
   44307                 :           0 :         init = error_mark_node;
   44308                 :          80 :       if (!type_dependent_expression_p (init)
   44309                 :             :           /* do_auto_deduction doesn't mess with template init-lists.  */
   44310                 :          80 :           && !BRACE_ENCLOSED_INITIALIZER_P (init))
   44311                 :             :         {
   44312                 :          48 :           tree d = decl;
   44313                 :          48 :           cp_decomp decomp_d, *decomp = NULL;
   44314                 :          48 :           if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
   44315                 :             :             {
   44316                 :          19 :               tree v = DECL_VALUE_EXPR (decl);
   44317                 :          19 :               if (TREE_CODE (v) == ARRAY_REF
   44318                 :          19 :                   && VAR_P (TREE_OPERAND (v, 0))
   44319                 :          38 :                   && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
   44320                 :             :                 {
   44321                 :          19 :                   d = TREE_OPERAND (v, 0);
   44322                 :          19 :                   decomp = &decomp_d;
   44323                 :          19 :                   decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
   44324                 :          19 :                   decomp->decl = decl;
   44325                 :             :                 }
   44326                 :             :             }
   44327                 :          48 :           do_range_for_auto_deduction (d, init, decomp);
   44328                 :             :         }
   44329                 :          80 :       cond = global_namespace;
   44330                 :          80 :       incr = NULL_TREE;
   44331                 :          80 :       orig_init = init;
   44332                 :          80 :       if (sl)
   44333                 :             :         {
   44334                 :          75 :           this_pre_body = pop_stmt_list (sl);
   44335                 :          75 :           sl = NULL_TREE;
   44336                 :             :         }
   44337                 :          80 :       return;
   44338                 :             :     }
   44339                 :             : 
   44340                 :         141 :   init = mark_lvalue_use (init);
   44341                 :             : 
   44342                 :         141 :   if (decl == error_mark_node || init == error_mark_node)
   44343                 :             :     /* If an error happened previously do nothing or else a lot of
   44344                 :             :        unhelpful errors would be issued.  */
   44345                 :           2 :     begin_expr = end_expr = iter_type = error_mark_node;
   44346                 :             :   else
   44347                 :             :     {
   44348                 :         139 :       tree range_temp;
   44349                 :             : 
   44350                 :         139 :       if (VAR_P (init)
   44351                 :         139 :           && array_of_runtime_bound_p (TREE_TYPE (init)))
   44352                 :             :         /* Can't bind a reference to an array of runtime bound.  */
   44353                 :           0 :         range_temp = init;
   44354                 :             :       else
   44355                 :             :         {
   44356                 :         139 :           range_temp = build_range_temp (init);
   44357                 :         139 :           DECL_NAME (range_temp) = NULL_TREE;
   44358                 :         139 :           pushdecl (range_temp);
   44359                 :         139 :           cp_finish_decl (range_temp, init,
   44360                 :             :                           /*is_constant_init*/false, NULL_TREE,
   44361                 :             :                           LOOKUP_ONLYCONVERTING);
   44362                 :         139 :           range_temp_decl = range_temp;
   44363                 :         139 :           range_temp = convert_from_reference (range_temp);
   44364                 :             :         }
   44365                 :         139 :       iter_type = cp_parser_perform_range_for_lookup (range_temp,
   44366                 :             :                                                       &begin_expr, &end_expr);
   44367                 :             :     }
   44368                 :             : 
   44369                 :         141 :   tree end_iter_type = iter_type;
   44370                 :         141 :   if (cxx_dialect >= cxx17)
   44371                 :         136 :     end_iter_type = cv_unqualified (TREE_TYPE (end_expr));
   44372                 :         141 :   end = build_decl (input_location, VAR_DECL, NULL_TREE, end_iter_type);
   44373                 :         141 :   TREE_USED (end) = 1;
   44374                 :         141 :   DECL_ARTIFICIAL (end) = 1;
   44375                 :         141 :   pushdecl (end);
   44376                 :         141 :   cp_finish_decl (end, end_expr,
   44377                 :             :                   /*is_constant_init*/false, NULL_TREE,
   44378                 :             :                   LOOKUP_ONLYCONVERTING);
   44379                 :             : 
   44380                 :             :   /* The new for initialization statement.  */
   44381                 :         141 :   begin = build_decl (input_location, VAR_DECL, NULL_TREE, iter_type);
   44382                 :         141 :   TREE_USED (begin) = 1;
   44383                 :         141 :   DECL_ARTIFICIAL (begin) = 1;
   44384                 :         141 :   pushdecl (begin);
   44385                 :         141 :   orig_init = init;
   44386                 :         141 :   if (CLASS_TYPE_P (iter_type))
   44387                 :          56 :     init = NULL_TREE;
   44388                 :             :   else
   44389                 :             :     {
   44390                 :          85 :       init = begin_expr;
   44391                 :          85 :       begin_expr = NULL_TREE;
   44392                 :             :     }
   44393                 :         141 :   cp_finish_decl (begin, begin_expr,
   44394                 :             :                   /*is_constant_init*/false, NULL_TREE,
   44395                 :             :                   LOOKUP_ONLYCONVERTING);
   44396                 :             : 
   44397                 :             :   /* The new for condition.  */
   44398                 :         141 :   if (CLASS_TYPE_P (iter_type))
   44399                 :          56 :     cond = build2 (NE_EXPR, boolean_type_node, begin, end);
   44400                 :             :   else
   44401                 :          85 :     cond = build_x_binary_op (input_location, NE_EXPR,
   44402                 :             :                               begin, ERROR_MARK,
   44403                 :             :                               end, ERROR_MARK,
   44404                 :             :                               NULL_TREE, NULL, tf_warning_or_error);
   44405                 :             : 
   44406                 :             :   /* The new increment expression.  */
   44407                 :         141 :   if (CLASS_TYPE_P (iter_type))
   44408                 :          56 :     incr = build2 (PREINCREMENT_EXPR, iter_type, begin, NULL_TREE);
   44409                 :             :   else
   44410                 :          85 :     incr = finish_unary_op_expr (input_location,
   44411                 :             :                                  PREINCREMENT_EXPR, begin,
   44412                 :             :                                  tf_warning_or_error);
   44413                 :             : 
   44414                 :         141 :   orig_decl = decl;
   44415                 :         141 :   decl = begin;
   44416                 :             :   /* Defer popping sl here.  */
   44417                 :             : 
   44418                 :         141 :   cp_decomp decomp_d, *decomp = NULL;
   44419                 :         141 :   if (orig_decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (orig_decl))
   44420                 :             :     {
   44421                 :          58 :       tree v = DECL_VALUE_EXPR (orig_decl);
   44422                 :          58 :       if (TREE_CODE (v) == ARRAY_REF
   44423                 :          58 :           && VAR_P (TREE_OPERAND (v, 0))
   44424                 :         116 :           && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
   44425                 :             :         {
   44426                 :          58 :           tree d = orig_decl;
   44427                 :          58 :           orig_decl = TREE_OPERAND (v, 0);
   44428                 :          58 :           decomp = &decomp_d;
   44429                 :          58 :           decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
   44430                 :          58 :           decomp->decl = d;
   44431                 :             :         }
   44432                 :             :     }
   44433                 :             : 
   44434                 :         141 :   tree auto_node = type_uses_auto (TREE_TYPE (orig_decl));
   44435                 :         141 :   if (auto_node)
   44436                 :             :     {
   44437                 :          95 :       tree t = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
   44438                 :             :                                      NULL_TREE, tf_none);
   44439                 :          95 :       if (!error_operand_p (t))
   44440                 :             :         {
   44441                 :          95 :           TREE_TYPE (orig_decl) = do_auto_deduction (TREE_TYPE (orig_decl),
   44442                 :             :                                                      t, auto_node);
   44443                 :          95 :           if (decomp)
   44444                 :             :             {
   44445                 :          41 :               ++processing_template_decl;
   44446                 :          41 :               cp_finish_decomp (orig_decl, decomp);
   44447                 :          41 :               --processing_template_decl;
   44448                 :          41 :               if (!processing_template_decl)
   44449                 :          87 :                 clear_has_value_expr = true;
   44450                 :             :             }
   44451                 :             :         }
   44452                 :             :     }
   44453                 :             : 
   44454                 :             :   /* The output ORIG_DECL is not a decl.  Instead, it is a tree structure
   44455                 :             :      that holds decls for variables implementing the iterator, represented
   44456                 :             :      as a TREE_LIST whose TREE_CHAIN is a vector.  The first two elements
   44457                 :             :      of the vector are decls of scratch variables for the range start and
   44458                 :             :      end that will eventually be bound in the implicit scope surrounding
   44459                 :             :      the whole loop nest.  The remaining elements are decls of derived
   44460                 :             :      decomposition variables that are bound inside the loop body.  This
   44461                 :             :      structure is further mangled by finish_omp_for into the form required
   44462                 :             :      for the OMP_FOR_ORIG_DECLS field of the OMP_FOR tree node.  */\
   44463                 :          87 :   unsigned decomp_cnt = decomp ? decomp->count : 0;
   44464                 :         141 :   tree v = make_tree_vec (decomp_cnt + 3);
   44465                 :         141 :   TREE_VEC_ELT (v, 0) = range_temp_decl;
   44466                 :         141 :   TREE_VEC_ELT (v, 1) = end;
   44467                 :         141 :   TREE_VEC_ELT (v, 2) = orig_decl;
   44468                 :         141 :   if (clear_has_value_expr)
   44469                 :          41 :     TREE_PUBLIC (v) = 1;
   44470                 :         311 :   for (unsigned i = 0; i < decomp_cnt; i++)
   44471                 :             :     {
   44472                 :         170 :       if (clear_has_value_expr)
   44473                 :             :         {
   44474                 :             :           /* If cp_finish_decomp was called with processing_template_decl
   44475                 :             :              temporarily set to 1, then decomp names will have deduced
   44476                 :             :              name but the DECL_VALUE_EXPR will be dependent.  Hide those
   44477                 :             :              from folding of other loop initializers e.g. for warning
   44478                 :             :              purposes until cp_finish_omp_range_for.  */
   44479                 :         122 :           gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (decomp->decl)
   44480                 :             :                                || (TREE_TYPE (decomp->decl)
   44481                 :             :                                    == error_mark_node));
   44482                 :         122 :           DECL_HAS_VALUE_EXPR_P (decomp->decl) = 0;
   44483                 :             :         }
   44484                 :         170 :       TREE_VEC_ELT (v, i + 3) = decomp->decl;
   44485                 :         170 :       decomp->decl = DECL_CHAIN (decomp->decl);
   44486                 :             :     }
   44487                 :         141 :   orig_decl = tree_cons (NULL_TREE, NULL_TREE, v);
   44488                 :             : }
   44489                 :             : 
   44490                 :             : /* Helper for cp_parser_omp_for_loop, finalize part of range for
   44491                 :             :    inside of the collapsed body.  */
   44492                 :             : 
   44493                 :             : void
   44494                 :         141 : cp_finish_omp_range_for (tree orig, tree begin)
   44495                 :             : {
   44496                 :         141 :   gcc_assert (TREE_CODE (orig) == TREE_LIST
   44497                 :             :               && TREE_CODE (TREE_CHAIN (orig)) == TREE_VEC);
   44498                 :         141 :   tree decl = TREE_VEC_ELT (TREE_CHAIN (orig), 2);
   44499                 :         141 :   cp_decomp decomp_d, *decomp = NULL;
   44500                 :             : 
   44501                 :         141 :   if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
   44502                 :             :     {
   44503                 :          58 :       decomp = &decomp_d;
   44504                 :          58 :       decomp_d.decl = TREE_VEC_ELT (TREE_CHAIN (orig), 3);
   44505                 :          58 :       decomp_d.count = TREE_VEC_LENGTH (TREE_CHAIN (orig)) - 3;
   44506                 :          58 :       if (TREE_PUBLIC (TREE_CHAIN (orig)))
   44507                 :             :         {
   44508                 :             :           /* Undo temporary clearing of DECL_HAS_VALUE_EXPR_P done
   44509                 :             :              by cp_convert_omp_range_for above.  */
   44510                 :          41 :           TREE_PUBLIC (TREE_CHAIN (orig)) = 0;
   44511                 :          41 :           tree d = decomp_d.decl;
   44512                 :         163 :           for (unsigned i = 0; i < decomp_d.count; i++)
   44513                 :             :             {
   44514                 :         122 :               if (TREE_TYPE (d) != error_mark_node)
   44515                 :         120 :                 DECL_HAS_VALUE_EXPR_P (d) = 1;
   44516                 :         122 :               d = DECL_CHAIN (d);
   44517                 :             :             }
   44518                 :             :         }
   44519                 :             :     }
   44520                 :             : 
   44521                 :             :   /* The declaration is initialized with *__begin inside the loop body.  */
   44522                 :         141 :   cp_finish_decl (decl,
   44523                 :             :                   build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
   44524                 :             :                                         NULL_TREE, tf_warning_or_error),
   44525                 :             :                   /*is_constant_init*/false, NULL_TREE,
   44526                 :             :                   LOOKUP_ONLYCONVERTING, decomp);
   44527                 :         141 :   if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
   44528                 :          58 :     cp_finish_decomp (decl, decomp);
   44529                 :         141 : }
   44530                 :             : 
   44531                 :             : /* Return true if next tokens contain a standard attribute that contains
   44532                 :             :    omp::directive (DIRECTIVE).  */
   44533                 :             : 
   44534                 :             : static bool
   44535                 :        1058 : cp_parser_omp_section_scan (cp_parser *parser, const char *directive,
   44536                 :             :                             bool tentative)
   44537                 :             : {
   44538                 :        1058 :   size_t n = cp_parser_skip_attributes_opt (parser, 1), i;
   44539                 :        1058 :   if (n < 10)
   44540                 :             :     return false;
   44541                 :         312 :   for (i = 5; i < n - 4; i++)
   44542                 :         309 :     if (cp_lexer_nth_token_is (parser->lexer, i, CPP_NAME)
   44543                 :         198 :         && cp_lexer_nth_token_is (parser->lexer, i + 1, CPP_OPEN_PAREN)
   44544                 :         468 :         && cp_lexer_nth_token_is (parser->lexer, i + 2, CPP_NAME))
   44545                 :             :       {
   44546                 :         159 :         tree first = cp_lexer_peek_nth_token (parser->lexer, i)->u.value;
   44547                 :         159 :         tree second = cp_lexer_peek_nth_token (parser->lexer, i + 2)->u.value;
   44548                 :         159 :         if (strcmp (IDENTIFIER_POINTER (first), "directive")
   44549                 :         159 :             && strcmp (IDENTIFIER_POINTER (first), "__directive__"))
   44550                 :          42 :           continue;
   44551                 :         117 :         if (strcmp (IDENTIFIER_POINTER (second), directive) == 0)
   44552                 :             :           break;
   44553                 :             :       }
   44554                 :         111 :   if (i == n - 4)
   44555                 :             :     return false;
   44556                 :         108 :   cp_parser_parse_tentatively (parser);
   44557                 :         108 :   location_t first_loc = cp_lexer_peek_token (parser->lexer)->location;
   44558                 :         108 :   location_t last_loc
   44559                 :         108 :     = cp_lexer_peek_nth_token (parser->lexer, n - 1)->location;
   44560                 :         108 :   location_t middle_loc = UNKNOWN_LOCATION;
   44561                 :         108 :   tree std_attrs = cp_parser_std_attribute_spec_seq (parser);
   44562                 :         108 :   int cnt = 0;
   44563                 :         108 :   bool seen = false;
   44564                 :         228 :   for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
   44565                 :         120 :     if (get_attribute_namespace (attr) == omp_identifier
   44566                 :         120 :         && is_attribute_p ("directive", get_attribute_name (attr)))
   44567                 :             :       {
   44568                 :         228 :         for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
   44569                 :             :           {
   44570                 :         120 :             tree d = TREE_VALUE (a);
   44571                 :         120 :             gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
   44572                 :         120 :             cp_token *first = DEFPARSE_TOKENS (d)->first;
   44573                 :         120 :             cnt++;
   44574                 :         120 :             if (first->type == CPP_NAME
   44575                 :         120 :                 && strcmp (IDENTIFIER_POINTER (first->u.value),
   44576                 :             :                            directive) == 0)
   44577                 :             :               {
   44578                 :         108 :                 seen = true;
   44579                 :         108 :                 if (middle_loc == UNKNOWN_LOCATION)
   44580                 :         108 :                   middle_loc = first->location;
   44581                 :             :               }
   44582                 :             :           }
   44583                 :             :       }
   44584                 :         108 :   if (!seen || tentative)
   44585                 :             :     {
   44586                 :           6 :       cp_parser_abort_tentative_parse (parser);
   44587                 :           6 :       return seen;
   44588                 :             :     }
   44589                 :         102 :   if (cnt != 1 || TREE_CHAIN (std_attrs))
   44590                 :             :     {
   44591                 :          24 :       error_at (make_location (first_loc, last_loc, middle_loc),
   44592                 :             :                 "%<[[omp::directive(%s)]]%> must be the only specified "
   44593                 :             :                 "attribute on a statement", directive);
   44594                 :          24 :       cp_parser_abort_tentative_parse (parser);
   44595                 :          24 :       return false;
   44596                 :             :     }
   44597                 :          78 :   if (!cp_parser_parse_definitely (parser))
   44598                 :             :     return false;
   44599                 :          78 :   cp_parser_handle_statement_omp_attributes (parser, std_attrs);
   44600                 :          78 :   return true;
   44601                 :             : }
   44602                 :             : 
   44603                 :             : /* Parse an OpenMP structured block sequence.  KIND is the corresponding
   44604                 :             :    separating directive.  */
   44605                 :             : 
   44606                 :             : static tree
   44607                 :        1525 : cp_parser_omp_structured_block_sequence (cp_parser *parser,
   44608                 :             :                                          enum pragma_kind kind)
   44609                 :             : {
   44610                 :        1525 :   tree stmt = begin_omp_structured_block ();
   44611                 :        1525 :   unsigned int save = cp_parser_begin_omp_structured_block (parser);
   44612                 :             : 
   44613                 :        1525 :   cp_parser_statement (parser, NULL_TREE, false, NULL);
   44614                 :        1819 :   while (true)
   44615                 :             :     {
   44616                 :        1672 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   44617                 :             : 
   44618                 :        1672 :       if (token->type == CPP_CLOSE_BRACE
   44619                 :             :           || token->type == CPP_EOF
   44620                 :             :           || token->type == CPP_PRAGMA_EOL
   44621                 :         873 :           || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END)
   44622                 :         873 :           || (kind != PRAGMA_NONE
   44623                 :         843 :               && cp_parser_pragma_kind (token) == kind))
   44624                 :             :         break;
   44625                 :             : 
   44626                 :         219 :       if (kind != PRAGMA_NONE
   44627                 :         333 :           && cp_parser_omp_section_scan (parser,
   44628                 :             :                                          kind == PRAGMA_OMP_SCAN
   44629                 :             :                                          ? "scan" : "section", false))
   44630                 :             :         break;
   44631                 :             : 
   44632                 :         147 :       cp_parser_statement (parser, NULL_TREE, false, NULL);
   44633                 :         147 :     }
   44634                 :             : 
   44635                 :        1525 :   cp_parser_end_omp_structured_block (parser, save);
   44636                 :        1525 :   return finish_omp_structured_block (stmt);
   44637                 :             : }
   44638                 :             : 
   44639                 :             : 
   44640                 :             : /* OpenMP 5.0:
   44641                 :             : 
   44642                 :             :    scan-loop-body:
   44643                 :             :      { structured-block scan-directive structured-block }  */
   44644                 :             : 
   44645                 :             : static void
   44646                 :         355 : cp_parser_omp_scan_loop_body (cp_parser *parser)
   44647                 :             : {
   44648                 :         355 :   tree substmt, clauses = NULL_TREE;
   44649                 :         355 :   bool found_scan = false;
   44650                 :             : 
   44651                 :         355 :   matching_braces braces;
   44652                 :         355 :   if (!braces.require_open (parser))
   44653                 :           4 :     return;
   44654                 :             : 
   44655                 :         351 :   cp_token *tok = cp_lexer_peek_token (parser->lexer);
   44656                 :         351 :   if (cp_parser_pragma_kind (tok) != PRAGMA_OMP_SCAN)
   44657                 :         343 :     substmt = cp_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
   44658                 :             :   else
   44659                 :             :     {
   44660                 :           8 :       warning_at (tok->location, OPT_Wopenmp,
   44661                 :             :                   "%<#pragma omp scan%> with zero preceding executable "
   44662                 :             :                   "statements");
   44663                 :           8 :       substmt = build_empty_stmt (tok->location);
   44664                 :             :     }
   44665                 :         351 :   substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
   44666                 :         351 :   add_stmt (substmt);
   44667                 :             : 
   44668                 :         351 :   tok = cp_lexer_peek_token (parser->lexer);
   44669                 :         351 :   if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SCAN)
   44670                 :             :     {
   44671                 :         327 :       enum omp_clause_code clause = OMP_CLAUSE_ERROR;
   44672                 :         327 :       found_scan = true;
   44673                 :             : 
   44674                 :         327 :       cp_lexer_consume_token (parser->lexer);
   44675                 :             : 
   44676                 :         327 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   44677                 :          19 :         cp_lexer_consume_token (parser->lexer);
   44678                 :             : 
   44679                 :         327 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   44680                 :             :         {
   44681                 :         320 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   44682                 :         320 :           const char *p = IDENTIFIER_POINTER (id);
   44683                 :         320 :           if (strcmp (p, "inclusive") == 0)
   44684                 :             :             clause = OMP_CLAUSE_INCLUSIVE;
   44685                 :         159 :           else if (strcmp (p, "exclusive") == 0)
   44686                 :             :             clause = OMP_CLAUSE_EXCLUSIVE;
   44687                 :             :         }
   44688                 :             :       if (clause != OMP_CLAUSE_ERROR)
   44689                 :             :         {
   44690                 :         320 :           cp_lexer_consume_token (parser->lexer);
   44691                 :         320 :           clauses = cp_parser_omp_var_list (parser, clause, NULL_TREE);
   44692                 :             :         }
   44693                 :             :       else
   44694                 :           7 :         cp_parser_error (parser, "expected %<inclusive%> or "
   44695                 :             :                                  "%<exclusive%> clause");
   44696                 :             : 
   44697                 :         327 :       cp_parser_require_pragma_eol (parser, tok);
   44698                 :             :     }
   44699                 :             :   else
   44700                 :          24 :     error ("expected %<#pragma omp scan%>");
   44701                 :             : 
   44702                 :         351 :   clauses = finish_omp_clauses (clauses, C_ORT_OMP);
   44703                 :         351 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
   44704                 :         319 :     substmt = cp_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
   44705                 :             :   else
   44706                 :             :     {
   44707                 :          32 :       if (found_scan)
   44708                 :           8 :         warning_at (tok->location, OPT_Wopenmp,
   44709                 :             :                     "%<#pragma omp scan%> with zero succeeding executable "
   44710                 :             :                     "statements");
   44711                 :          32 :       substmt = build_empty_stmt (tok->location);
   44712                 :             :     }
   44713                 :         351 :   substmt = build2_loc (tok->location, OMP_SCAN, void_type_node, substmt,
   44714                 :             :                         clauses);
   44715                 :         351 :   add_stmt (substmt);
   44716                 :             : 
   44717                 :         351 :   braces.require_close (parser);
   44718                 :             : }
   44719                 :             : 
   44720                 :             : 
   44721                 :             : /* This function parses a single level of a loop nest, invoking itself
   44722                 :             :    recursively if necessary.
   44723                 :             : 
   44724                 :             :    loop-nest :: for (...) loop-body
   44725                 :             :    loop-body :: loop-nest
   44726                 :             :              |  { [intervening-code] loop-body [intervening-code] }
   44727                 :             :              |  final-loop-body
   44728                 :             :    intervening-code :: structured-block-sequence
   44729                 :             :    final-loop-body :: structured-block
   44730                 :             : 
   44731                 :             :    For a collapsed loop nest, only a single OMP_FOR is built, pulling out
   44732                 :             :    all the iterator information from the inner loops into vectors in the
   44733                 :             :    parser->omp_for_parse_state structure.
   44734                 :             : 
   44735                 :             :    In the "range for" case, it is transformed into a regular "for" iterator
   44736                 :             :    by introducing some temporary variables for the begin/end,
   44737                 :             :    as well as bindings of the actual iteration variables which are
   44738                 :             :    injected into the body of the loop.
   44739                 :             : 
   44740                 :             :    Initialization code for iterator variables may end up either in the
   44741                 :             :    init vector (simple assignments), in omp_for_parse_state->pre_body
   44742                 :             :    (decl_exprs for iterators bound in the for statement), or in the
   44743                 :             :    scope surrounding this level of loop initialization.
   44744                 :             : 
   44745                 :             :    The scopes of class iterator variables and their finalizers need to
   44746                 :             :    be adjusted after parsing so that all of the initialization happens
   44747                 :             :    in a scope surrounding all of the intervening and body code.  For
   44748                 :             :    this reason we separately store the initialization and body blocks
   44749                 :             :    for each level of loops in the omp_for_parse_state structure and
   44750                 :             :    reassemble/reorder them in cp_parser_omp_for.  See additional
   44751                 :             :    comments there about the use of placeholders, etc.  */
   44752                 :             : 
   44753                 :             : static tree
   44754                 :       26269 : cp_parser_omp_loop_nest (cp_parser *parser, bool *if_p)
   44755                 :             : {
   44756                 :       26269 :   tree decl, cond, incr, init;
   44757                 :       26269 :   tree orig_init, real_decl, orig_decl;
   44758                 :       26269 :   tree init_block, body_block;
   44759                 :       26269 :   tree init_placeholder, body_placeholder;
   44760                 :       26269 :   tree init_scope;
   44761                 :       26269 :   tree this_pre_body = NULL_TREE;
   44762                 :       26269 :   bool moreloops;
   44763                 :       26269 :   unsigned char save_in_statement;
   44764                 :       26269 :   tree add_private_clause = NULL_TREE;
   44765                 :       26269 :   location_t loc;
   44766                 :       26269 :   bool is_range_for = false;
   44767                 :       26269 :   tree sl = NULL_TREE;
   44768                 :       26269 :   struct omp_for_parse_data *omp_for_parse_state
   44769                 :             :     = parser->omp_for_parse_state;
   44770                 :       26269 :   gcc_assert (omp_for_parse_state);
   44771                 :       26269 :   int depth = omp_for_parse_state->depth;
   44772                 :             : 
   44773                 :             :   /* We have already matched the FOR token but not consumed it yet.  */
   44774                 :       26269 :   gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR));
   44775                 :       26269 :   loc = cp_lexer_consume_token (parser->lexer)->location;
   44776                 :             : 
   44777                 :             :   /* Forbid break/continue in the loop initializer, condition, and
   44778                 :             :      increment expressions.  */
   44779                 :       26269 :   save_in_statement = parser->in_statement;
   44780                 :       26269 :   parser->in_statement = IN_OMP_BLOCK;
   44781                 :             : 
   44782                 :             :   /* We are not in intervening code now.  */
   44783                 :       26269 :   omp_for_parse_state->in_intervening_code = false;
   44784                 :             : 
   44785                 :             :   /* Don't create location wrapper nodes within an OpenMP "for"
   44786                 :             :      statement.  */
   44787                 :       26269 :   auto_suppress_location_wrappers sentinel;
   44788                 :             : 
   44789                 :       26269 :   matching_parens parens;
   44790                 :       26269 :   if (!parens.require_open (parser))
   44791                 :             :     return NULL;
   44792                 :             : 
   44793                 :       26269 :   init = orig_init = decl = real_decl = orig_decl = NULL_TREE;
   44794                 :             : 
   44795                 :       26269 :   init_placeholder = build_stmt (input_location, EXPR_STMT,
   44796                 :             :                                  integer_zero_node);
   44797                 :       26269 :   vec_safe_push (omp_for_parse_state->init_placeholderv, init_placeholder);
   44798                 :             : 
   44799                 :             :   /* The init_block acts as a container for this level of loop goo.  */
   44800                 :       26269 :   init_block = push_stmt_list ();
   44801                 :       26269 :   vec_safe_push (omp_for_parse_state->init_blockv, init_block);
   44802                 :             : 
   44803                 :             :   /* Wrap a scope around this entire level of loop to hold bindings
   44804                 :             :      of loop iteration variables.  We can't insert them directly
   44805                 :             :      in the containing scope because that would cause their visibility to
   44806                 :             :      be incorrect with respect to intervening code after this loop.
   44807                 :             :      We will combine the nested init_scopes in postprocessing after the
   44808                 :             :      entire loop is parsed.  */
   44809                 :       26269 :   init_scope = begin_compound_stmt (0);
   44810                 :             : 
   44811                 :             :   /* Now we need another level of statement list container to capture the
   44812                 :             :      initialization (and possible finalization) bits.  In some cases this
   44813                 :             :      container may be popped off during initializer parsing to store code in
   44814                 :             :      INIT or THIS_PRE_BODY, depending on the form of initialization.  If
   44815                 :             :      we have a class iterator we will pop it at the end of parsing this
   44816                 :             :      level, so the cleanups are handled correctly.  */
   44817                 :       26269 :   sl = push_stmt_list ();
   44818                 :             : 
   44819                 :       26269 :   if (omp_for_parse_state->code != OACC_LOOP && cxx_dialect >= cxx11)
   44820                 :             :     {
   44821                 :             :       /* Save tokens so that we can put them back.  */
   44822                 :       17968 :       cp_lexer_save_tokens (parser->lexer);
   44823                 :             : 
   44824                 :             :       /* Look for ':' that is not nested in () or {}.  */
   44825                 :       17968 :       is_range_for
   44826                 :       17968 :         = (cp_parser_skip_to_closing_parenthesis_1 (parser,
   44827                 :             :                                                     /*recovering=*/false,
   44828                 :             :                                                     CPP_COLON,
   44829                 :             :                                                     /*consume_paren=*/
   44830                 :             :                                                     false) == -1);
   44831                 :             : 
   44832                 :             :       /* Roll back the tokens we skipped.  */
   44833                 :       17968 :       cp_lexer_rollback_tokens (parser->lexer);
   44834                 :             : 
   44835                 :       17968 :       if (is_range_for)
   44836                 :             :         {
   44837                 :         145 :           bool saved_colon_corrects_to_scope_p
   44838                 :             :             = parser->colon_corrects_to_scope_p;
   44839                 :             : 
   44840                 :             :           /* A colon is used in range-based for.  */
   44841                 :         145 :           parser->colon_corrects_to_scope_p = false;
   44842                 :             : 
   44843                 :             :           /* Parse the declaration.  */
   44844                 :         145 :           cp_parser_simple_declaration (parser,
   44845                 :             :                                         /*function_definition_allowed_p=*/
   44846                 :             :                                         false, &decl);
   44847                 :         145 :           parser->colon_corrects_to_scope_p
   44848                 :         145 :             = saved_colon_corrects_to_scope_p;
   44849                 :             : 
   44850                 :         145 :           cp_parser_require (parser, CPP_COLON, RT_COLON);
   44851                 :             : 
   44852                 :         145 :           init = cp_parser_range_for (parser, NULL_TREE, NULL_TREE, decl,
   44853                 :             :                                       false, NULL_TREE, false, true);
   44854                 :             : 
   44855                 :         145 :           cp_convert_omp_range_for (this_pre_body, sl, decl,
   44856                 :             :                                     orig_decl, init, orig_init,
   44857                 :             :                                     cond, incr);
   44858                 :             : 
   44859                 :         145 :           if (omp_for_parse_state->ordered_cl)
   44860                 :           6 :             error_at (OMP_CLAUSE_LOCATION (omp_for_parse_state->ordered_cl),
   44861                 :             :                       "%<ordered%> clause with parameter on "
   44862                 :             :                       "range-based %<for%> loop");
   44863                 :             : 
   44864                 :         145 :           goto parse_close_paren;
   44865                 :             :         }
   44866                 :             :     }
   44867                 :             : 
   44868                 :       26124 :   add_private_clause
   44869                 :       26124 :     = cp_parser_omp_for_loop_init (parser, this_pre_body, sl,
   44870                 :             :                                    init, orig_init, decl, real_decl);
   44871                 :             : 
   44872                 :       26124 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   44873                 :             : 
   44874                 :             :   /* If the iteration variable was introduced via a declaration in the
   44875                 :             :      for statement, DECL points at it.  Otherwise DECL is null and
   44876                 :             :      REAL_DECL is a variable previously declared in an outer scope.
   44877                 :             :      Make REAL_DECL point at the iteration variable no matter where it
   44878                 :             :      was introduced.  */
   44879                 :       26124 :   if (decl)
   44880                 :        8091 :     real_decl = decl;
   44881                 :             : 
   44882                 :             :   /* Some clauses treat iterator variables specially.  */
   44883                 :       26124 :   if (omp_for_parse_state->cclauses != NULL
   44884                 :       11729 :       && omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL
   44885                 :        2010 :       && real_decl != NULL_TREE
   44886                 :        2010 :       && omp_for_parse_state->code != OMP_LOOP)
   44887                 :             :     {
   44888                 :        1905 :       tree *c;
   44889                 :        1905 :       for (c = &(omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]);
   44890                 :        8956 :            *c ; )
   44891                 :        7051 :         if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE
   44892                 :        7051 :             && OMP_CLAUSE_DECL (*c) == real_decl)
   44893                 :             :           {
   44894                 :           4 :             error_at (loc, "iteration variable %qD"
   44895                 :             :                       " should not be firstprivate", real_decl);
   44896                 :           4 :             *c = OMP_CLAUSE_CHAIN (*c);
   44897                 :             :           }
   44898                 :        7047 :         else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_LASTPRIVATE
   44899                 :        7047 :                  && OMP_CLAUSE_DECL (*c) == real_decl)
   44900                 :             :           {
   44901                 :             :             /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES.  */
   44902                 :         123 :             tree l = *c;
   44903                 :         123 :             *c = OMP_CLAUSE_CHAIN (*c);
   44904                 :         123 :             if (omp_for_parse_state->code == OMP_SIMD)
   44905                 :             :               {
   44906                 :          52 :                 OMP_CLAUSE_CHAIN (l)
   44907                 :          52 :                   = omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_FOR];
   44908                 :          52 :                 omp_for_parse_state->cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
   44909                 :             :               }
   44910                 :             :             else
   44911                 :             :               {
   44912                 :          71 :                 OMP_CLAUSE_CHAIN (l) = omp_for_parse_state->clauses;
   44913                 :          71 :                 omp_for_parse_state->clauses = l;
   44914                 :             :               }
   44915                 :             :             add_private_clause = NULL_TREE;
   44916                 :             :           }
   44917                 :             :         else
   44918                 :             :           {
   44919                 :        6924 :             if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_PRIVATE
   44920                 :        6924 :                 && OMP_CLAUSE_DECL (*c) == real_decl)
   44921                 :             :               add_private_clause = NULL_TREE;
   44922                 :        6924 :             c = &OMP_CLAUSE_CHAIN (*c);
   44923                 :             :           }
   44924                 :             :     }
   44925                 :             : 
   44926                 :       26124 :   if (add_private_clause)
   44927                 :             :     {
   44928                 :         511 :       tree c;
   44929                 :         896 :       for (c = omp_for_parse_state->clauses; c ; c = OMP_CLAUSE_CHAIN (c))
   44930                 :             :         {
   44931                 :         441 :           if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
   44932                 :         352 :                || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
   44933                 :         510 :               && OMP_CLAUSE_DECL (c) == decl)
   44934                 :             :             break;
   44935                 :         385 :           else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
   44936                 :         385 :                    && OMP_CLAUSE_DECL (c) == decl)
   44937                 :           0 :             error_at (loc, "iteration variable %qD "
   44938                 :             :                       "should not be firstprivate",
   44939                 :             :                       decl);
   44940                 :         385 :           else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
   44941                 :         385 :                     || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
   44942                 :         385 :                    && OMP_CLAUSE_DECL (c) == decl)
   44943                 :           0 :             error_at (loc, "iteration variable %qD should not be reduction",
   44944                 :             :                       decl);
   44945                 :             :         }
   44946                 :         511 :       if (c == NULL)
   44947                 :             :         {
   44948                 :         455 :           if ((omp_for_parse_state->code == OMP_SIMD
   44949                 :          10 :                && omp_for_parse_state->count != 1)
   44950                 :         449 :               || omp_for_parse_state->code == OMP_LOOP)
   44951                 :          13 :             c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
   44952                 :         442 :           else if (omp_for_parse_state->code != OMP_SIMD)
   44953                 :         438 :             c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
   44954                 :             :           else
   44955                 :           4 :             c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
   44956                 :         455 :           OMP_CLAUSE_DECL (c) = add_private_clause;
   44957                 :         455 :           c = finish_omp_clauses (c, C_ORT_OMP);
   44958                 :         455 :           if (c)
   44959                 :             :             {
   44960                 :         423 :               OMP_CLAUSE_CHAIN (c) = omp_for_parse_state->clauses;
   44961                 :         423 :               omp_for_parse_state->clauses = c;
   44962                 :             :               /* For linear, signal that we need to fill up
   44963                 :             :                  the so far unknown linear step.  */
   44964                 :         423 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
   44965                 :           4 :                 OMP_CLAUSE_LINEAR_STEP (c) = NULL_TREE;
   44966                 :             :             }
   44967                 :             :         }
   44968                 :             :     }
   44969                 :             : 
   44970                 :       26124 :   cond = NULL;
   44971                 :       26124 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
   44972                 :       26108 :     cond = cp_parser_omp_for_cond (parser, decl, omp_for_parse_state->code);
   44973                 :       26124 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   44974                 :             : 
   44975                 :       26124 :   incr = NULL;
   44976                 :       26124 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
   44977                 :             :     {
   44978                 :             :       /* If decl is an iterator, preserve the operator on decl
   44979                 :             :          until finish_omp_for.  */
   44980                 :       26112 :       if (real_decl
   44981                 :       26112 :           && ((processing_template_decl
   44982                 :        1452 :                && (TREE_TYPE (real_decl) == NULL_TREE
   44983                 :        1442 :                    || !INDIRECT_TYPE_P (TREE_TYPE (real_decl))))
   44984                 :       24654 :               || CLASS_TYPE_P (TREE_TYPE (real_decl))))
   44985                 :        2079 :         incr = cp_parser_omp_for_incr (parser, real_decl);
   44986                 :             :       else
   44987                 :       24033 :         incr = cp_parser_expression (parser);
   44988                 :       26112 :       protected_set_expr_location_if_unset (incr, input_location);
   44989                 :             :     }
   44990                 :             : 
   44991                 :          12 :  parse_close_paren:
   44992                 :       26269 :   if (!parens.require_close (parser))
   44993                 :          12 :     cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
   44994                 :             :                                            /*or_comma=*/false,
   44995                 :             :                                            /*consume_paren=*/true);
   44996                 :             : 
   44997                 :             :   /* We've parsed all the for (...) stuff now.  Store the bits.  */
   44998                 :       26269 :   TREE_VEC_ELT (omp_for_parse_state->declv, depth) = decl;
   44999                 :       26269 :   TREE_VEC_ELT (omp_for_parse_state->initv, depth) = init;
   45000                 :       26269 :   TREE_VEC_ELT (omp_for_parse_state->condv, depth) = cond;
   45001                 :       26269 :   TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = incr;
   45002                 :       26269 :   if (orig_init)
   45003                 :             :     {
   45004                 :        1243 :       omp_for_parse_state->orig_inits.safe_grow_cleared (depth + 1, true);
   45005                 :        1243 :       omp_for_parse_state->orig_inits[depth] = orig_init;
   45006                 :             :     }
   45007                 :       26269 :   if (orig_decl)
   45008                 :             :     {
   45009                 :          70 :       if (!omp_for_parse_state->orig_declv)
   45010                 :          63 :         omp_for_parse_state->orig_declv
   45011                 :          63 :           = copy_node (omp_for_parse_state->declv);
   45012                 :          70 :       TREE_VEC_ELT (omp_for_parse_state->orig_declv, depth) = orig_decl;
   45013                 :             :     }
   45014                 :       26199 :   else if (omp_for_parse_state->orig_declv)
   45015                 :          13 :     TREE_VEC_ELT (omp_for_parse_state->orig_declv, depth) = decl;
   45016                 :       26269 :   if (this_pre_body)
   45017                 :       25621 :     append_to_statement_list_force (this_pre_body,
   45018                 :             :                                     &(omp_for_parse_state->pre_body));
   45019                 :             : 
   45020                 :             :   /* Start a nested block for the loop body.  */
   45021                 :       26269 :   body_placeholder = build_stmt (input_location, EXPR_STMT,
   45022                 :             :                                  integer_zero_node);
   45023                 :       26269 :   vec_safe_push (omp_for_parse_state->body_placeholderv, body_placeholder);
   45024                 :       26269 :   body_block = push_stmt_list ();
   45025                 :       26269 :   vec_safe_push (omp_for_parse_state->body_blockv, body_block);
   45026                 :             : 
   45027                 :       26269 :   moreloops = depth < omp_for_parse_state->count - 1;
   45028                 :       26269 :   omp_for_parse_state->want_nested_loop = moreloops;
   45029                 :       26269 :   if (moreloops && cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
   45030                 :             :     {
   45031                 :        5554 :       omp_for_parse_state->depth++;
   45032                 :        5554 :       add_stmt (cp_parser_omp_loop_nest (parser, if_p));
   45033                 :        5554 :       omp_for_parse_state->depth--;
   45034                 :             :     }
   45035                 :       20715 :   else if (moreloops
   45036                 :       20715 :            && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
   45037                 :             :     {
   45038                 :             :       /* This is the open brace in the loop-body grammar production.  Rather
   45039                 :             :          than trying to special-case braces, just parse it as a compound
   45040                 :             :          statement and handle the nested loop-body case there.  Note that
   45041                 :             :          when we see a further open brace inside the compound statement
   45042                 :             :          loop-body, we don't know whether it is the start of intervening
   45043                 :             :          code that is a compound statement, or a level of braces
   45044                 :             :          surrounding a nested loop-body.  Use the WANT_NESTED_LOOP state
   45045                 :             :          bit to ensure we have only one nested loop at each level.  */
   45046                 :             : 
   45047                 :         433 :       omp_for_parse_state->in_intervening_code = true;
   45048                 :         433 :       cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
   45049                 :         433 :       omp_for_parse_state->in_intervening_code = false;
   45050                 :             : 
   45051                 :         433 :       if (omp_for_parse_state->want_nested_loop)
   45052                 :             :         {
   45053                 :             :           /* We have already parsed the whole loop body and not found a
   45054                 :             :              nested loop.  */
   45055                 :          51 :           error_at (omp_for_parse_state->for_loc,
   45056                 :             :                     "not enough nested loops");
   45057                 :          51 :           omp_for_parse_state->fail = true;
   45058                 :             :         }
   45059                 :       26269 :       if_p = NULL;
   45060                 :             :     }
   45061                 :             :   else
   45062                 :             :     {
   45063                 :             :       /* This is the final-loop-body case in the grammar: we have something
   45064                 :             :          that is not a FOR and not an open brace.  */
   45065                 :       20282 :       if (moreloops)
   45066                 :             :         {
   45067                 :             :           /* If we were expecting a nested loop, give an error and mark
   45068                 :             :              that parsing has failed, and try to recover by parsing the
   45069                 :             :              body as regular code without further collapsing.  */
   45070                 :           4 :           error_at (omp_for_parse_state->for_loc,
   45071                 :             :                     "not enough nested loops");
   45072                 :           4 :           omp_for_parse_state->fail = true;
   45073                 :             :         }
   45074                 :       20282 :       parser->in_statement = IN_OMP_FOR;
   45075                 :             : 
   45076                 :             :       /* Generate the parts of range for that belong in the loop body,
   45077                 :             :          to be executed on every iteration.  This includes setting the
   45078                 :             :          user-declared decomposition variables from the compiler-generated
   45079                 :             :          temporaries that are the real iteration variables for OMP_FOR.
   45080                 :             :          FIXME:  Not sure if this is correct with respect to visibility
   45081                 :             :          of the variables from intervening code.  However, putting this
   45082                 :             :          code in each level of loop instead of all around the innermost
   45083                 :             :          body also makes the decomposition variables visible to the
   45084                 :             :          inner for init/bound/step exressions, which is not supposed to
   45085                 :             :          happen and causes test failures.  */
   45086                 :       20282 :       if (omp_for_parse_state->orig_declv)
   45087                 :         151 :         for (int i = 0; i < omp_for_parse_state->count; i++)
   45088                 :             :           {
   45089                 :          88 :             tree o = TREE_VEC_ELT (omp_for_parse_state->orig_declv, i);
   45090                 :          88 :             tree d = TREE_VEC_ELT (omp_for_parse_state->declv, i);
   45091                 :          88 :             if (o != d)
   45092                 :          70 :               cp_finish_omp_range_for (o, d);
   45093                 :             :           }
   45094                 :             : 
   45095                 :             :       /* Now parse the final-loop-body for the innermost loop.  */
   45096                 :       20282 :       parser->omp_for_parse_state = NULL;
   45097                 :       20282 :       if (omp_for_parse_state->inscan)
   45098                 :         355 :         cp_parser_omp_scan_loop_body (parser);
   45099                 :             :       else
   45100                 :       19927 :         cp_parser_statement (parser, NULL_TREE, false, if_p);
   45101                 :       20282 :       parser->omp_for_parse_state = omp_for_parse_state;
   45102                 :             :     }
   45103                 :       26269 :   parser->in_statement = save_in_statement;
   45104                 :       26269 :   omp_for_parse_state->want_nested_loop = false;
   45105                 :       26269 :   omp_for_parse_state->in_intervening_code = true;
   45106                 :             : 
   45107                 :             :   /* Pop and remember the body block.  Add the body placeholder
   45108                 :             :      to the surrounding statement list instead.  This is just a unique
   45109                 :             :      token that will be replaced when we reassemble the generated
   45110                 :             :      code for the entire omp for statement.  */
   45111                 :       26269 :   body_block = pop_stmt_list (body_block);
   45112                 :       26269 :   omp_for_parse_state->body_blockv[depth] = body_block;
   45113                 :       26269 :   add_stmt (body_placeholder);
   45114                 :             : 
   45115                 :             :   /* Pop and remember the init block.  */
   45116                 :       26269 :   if (sl)
   45117                 :         371 :     add_stmt (pop_stmt_list (sl));
   45118                 :       26269 :   finish_compound_stmt (init_scope);
   45119                 :       26269 :   init_block = pop_stmt_list (init_block);
   45120                 :       26269 :   omp_for_parse_state->init_blockv[depth] = init_block;
   45121                 :             : 
   45122                 :             :   /* Return the init placeholder rather than the remembered init block.
   45123                 :             :      Again, this is just a unique cookie that will be used to reassemble
   45124                 :             :      code pieces when the entire omp for statement has been parsed.  */
   45125                 :       26269 :   return init_placeholder;
   45126                 :             : }
   45127                 :             : 
   45128                 :             : /* Worker for find_structured_blocks.  *TP points to a STATEMENT_LIST
   45129                 :             :    and ITER is the element that is or contains a nested loop.  This
   45130                 :             :    function moves the statements before and after ITER into
   45131                 :             :    OMP_STRUCTURED_BLOCKs and modifies *TP.  */
   45132                 :             : static void
   45133                 :         186 : insert_structured_blocks (tree *tp, tree_stmt_iterator iter)
   45134                 :             : {
   45135                 :         186 :   tree sl = push_stmt_list ();
   45136                 :        1114 :   for (tree_stmt_iterator i = tsi_start (*tp); !tsi_end_p (i); )
   45137                 :         928 :     if (i == iter)
   45138                 :             :       {
   45139                 :         186 :         sl = pop_stmt_list (sl);
   45140                 :         186 :         if (TREE_CODE (sl) != STATEMENT_LIST || !tsi_end_p (tsi_start (sl)))
   45141                 :         182 :           tsi_link_before (&i,
   45142                 :             :                            build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl),
   45143                 :             :                            TSI_SAME_STMT);
   45144                 :         186 :         i++;
   45145                 :         186 :         sl = push_stmt_list ();
   45146                 :             :       }
   45147                 :             :     else
   45148                 :             :       {
   45149                 :         742 :         tree s = tsi_stmt (i);
   45150                 :         742 :         tsi_delink (&i);  /* Advances i to next statement.  */
   45151                 :         742 :         add_stmt (s);
   45152                 :             :       }
   45153                 :         186 :   sl = pop_stmt_list (sl);
   45154                 :         186 :   if (TREE_CODE (sl) != STATEMENT_LIST || !tsi_end_p (tsi_start (sl)))
   45155                 :         128 :     tsi_link_after (&iter,
   45156                 :             :                     build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl),
   45157                 :             :                     TSI_SAME_STMT);
   45158                 :         186 : }
   45159                 :             : 
   45160                 :             : /* Helper to find and mark structured blocks in intervening code for a
   45161                 :             :    single loop level with markers for later error checking.  *TP is the
   45162                 :             :    piece of code to be marked and INNER is the inner loop placeholder.
   45163                 :             :    Returns true if INNER was found (recursively) in *TP.  */
   45164                 :             : static bool
   45165                 :        6482 : find_structured_blocks (tree *tp, tree inner)
   45166                 :             : {
   45167                 :        6682 :   if (*tp == inner)
   45168                 :             :     return true;
   45169                 :         844 :   else if (TREE_CODE (*tp) == BIND_EXPR)
   45170                 :         198 :     return find_structured_blocks (&(BIND_EXPR_BODY (*tp)), inner);
   45171                 :         646 :   else if (TREE_CODE (*tp) == STATEMENT_LIST)
   45172                 :             :     {
   45173                 :         644 :       for (tree_stmt_iterator i = tsi_start (*tp); !tsi_end_p (i); ++i)
   45174                 :             :         {
   45175                 :         644 :           tree *p = tsi_stmt_ptr (i);
   45176                 :             :           /* The normal case is that there is no intervening code and we
   45177                 :             :              do not have to insert any OMP_STRUCTURED_BLOCK markers.  */
   45178                 :         644 :           if (find_structured_blocks (p, inner))
   45179                 :             :             {
   45180                 :         190 :               if (!(i == tsi_start (*tp) && i == tsi_last (*tp)))
   45181                 :         186 :                 insert_structured_blocks (tp, i);
   45182                 :         186 :               return true;
   45183                 :             :             }
   45184                 :             :         }
   45185                 :             :       return false;
   45186                 :             :     }
   45187                 :         460 :   else if (TREE_CODE (*tp) == TRY_FINALLY_EXPR)
   45188                 :           0 :     return find_structured_blocks (&(TREE_OPERAND (*tp, 0)), inner);
   45189                 :         460 :   else if (TREE_CODE (*tp) == CLEANUP_STMT)
   45190                 :           2 :     return find_structured_blocks (&(CLEANUP_BODY (*tp)), inner);
   45191                 :             :   else
   45192                 :             :     return false;
   45193                 :             : }
   45194                 :             : 
   45195                 :             : /* Helpers used for relinking tree structures: In tree rooted at
   45196                 :             :    CONTEXT, replace ORIG with REPLACEMENT.  If FLATTEN is true, try to combine
   45197                 :             :    nested BIND_EXPRs.  Gives an assertion if it fails to find ORIG.  */
   45198                 :             : 
   45199                 :             : struct sit_data {
   45200                 :             :   tree orig;
   45201                 :             :   tree repl;
   45202                 :             :   bool flatten;
   45203                 :             : };
   45204                 :             : 
   45205                 :             : static tree
   45206                 :       59746 : substitute_in_tree_walker (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
   45207                 :             :                            void *dp)
   45208                 :             : {
   45209                 :       59746 :   struct sit_data *sit = (struct sit_data *)dp;
   45210                 :       59746 :   if (*tp == sit->orig)
   45211                 :             :     {
   45212                 :       26866 :       *tp = sit->repl;
   45213                 :       26866 :       return *tp;
   45214                 :             :     }
   45215                 :             :   /* Remove redundant BIND_EXPRs with no bindings even when not specifically
   45216                 :             :      trying to flatten.  */
   45217                 :       32880 :   else if (TREE_CODE (*tp) == BIND_EXPR
   45218                 :        9506 :            && BIND_EXPR_BODY (*tp) == sit->orig
   45219                 :        8999 :            && !BIND_EXPR_VARS (*tp)
   45220                 :       35648 :            && (sit->flatten || TREE_CODE (sit->repl) == BIND_EXPR))
   45221                 :             :     {
   45222                 :        2736 :       *tp = sit->repl;
   45223                 :        2736 :       return *tp;
   45224                 :             :     }
   45225                 :       30144 :   else if (sit->flatten
   45226                 :       27590 :            && TREE_CODE (*tp) == BIND_EXPR
   45227                 :        6558 :            && TREE_CODE (sit->repl) == BIND_EXPR)
   45228                 :             :     {
   45229                 :        1254 :       if (BIND_EXPR_BODY (*tp) == sit->orig)
   45230                 :             :         {
   45231                 :             :           /* Merge binding lists for two directly nested BIND_EXPRs,
   45232                 :             :              keeping the outer one.  */
   45233                 :        1158 :           BIND_EXPR_VARS (*tp) = chainon (BIND_EXPR_VARS (*tp),
   45234                 :        1158 :                                           BIND_EXPR_VARS (sit->repl));
   45235                 :        1158 :           BIND_EXPR_BODY (*tp) = BIND_EXPR_BODY (sit->repl);
   45236                 :        1158 :           return *tp;
   45237                 :             :         }
   45238                 :          96 :       else if (TREE_CODE (BIND_EXPR_BODY (*tp)) == STATEMENT_LIST)
   45239                 :             :         /* There might be a statement list containing cleanup_points
   45240                 :             :            etc between the two levels of BIND_EXPR.  We can still merge
   45241                 :             :            them, again keeping the outer BIND_EXPR.  */
   45242                 :         381 :         for (tree_stmt_iterator i = tsi_start (BIND_EXPR_BODY (*tp));
   45243                 :         381 :              !tsi_end_p (i); ++i)
   45244                 :             :           {
   45245                 :         307 :             tree *p = tsi_stmt_ptr (i);
   45246                 :         307 :             if (*p == sit->orig)
   45247                 :             :               {
   45248                 :          22 :                 BIND_EXPR_VARS (*tp) = chainon (BIND_EXPR_VARS (*tp),
   45249                 :          22 :                                                 BIND_EXPR_VARS (sit->repl));
   45250                 :          22 :                 *p = BIND_EXPR_BODY (sit->repl);
   45251                 :          22 :                 return *tp;
   45252                 :             :               }
   45253                 :             :           }
   45254                 :             :     }
   45255                 :             :   return NULL;
   45256                 :             : }
   45257                 :             : 
   45258                 :             : static void
   45259                 :       30782 : substitute_in_tree (tree *context, tree orig, tree repl, bool flatten)
   45260                 :             : {
   45261                 :       30782 :   struct sit_data data;
   45262                 :             : 
   45263                 :       30782 :   gcc_assert (*context && orig && repl);
   45264                 :       30782 :   if (TREE_CODE (repl) == BIND_EXPR && !BIND_EXPR_VARS (repl))
   45265                 :         398 :     repl = BIND_EXPR_BODY (repl);
   45266                 :       30782 :   data.orig = orig;
   45267                 :       30782 :   data.repl = repl;
   45268                 :       30782 :   data.flatten = flatten;
   45269                 :             : 
   45270                 :       30782 :   tree result = cp_walk_tree (context, substitute_in_tree_walker,
   45271                 :             :                               (void *)&data, NULL);
   45272                 :       30782 :   gcc_assert (result != NULL_TREE);
   45273                 :       30782 : }
   45274                 :             : 
   45275                 :             : /* Walker to patch up the BLOCK_NODE hierarchy after the above surgery.
   45276                 :             :    *DP is the parent block.  */
   45277                 :             : 
   45278                 :             : static tree
   45279                 :      872506 : fixup_blocks_walker (tree *tp, int *walk_subtrees, void *dp)
   45280                 :             : {
   45281                 :      872506 :   tree superblock = *(tree *)dp;
   45282                 :             : 
   45283                 :             :   /* BIND_EXPR_BLOCK may be null if the expression is not a
   45284                 :             :      full-expression; if there's no block, no patching is necessary
   45285                 :             :      for this node.  */
   45286                 :      872506 :   if (TREE_CODE (*tp) == BIND_EXPR && BIND_EXPR_BLOCK (*tp))
   45287                 :             :     {
   45288                 :        8662 :       tree block = BIND_EXPR_BLOCK (*tp);
   45289                 :        8662 :       if (superblock)
   45290                 :             :         {
   45291                 :        2329 :           BLOCK_SUPERCONTEXT (block) = superblock;
   45292                 :        2329 :           BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (superblock);
   45293                 :        2329 :           BLOCK_SUBBLOCKS (superblock) = block;
   45294                 :             :         }
   45295                 :        8662 :       BLOCK_SUBBLOCKS (block) = NULL_TREE;
   45296                 :        8662 :       cp_walk_tree (&BIND_EXPR_BODY (*tp), fixup_blocks_walker,
   45297                 :             :                     (void *)&block, NULL);
   45298                 :        8662 :       *walk_subtrees = 0;
   45299                 :             :     }
   45300                 :             : 
   45301                 :      872506 :   return NULL;
   45302                 :             : }
   45303                 :             : 
   45304                 :             : /* Parse the restricted form of the for statement allowed by OpenMP.  */
   45305                 :             : 
   45306                 :             : static tree
   45307                 :       20360 : cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
   45308                 :             :                         tree *cclauses, bool *if_p)
   45309                 :             : {
   45310                 :       20360 :   tree ret;
   45311                 :       20360 :   tree cl, ordered_cl = NULL_TREE;
   45312                 :       20360 :   int collapse = 1, ordered = 0;
   45313                 :       20360 :   unsigned int count;
   45314                 :       20360 :   bool tiling = false;
   45315                 :       20360 :   bool inscan = false;
   45316                 :       20360 :   struct omp_for_parse_data data;
   45317                 :       20360 :   struct omp_for_parse_data *save_data = parser->omp_for_parse_state;
   45318                 :       20360 :   tree result;
   45319                 :       20360 :   location_t loc_first = cp_lexer_peek_token (parser->lexer)->location;
   45320                 :             : 
   45321                 :       49174 :   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
   45322                 :       28814 :     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
   45323                 :        4456 :       collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
   45324                 :       24358 :     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
   45325                 :             :       {
   45326                 :         309 :         tiling = true;
   45327                 :         309 :         collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
   45328                 :             :       }
   45329                 :       24049 :     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
   45330                 :       24049 :              && OMP_CLAUSE_ORDERED_EXPR (cl))
   45331                 :             :       {
   45332                 :         400 :         ordered_cl = cl;
   45333                 :         400 :         ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
   45334                 :             :       }
   45335                 :       23649 :     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
   45336                 :        4241 :              && OMP_CLAUSE_REDUCTION_INSCAN (cl)
   45337                 :       24024 :              && (code == OMP_SIMD || code == OMP_FOR))
   45338                 :             :       inscan = true;
   45339                 :             : 
   45340                 :       20360 :   if (ordered && ordered < collapse)
   45341                 :             :     {
   45342                 :           8 :       error_at (OMP_CLAUSE_LOCATION (ordered_cl),
   45343                 :             :                 "%<ordered%> clause parameter is less than %<collapse%>");
   45344                 :           8 :       OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
   45345                 :           8 :         = build_int_cst (NULL_TREE, collapse);
   45346                 :           8 :       ordered = collapse;
   45347                 :             :     }
   45348                 :             : 
   45349                 :       20360 :   gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
   45350                 :       20360 :   count = ordered ? ordered : collapse;
   45351                 :             : 
   45352                 :       20360 :   if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
   45353                 :             :     {
   45354                 :          27 :       cp_parser_error (parser, "for statement expected");
   45355                 :          27 :       return NULL;
   45356                 :             :     }
   45357                 :             : 
   45358                 :             :   /* Initialize parse state for recursive descent.  */
   45359                 :       20333 :   data.declv = make_tree_vec (count);
   45360                 :       20333 :   data.initv = make_tree_vec (count);
   45361                 :       20333 :   data.condv = make_tree_vec (count);
   45362                 :       20333 :   data.incrv = make_tree_vec (count);
   45363                 :       20333 :   data.pre_body = NULL_TREE;
   45364                 :       20333 :   data.for_loc = cp_lexer_peek_token (parser->lexer)->location;
   45365                 :       20333 :   data.count = count;
   45366                 :       20333 :   data.depth = 0;
   45367                 :       20333 :   data.want_nested_loop = true;
   45368                 :       20333 :   data.ordered = ordered > 0;
   45369                 :       20333 :   data.in_intervening_code = false;
   45370                 :       20333 :   data.perfect_nesting_fail = false;
   45371                 :       20333 :   data.fail = false;
   45372                 :       20333 :   data.inscan = inscan;
   45373                 :       20333 :   data.saw_intervening_code = false;
   45374                 :       20333 :   data.code = code;
   45375                 :       20333 :   data.orig_declv = NULL_TREE;
   45376                 :       20333 :   data.clauses = clauses;
   45377                 :       20333 :   data.cclauses = cclauses;
   45378                 :       20333 :   data.ordered_cl = ordered_cl;
   45379                 :       20333 :   parser->omp_for_parse_state = &data;
   45380                 :             : 
   45381                 :       20333 :   cp_parser_omp_loop_nest (parser, if_p);
   45382                 :             : 
   45383                 :             :   /* Bomb out early if there was an error (not enough loops, etc).  */
   45384                 :       20333 :   if (data.fail || data.declv == NULL_TREE)
   45385                 :             :     {
   45386                 :         111 :       parser->omp_for_parse_state = save_data;
   45387                 :         111 :       return NULL_TREE;
   45388                 :             :     }
   45389                 :             : 
   45390                 :             :   /* Relink the init and body blocks that were built during parsing.  At
   45391                 :             :      this point we have a structure nested like
   45392                 :             :        init 0
   45393                 :             :          body 0
   45394                 :             :            init 1
   45395                 :             :              body 1
   45396                 :             :                init 2
   45397                 :             :                  body 2
   45398                 :             :      and we want to turn it into
   45399                 :             :       init 0
   45400                 :             :          init 1
   45401                 :             :            init 2
   45402                 :             :              omp_for
   45403                 :             :                body 0
   45404                 :             :                  body 1
   45405                 :             :                    body 2
   45406                 :             :      We also need to flatten the init blocks, as some code for later
   45407                 :             :      processing of combined directives gets confused otherwise.  */
   45408                 :             : 
   45409                 :       20222 :   gcc_assert (vec_safe_length (data.init_blockv) == count);
   45410                 :       20222 :   gcc_assert (vec_safe_length (data.body_blockv) == count);
   45411                 :       20222 :   gcc_assert (vec_safe_length (data.init_placeholderv) == count);
   45412                 :       20222 :   gcc_assert (vec_safe_length (data.body_placeholderv) == count);
   45413                 :             : 
   45414                 :             :   /* First insert markers for structured blocks for intervening code in
   45415                 :             :      the loop bodies.  */
   45416                 :       26060 :   for (unsigned int i = 0; i < count - 1; i++)
   45417                 :             :     {
   45418                 :        5838 :       bool good = find_structured_blocks (&(data.body_blockv[i]),
   45419                 :        5838 :                                           data.init_placeholderv[i+1]);
   45420                 :        5838 :       gcc_assert (good);
   45421                 :             :     }
   45422                 :             : 
   45423                 :             :   /* Do the substitution from the inside out.  */
   45424                 :       26060 :   for (unsigned int i = count - 1; i > 0; i--)
   45425                 :             :     {
   45426                 :        5838 :       substitute_in_tree (&(data.body_blockv[i-1]),
   45427                 :        5838 :                           data.init_placeholderv[i],
   45428                 :        5838 :                           data.body_blockv[i], false);
   45429                 :        5838 :       substitute_in_tree (&(data.init_blockv[i-1]),
   45430                 :        5838 :                           data.body_placeholderv[i-1],
   45431                 :        5838 :                           data.init_blockv[i], true);
   45432                 :             :     }
   45433                 :             : 
   45434                 :             :   /* Generate the OMP_FOR.  Note finish_omp_for adds the OMP_FOR
   45435                 :             :      (and possibly other stuff) to the current statement list but
   45436                 :             :      returns a pointer to the OMP_FOR itself, or null in case of error.  */
   45437                 :       20222 :   result = push_stmt_list ();
   45438                 :       20222 :   ret = finish_omp_for (loc_first, code, data.declv, data.orig_declv,
   45439                 :             :                         data.initv, data.condv, data.incrv,
   45440                 :       20222 :                         data.body_blockv[0],
   45441                 :             :                         data.pre_body, &data.orig_inits, data.clauses);
   45442                 :       20222 :   result = pop_stmt_list (result);
   45443                 :             : 
   45444                 :             :   /* Check for errors involving lb/ub/incr expressions referencing
   45445                 :             :      variables declared in intervening code.  */
   45446                 :       20222 :   if (data.saw_intervening_code
   45447                 :       20222 :       && !c_omp_check_loop_binding_exprs (ret, &data.orig_inits))
   45448                 :             :     ret = NULL_TREE;
   45449                 :             : 
   45450                 :       20174 :   if (ret)
   45451                 :             :     {
   45452                 :             :       /* Splice the omp_for into the nest of init blocks.  */
   45453                 :       19106 :       substitute_in_tree (&(data.init_blockv[0]),
   45454                 :       19106 :                           data.body_placeholderv[count - 1],
   45455                 :             :                           result, true);
   45456                 :             : 
   45457                 :             :       /* Some later processing for combined directives assumes
   45458                 :             :          that the BIND_EXPR containing range for variables appears
   45459                 :             :          at top level in the OMP_FOR body.  Fix that up if it's
   45460                 :             :          not the case, e.g. because there is intervening code.  */
   45461                 :       19106 :       if (code != OACC_LOOP)
   45462                 :       13706 :         finish_omp_for_block (data.init_blockv[0], ret);
   45463                 :             : 
   45464                 :             :       /* Clean up the block subblock/superblock links.  Per comment in
   45465                 :             :          begin_compound_stmt, "we don't build BLOCK nodes when processing
   45466                 :             :          templates", so skip this step in that case.  */
   45467                 :       19106 :       if (!processing_template_decl)
   45468                 :             :         {
   45469                 :       18170 :           tree superblock = NULL_TREE;
   45470                 :       18170 :           cp_walk_tree (&data.init_blockv[0], fixup_blocks_walker,
   45471                 :             :                         (void *)&superblock, NULL);
   45472                 :             :         }
   45473                 :             : 
   45474                 :             :       /* Finally record the result.  */
   45475                 :       19106 :       add_stmt (data.init_blockv[0]);
   45476                 :             :     }
   45477                 :             : 
   45478                 :       20222 :   parser->omp_for_parse_state = save_data;
   45479                 :       20222 :   return ret;
   45480                 :       20360 : }
   45481                 :             : 
   45482                 :             : /* Helper function for OpenMP parsing, split clauses and call
   45483                 :             :    finish_omp_clauses on each of the set of clauses afterwards.  */
   45484                 :             : 
   45485                 :             : static void
   45486                 :        9714 : cp_omp_split_clauses (location_t loc, enum tree_code code,
   45487                 :             :                       omp_clause_mask mask, tree clauses, tree *cclauses)
   45488                 :             : {
   45489                 :        9714 :   int i;
   45490                 :        9714 :   c_omp_split_clauses (loc, code, mask, clauses, cclauses);
   45491                 :       77712 :   for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
   45492                 :       58284 :     if (cclauses[i])
   45493                 :       32685 :       cclauses[i] = finish_omp_clauses (cclauses[i],
   45494                 :             :                                         i == C_OMP_CLAUSE_SPLIT_TARGET
   45495                 :             :                                         ? C_ORT_OMP_TARGET : C_ORT_OMP);
   45496                 :        9714 : }
   45497                 :             : 
   45498                 :             : /* OpenMP 5.0:
   45499                 :             :    #pragma omp loop loop-clause[optseq] new-line
   45500                 :             :      for-loop  */
   45501                 :             : 
   45502                 :             : #define OMP_LOOP_CLAUSE_MASK                                    \
   45503                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   45504                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   45505                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   45506                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   45507                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND)           \
   45508                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   45509                 :             : 
   45510                 :             : static tree
   45511                 :         881 : cp_parser_omp_loop (cp_parser *parser, cp_token *pragma_tok,
   45512                 :             :                     char *p_name, omp_clause_mask mask, tree *cclauses,
   45513                 :             :                     bool *if_p)
   45514                 :             : {
   45515                 :         881 :   tree clauses, sb, ret;
   45516                 :         881 :   unsigned int save;
   45517                 :         881 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   45518                 :             : 
   45519                 :         881 :   strcat (p_name, " loop");
   45520                 :         881 :   mask |= OMP_LOOP_CLAUSE_MASK;
   45521                 :             : 
   45522                 :         881 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   45523                 :             :                                        cclauses == NULL);
   45524                 :         881 :   if (cclauses)
   45525                 :             :     {
   45526                 :         259 :       cp_omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
   45527                 :         259 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
   45528                 :             :     }
   45529                 :             : 
   45530                 :         881 :   keep_next_level (true);
   45531                 :         881 :   sb = begin_omp_structured_block ();
   45532                 :         881 :   save = cp_parser_begin_omp_structured_block (parser);
   45533                 :             : 
   45534                 :         881 :   ret = cp_parser_omp_for_loop (parser, OMP_LOOP, clauses, cclauses, if_p);
   45535                 :             : 
   45536                 :         881 :   cp_parser_end_omp_structured_block (parser, save);
   45537                 :         881 :   add_stmt (finish_omp_structured_block (sb));
   45538                 :             : 
   45539                 :         881 :   return ret;
   45540                 :             : }
   45541                 :             : 
   45542                 :             : /* OpenMP 4.0:
   45543                 :             :    #pragma omp simd simd-clause[optseq] new-line
   45544                 :             :      for-loop  */
   45545                 :             : 
   45546                 :             : #define OMP_SIMD_CLAUSE_MASK                                    \
   45547                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN)        \
   45548                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)        \
   45549                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
   45550                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)        \
   45551                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   45552                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   45553                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   45554                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   45555                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   45556                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)    \
   45557                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   45558                 :             : 
   45559                 :             : static tree
   45560                 :        5382 : cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
   45561                 :             :                     char *p_name, omp_clause_mask mask, tree *cclauses,
   45562                 :             :                     bool *if_p)
   45563                 :             : {
   45564                 :        5382 :   tree clauses, sb, ret;
   45565                 :        5382 :   unsigned int save;
   45566                 :        5382 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   45567                 :             : 
   45568                 :        5382 :   strcat (p_name, " simd");
   45569                 :        5382 :   mask |= OMP_SIMD_CLAUSE_MASK;
   45570                 :             : 
   45571                 :        5382 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   45572                 :             :                                        cclauses == NULL);
   45573                 :        5382 :   if (cclauses)
   45574                 :             :     {
   45575                 :        4144 :       cp_omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
   45576                 :        4144 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
   45577                 :             :     }
   45578                 :             : 
   45579                 :        5382 :   keep_next_level (true);
   45580                 :        5382 :   sb = begin_omp_structured_block ();
   45581                 :        5382 :   save = cp_parser_begin_omp_structured_block (parser);
   45582                 :             : 
   45583                 :        5382 :   ret = cp_parser_omp_for_loop (parser, OMP_SIMD, clauses, cclauses, if_p);
   45584                 :             : 
   45585                 :        5382 :   cp_parser_end_omp_structured_block (parser, save);
   45586                 :        5382 :   add_stmt (finish_omp_structured_block (sb));
   45587                 :             : 
   45588                 :        5382 :   return ret;
   45589                 :             : }
   45590                 :             : 
   45591                 :             : /* OpenMP 2.5:
   45592                 :             :    #pragma omp for for-clause[optseq] new-line
   45593                 :             :      for-loop
   45594                 :             : 
   45595                 :             :    OpenMP 4.0:
   45596                 :             :    #pragma omp for simd for-simd-clause[optseq] new-line
   45597                 :             :      for-loop  */
   45598                 :             : 
   45599                 :             : #define OMP_FOR_CLAUSE_MASK                                     \
   45600                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   45601                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   45602                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   45603                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
   45604                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   45605                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)        \
   45606                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)       \
   45607                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
   45608                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   45609                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   45610                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   45611                 :             : 
   45612                 :             : static tree
   45613                 :       10423 : cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
   45614                 :             :                    char *p_name, omp_clause_mask mask, tree *cclauses,
   45615                 :             :                    bool *if_p)
   45616                 :             : {
   45617                 :       10423 :   tree clauses, sb, ret;
   45618                 :       10423 :   unsigned int save;
   45619                 :       10423 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   45620                 :             : 
   45621                 :       10423 :   strcat (p_name, " for");
   45622                 :       10423 :   mask |= OMP_FOR_CLAUSE_MASK;
   45623                 :             :   /* parallel for{, simd} disallows nowait clause, but for
   45624                 :             :      target {teams distribute ,}parallel for{, simd} it should be accepted.  */
   45625                 :       10423 :   if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
   45626                 :        4534 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
   45627                 :             :   /* Composite distribute parallel for{, simd} disallows ordered clause.  */
   45628                 :       10423 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
   45629                 :        3439 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
   45630                 :             : 
   45631                 :       10423 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   45632                 :             :     {
   45633                 :        8137 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   45634                 :        8137 :       const char *p = IDENTIFIER_POINTER (id);
   45635                 :             : 
   45636                 :        8137 :       if (strcmp (p, "simd") == 0)
   45637                 :             :         {
   45638                 :        2950 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   45639                 :        2950 :           if (cclauses == NULL)
   45640                 :         590 :             cclauses = cclauses_buf;
   45641                 :             : 
   45642                 :        2950 :           cp_lexer_consume_token (parser->lexer);
   45643                 :        2950 :           if (!flag_openmp)  /* flag_openmp_simd  */
   45644                 :          52 :             return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
   45645                 :          52 :                                        cclauses, if_p);
   45646                 :        2898 :           sb = begin_omp_structured_block ();
   45647                 :        2898 :           save = cp_parser_begin_omp_structured_block (parser);
   45648                 :        2898 :           ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
   45649                 :             :                                     cclauses, if_p);
   45650                 :        2898 :           cp_parser_end_omp_structured_block (parser, save);
   45651                 :        2898 :           tree body = finish_omp_structured_block (sb);
   45652                 :        2898 :           if (ret == NULL)
   45653                 :             :             return ret;
   45654                 :        2878 :           ret = make_node (OMP_FOR);
   45655                 :        2878 :           TREE_TYPE (ret) = void_type_node;
   45656                 :        2878 :           OMP_FOR_BODY (ret) = body;
   45657                 :        2878 :           OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
   45658                 :        2878 :           SET_EXPR_LOCATION (ret, loc);
   45659                 :        2878 :           add_stmt (ret);
   45660                 :        2878 :           return ret;
   45661                 :             :         }
   45662                 :             :     }
   45663                 :        7473 :   if (!flag_openmp)  /* flag_openmp_simd  */
   45664                 :             :     {
   45665                 :          36 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   45666                 :          36 :       return NULL_TREE;
   45667                 :             :     }
   45668                 :             : 
   45669                 :             :   /* Composite distribute parallel for disallows linear clause.  */
   45670                 :        7437 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
   45671                 :        1781 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
   45672                 :             : 
   45673                 :        7437 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   45674                 :             :                                        cclauses == NULL);
   45675                 :        7437 :   if (cclauses)
   45676                 :             :     {
   45677                 :        3398 :       cp_omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
   45678                 :        3398 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
   45679                 :             :     }
   45680                 :             : 
   45681                 :        7437 :   keep_next_level (true);
   45682                 :        7437 :   sb = begin_omp_structured_block ();
   45683                 :        7437 :   save = cp_parser_begin_omp_structured_block (parser);
   45684                 :             : 
   45685                 :        7437 :   ret = cp_parser_omp_for_loop (parser, OMP_FOR, clauses, cclauses, if_p);
   45686                 :             : 
   45687                 :        7437 :   cp_parser_end_omp_structured_block (parser, save);
   45688                 :        7437 :   add_stmt (finish_omp_structured_block (sb));
   45689                 :             : 
   45690                 :        7437 :   return ret;
   45691                 :             : }
   45692                 :             : 
   45693                 :             : static tree cp_parser_omp_taskloop (cp_parser *, cp_token *, char *,
   45694                 :             :                                     omp_clause_mask, tree *, bool *);
   45695                 :             : 
   45696                 :             : /* OpenMP 2.5:
   45697                 :             :    # pragma omp master new-line
   45698                 :             :      structured-block  */
   45699                 :             : 
   45700                 :             : static tree
   45701                 :         650 : cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok,
   45702                 :             :                       char *p_name, omp_clause_mask mask, tree *cclauses,
   45703                 :             :                       bool *if_p)
   45704                 :             : {
   45705                 :         650 :   tree clauses, sb, ret;
   45706                 :         650 :   unsigned int save;
   45707                 :         650 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   45708                 :             : 
   45709                 :         650 :   strcat (p_name, " master");
   45710                 :             : 
   45711                 :         650 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   45712                 :             :     {
   45713                 :         358 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   45714                 :         358 :       const char *p = IDENTIFIER_POINTER (id);
   45715                 :             : 
   45716                 :         358 :       if (strcmp (p, "taskloop") == 0)
   45717                 :             :         {
   45718                 :         336 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   45719                 :         336 :           if (cclauses == NULL)
   45720                 :         165 :             cclauses = cclauses_buf;
   45721                 :             : 
   45722                 :         336 :           cp_lexer_consume_token (parser->lexer);
   45723                 :         336 :           if (!flag_openmp)  /* flag_openmp_simd  */
   45724                 :          16 :             return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
   45725                 :          16 :                                            cclauses, if_p);
   45726                 :         320 :           sb = begin_omp_structured_block ();
   45727                 :         320 :           save = cp_parser_begin_omp_structured_block (parser);
   45728                 :         320 :           ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
   45729                 :             :                                         cclauses, if_p);
   45730                 :         320 :           cp_parser_end_omp_structured_block (parser, save);
   45731                 :         320 :           tree body = finish_omp_structured_block (sb);
   45732                 :         320 :           if (ret == NULL)
   45733                 :             :             return ret;
   45734                 :         316 :           ret = c_finish_omp_master (loc, body);
   45735                 :         316 :           OMP_MASTER_COMBINED (ret) = 1;
   45736                 :         316 :           return ret;
   45737                 :             :         }
   45738                 :             :     }
   45739                 :         314 :   if (!flag_openmp)  /* flag_openmp_simd  */
   45740                 :             :     {
   45741                 :           8 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   45742                 :           8 :       return NULL_TREE;
   45743                 :             :     }
   45744                 :             : 
   45745                 :         306 :   if (cclauses)
   45746                 :             :     {
   45747                 :          65 :       clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   45748                 :             :                                            false);
   45749                 :          65 :       cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
   45750                 :             :     }
   45751                 :             :   else
   45752                 :         241 :     cp_parser_require_pragma_eol (parser, pragma_tok);
   45753                 :             : 
   45754                 :         306 :   return c_finish_omp_master (loc,
   45755                 :         306 :                               cp_parser_omp_structured_block (parser, if_p));
   45756                 :             : }
   45757                 :             : 
   45758                 :             : /* OpenMP 5.1:
   45759                 :             :    # pragma omp masked masked-clauses new-line
   45760                 :             :      structured-block  */
   45761                 :             : 
   45762                 :             : #define OMP_MASKED_CLAUSE_MASK                                  \
   45763                 :             :         (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
   45764                 :             : 
   45765                 :             : static tree
   45766                 :         271 : cp_parser_omp_masked (cp_parser *parser, cp_token *pragma_tok,
   45767                 :             :                       char *p_name, omp_clause_mask mask, tree *cclauses,
   45768                 :             :                       bool *if_p)
   45769                 :             : {
   45770                 :         271 :   tree clauses, sb, ret;
   45771                 :         271 :   unsigned int save;
   45772                 :         271 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   45773                 :             : 
   45774                 :         271 :   strcat (p_name, " masked");
   45775                 :         271 :   mask |= OMP_MASKED_CLAUSE_MASK;
   45776                 :             : 
   45777                 :         271 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   45778                 :             :     {
   45779                 :         201 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   45780                 :         201 :       const char *p = IDENTIFIER_POINTER (id);
   45781                 :             : 
   45782                 :         201 :       if (strcmp (p, "taskloop") == 0)
   45783                 :             :         {
   45784                 :         145 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   45785                 :         145 :           if (cclauses == NULL)
   45786                 :          69 :             cclauses = cclauses_buf;
   45787                 :             : 
   45788                 :         145 :           cp_lexer_consume_token (parser->lexer);
   45789                 :         145 :           if (!flag_openmp)  /* flag_openmp_simd  */
   45790                 :           0 :             return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
   45791                 :           0 :                                            cclauses, if_p);
   45792                 :         145 :           sb = begin_omp_structured_block ();
   45793                 :         145 :           save = cp_parser_begin_omp_structured_block (parser);
   45794                 :         145 :           ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
   45795                 :             :                                         cclauses, if_p);
   45796                 :         145 :           cp_parser_end_omp_structured_block (parser, save);
   45797                 :         145 :           tree body = finish_omp_structured_block (sb);
   45798                 :         145 :           if (ret == NULL)
   45799                 :             :             return ret;
   45800                 :         145 :           ret = c_finish_omp_masked (loc, body,
   45801                 :             :                                      cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
   45802                 :         145 :           OMP_MASKED_COMBINED (ret) = 1;
   45803                 :         145 :           return ret;
   45804                 :             :         }
   45805                 :             :     }
   45806                 :         126 :   if (!flag_openmp)  /* flag_openmp_simd  */
   45807                 :             :     {
   45808                 :           0 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   45809                 :           0 :       return NULL_TREE;
   45810                 :             :     }
   45811                 :             : 
   45812                 :         126 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   45813                 :             :                                        cclauses == NULL);
   45814                 :         126 :   if (cclauses)
   45815                 :             :     {
   45816                 :          28 :       cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
   45817                 :          28 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
   45818                 :             :     }
   45819                 :             : 
   45820                 :         126 :   return c_finish_omp_masked (loc,
   45821                 :             :                               cp_parser_omp_structured_block (parser, if_p),
   45822                 :         126 :                               clauses);
   45823                 :             : }
   45824                 :             : 
   45825                 :             : /* OpenMP 2.5:
   45826                 :             :    # pragma omp ordered new-line
   45827                 :             :      structured-block
   45828                 :             : 
   45829                 :             :    OpenMP 4.5:
   45830                 :             :    # pragma omp ordered ordered-clauses new-line
   45831                 :             :      structured-block  */
   45832                 :             : 
   45833                 :             : #define OMP_ORDERED_CLAUSE_MASK                                 \
   45834                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)        \
   45835                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
   45836                 :             : 
   45837                 :             : #define OMP_ORDERED_DEPEND_CLAUSE_MASK                          \
   45838                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   45839                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
   45840                 :             : 
   45841                 :             : static bool
   45842                 :        1309 : cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
   45843                 :             :                        enum pragma_context context, bool *if_p)
   45844                 :             : {
   45845                 :        1309 :   location_t loc = pragma_tok->location;
   45846                 :        1309 :   int n = 1;
   45847                 :             : 
   45848                 :        1309 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   45849                 :          28 :     n = 2;
   45850                 :             : 
   45851                 :        1309 :   if (cp_lexer_nth_token_is (parser->lexer, n, CPP_NAME))
   45852                 :             :     {
   45853                 :        1072 :       tree id = cp_lexer_peek_nth_token (parser->lexer, n)->u.value;
   45854                 :        1072 :       const char *p = IDENTIFIER_POINTER (id);
   45855                 :             : 
   45856                 :        1072 :       if (strcmp (p, "depend") == 0 || strcmp (p, "doacross") == 0)
   45857                 :             :         {
   45858                 :         766 :           if (!flag_openmp)     /* flag_openmp_simd */
   45859                 :             :             {
   45860                 :           8 :               cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   45861                 :           8 :               return false;
   45862                 :             :             }
   45863                 :         758 :           if (context == pragma_stmt)
   45864                 :             :             {
   45865                 :          64 :               error_at (pragma_tok->location, "%<#pragma omp ordered%> with "
   45866                 :             :                         "%qs clause may only be used in compound "
   45867                 :             :                         "statements", p);
   45868                 :          64 :               cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   45869                 :          64 :               return true;
   45870                 :             :             }
   45871                 :         694 :           tree clauses
   45872                 :         694 :             = cp_parser_omp_all_clauses (parser,
   45873                 :         694 :                                          OMP_ORDERED_DEPEND_CLAUSE_MASK,
   45874                 :             :                                          "#pragma omp ordered", pragma_tok);
   45875                 :         694 :           c_finish_omp_ordered (loc, clauses, NULL_TREE);
   45876                 :         694 :           return false;
   45877                 :             :         }
   45878                 :             :     }
   45879                 :             : 
   45880                 :         543 :   tree clauses
   45881                 :         543 :     = cp_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
   45882                 :             :                                  "#pragma omp ordered", pragma_tok);
   45883                 :             : 
   45884                 :         543 :   if (!flag_openmp     /* flag_openmp_simd  */
   45885                 :         543 :       && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
   45886                 :             :     return false;
   45887                 :             : 
   45888                 :         535 :   c_finish_omp_ordered (loc, clauses,
   45889                 :             :                         cp_parser_omp_structured_block (parser, if_p));
   45890                 :         535 :   return true;
   45891                 :             : }
   45892                 :             : 
   45893                 :             : /* OpenMP 2.5:
   45894                 :             : 
   45895                 :             :    section-scope:
   45896                 :             :      { section-sequence }
   45897                 :             : 
   45898                 :             :    section-sequence:
   45899                 :             :      section-directive[opt] structured-block
   45900                 :             :      section-sequence section-directive structured-block  */
   45901                 :             : 
   45902                 :             : static tree
   45903                 :         464 : cp_parser_omp_sections_scope (cp_parser *parser)
   45904                 :             : {
   45905                 :         464 :   tree stmt, substmt;
   45906                 :         464 :   bool error_suppress = false;
   45907                 :         464 :   cp_token *tok;
   45908                 :             : 
   45909                 :         464 :   matching_braces braces;
   45910                 :         464 :   if (!braces.require_open (parser))
   45911                 :             :     return NULL_TREE;
   45912                 :             : 
   45913                 :         456 :   stmt = push_stmt_list ();
   45914                 :             : 
   45915                 :         456 :   if (cp_parser_pragma_kind (cp_lexer_peek_token (parser->lexer))
   45916                 :             :       != PRAGMA_OMP_SECTION
   45917                 :         456 :       && !cp_parser_omp_section_scan (parser, "section", true))
   45918                 :             :     {
   45919                 :         291 :       substmt = cp_parser_omp_structured_block_sequence (parser,
   45920                 :             :                                                          PRAGMA_OMP_SECTION);
   45921                 :         291 :       substmt = build1 (OMP_SECTION, void_type_node, substmt);
   45922                 :         291 :       add_stmt (substmt);
   45923                 :             :     }
   45924                 :             : 
   45925                 :        1600 :   while (1)
   45926                 :             :     {
   45927                 :         572 :       tok = cp_lexer_peek_token (parser->lexer);
   45928                 :        1028 :       if (tok->type == CPP_CLOSE_BRACE)
   45929                 :             :         break;
   45930                 :         572 :       if (tok->type == CPP_EOF)
   45931                 :             :         break;
   45932                 :             : 
   45933                 :         572 :       if (cp_parser_omp_section_scan (parser, "section", false))
   45934                 :           6 :         tok = cp_lexer_peek_token (parser->lexer);
   45935                 :         572 :       if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SECTION)
   45936                 :             :         {
   45937                 :         572 :           cp_lexer_consume_token (parser->lexer);
   45938                 :         572 :           cp_parser_require_pragma_eol (parser, tok);
   45939                 :         572 :           error_suppress = false;
   45940                 :             :         }
   45941                 :           0 :       else if (!error_suppress)
   45942                 :             :         {
   45943                 :           0 :           cp_parser_error (parser, "expected %<#pragma omp section%> or %<}%>");
   45944                 :           0 :           error_suppress = true;
   45945                 :             :         }
   45946                 :             : 
   45947                 :         572 :       substmt = cp_parser_omp_structured_block_sequence (parser,
   45948                 :             :                                                          PRAGMA_OMP_SECTION);
   45949                 :         572 :       substmt = build1 (OMP_SECTION, void_type_node, substmt);
   45950                 :         572 :       add_stmt (substmt);
   45951                 :             :     }
   45952                 :         456 :   braces.require_close (parser);
   45953                 :             : 
   45954                 :         456 :   substmt = pop_stmt_list (stmt);
   45955                 :             : 
   45956                 :         456 :   stmt = make_node (OMP_SECTIONS);
   45957                 :         456 :   TREE_TYPE (stmt) = void_type_node;
   45958                 :         456 :   OMP_SECTIONS_BODY (stmt) = substmt;
   45959                 :             : 
   45960                 :         456 :   add_stmt (stmt);
   45961                 :         456 :   return stmt;
   45962                 :             : }
   45963                 :             : 
   45964                 :             : /* OpenMP 2.5:
   45965                 :             :    # pragma omp sections sections-clause[optseq] newline
   45966                 :             :      sections-scope  */
   45967                 :             : 
   45968                 :             : #define OMP_SECTIONS_CLAUSE_MASK                                \
   45969                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   45970                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   45971                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   45972                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   45973                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   45974                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   45975                 :             : 
   45976                 :             : static tree
   45977                 :         464 : cp_parser_omp_sections (cp_parser *parser, cp_token *pragma_tok,
   45978                 :             :                         char *p_name, omp_clause_mask mask, tree *cclauses)
   45979                 :             : {
   45980                 :         464 :   tree clauses, ret;
   45981                 :         464 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   45982                 :             : 
   45983                 :         464 :   strcat (p_name, " sections");
   45984                 :         464 :   mask |= OMP_SECTIONS_CLAUSE_MASK;
   45985                 :         464 :   if (cclauses)
   45986                 :         150 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
   45987                 :             : 
   45988                 :         464 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   45989                 :             :                                        cclauses == NULL);
   45990                 :         464 :   if (cclauses)
   45991                 :             :     {
   45992                 :         150 :       cp_omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
   45993                 :         150 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
   45994                 :             :     }
   45995                 :             : 
   45996                 :         464 :   ret = cp_parser_omp_sections_scope (parser);
   45997                 :         464 :   if (ret)
   45998                 :         456 :     OMP_SECTIONS_CLAUSES (ret) = clauses;
   45999                 :             : 
   46000                 :         464 :   return ret;
   46001                 :             : }
   46002                 :             : 
   46003                 :             : /* OpenMP 2.5:
   46004                 :             :    # pragma omp parallel parallel-clause[optseq] new-line
   46005                 :             :      structured-block
   46006                 :             :    # pragma omp parallel for parallel-for-clause[optseq] new-line
   46007                 :             :      structured-block
   46008                 :             :    # pragma omp parallel sections parallel-sections-clause[optseq] new-line
   46009                 :             :      structured-block
   46010                 :             : 
   46011                 :             :    OpenMP 4.0:
   46012                 :             :    # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
   46013                 :             :      structured-block */
   46014                 :             : 
   46015                 :             : #define OMP_PARALLEL_CLAUSE_MASK                                \
   46016                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   46017                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   46018                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   46019                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)        \
   46020                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   46021                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
   46022                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   46023                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)    \
   46024                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   46025                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
   46026                 :             : 
   46027                 :             : static tree
   46028                 :        9147 : cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
   46029                 :             :                         char *p_name, omp_clause_mask mask, tree *cclauses,
   46030                 :             :                         bool *if_p)
   46031                 :             : {
   46032                 :        9147 :   tree stmt, clauses, block;
   46033                 :        9147 :   unsigned int save;
   46034                 :        9147 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   46035                 :             : 
   46036                 :        9147 :   strcat (p_name, " parallel");
   46037                 :        9147 :   mask |= OMP_PARALLEL_CLAUSE_MASK;
   46038                 :             :   /* #pragma omp target parallel{, for, for simd} disallow copyin clause.  */
   46039                 :        9147 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
   46040                 :        1386 :       && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
   46041                 :         582 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
   46042                 :             : 
   46043                 :        9147 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
   46044                 :             :     {
   46045                 :        5790 :       tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46046                 :        5790 :       if (cclauses == NULL)
   46047                 :        1899 :         cclauses = cclauses_buf;
   46048                 :             : 
   46049                 :        5790 :       cp_lexer_consume_token (parser->lexer);
   46050                 :        5790 :       if (!flag_openmp)  /* flag_openmp_simd  */
   46051                 :          76 :         return cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses,
   46052                 :          76 :                                   if_p);
   46053                 :        5714 :       block = begin_omp_parallel ();
   46054                 :        5714 :       save = cp_parser_begin_omp_structured_block (parser);
   46055                 :        5714 :       tree ret = cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses,
   46056                 :             :                                     if_p);
   46057                 :        5714 :       cp_parser_end_omp_structured_block (parser, save);
   46058                 :        5714 :       stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   46059                 :             :                                   block);
   46060                 :        5714 :       if (ret == NULL_TREE)
   46061                 :             :         return ret;
   46062                 :        5651 :       OMP_PARALLEL_COMBINED (stmt) = 1;
   46063                 :        5651 :       return stmt;
   46064                 :             :     }
   46065                 :             :   /* When combined with distribute, parallel has to be followed by for.
   46066                 :             :      #pragma omp target parallel is allowed though.  */
   46067                 :        3357 :   else if (cclauses
   46068                 :        3357 :            && (mask & (OMP_CLAUSE_MASK_1
   46069                 :         130 :                        << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
   46070                 :             :     {
   46071                 :           0 :       error_at (loc, "expected %<for%> after %qs", p_name);
   46072                 :           0 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46073                 :           0 :       return NULL_TREE;
   46074                 :             :     }
   46075                 :        3357 :   else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   46076                 :             :     {
   46077                 :        1816 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   46078                 :        1816 :       const char *p = IDENTIFIER_POINTER (id);
   46079                 :        1816 :       if (cclauses == NULL && strcmp (p, "masked") == 0)
   46080                 :             :         {
   46081                 :         104 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46082                 :         104 :           cclauses = cclauses_buf;
   46083                 :             : 
   46084                 :         104 :           cp_lexer_consume_token (parser->lexer);
   46085                 :         104 :           if (!flag_openmp)  /* flag_openmp_simd  */
   46086                 :           0 :             return cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
   46087                 :           0 :                                          cclauses, if_p);
   46088                 :         104 :           block = begin_omp_parallel ();
   46089                 :         104 :           save = cp_parser_begin_omp_structured_block (parser);
   46090                 :         104 :           tree ret = cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
   46091                 :             :                                            cclauses, if_p);
   46092                 :         104 :           cp_parser_end_omp_structured_block (parser, save);
   46093                 :         104 :           stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   46094                 :             :                                       block);
   46095                 :         104 :           if (ret == NULL_TREE)
   46096                 :             :             return ret;
   46097                 :             :           /* masked does have just filter clause, but during gimplification
   46098                 :             :              isn't represented by a gimplification omp context, so for
   46099                 :             :              #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
   46100                 :             :              so that
   46101                 :             :              #pragma omp parallel masked
   46102                 :             :              #pragma omp taskloop simd lastprivate (x)
   46103                 :             :              isn't confused with
   46104                 :             :              #pragma omp parallel masked taskloop simd lastprivate (x)  */
   46105                 :         104 :           if (OMP_MASKED_COMBINED (ret))
   46106                 :          76 :             OMP_PARALLEL_COMBINED (stmt) = 1;
   46107                 :         104 :           return stmt;
   46108                 :             :         }
   46109                 :        1604 :       else if (cclauses == NULL && strcmp (p, "master") == 0)
   46110                 :             :         {
   46111                 :         240 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46112                 :         240 :           cclauses = cclauses_buf;
   46113                 :             : 
   46114                 :         240 :           cp_lexer_consume_token (parser->lexer);
   46115                 :         240 :           if (!flag_openmp)  /* flag_openmp_simd  */
   46116                 :          12 :             return cp_parser_omp_master (parser, pragma_tok, p_name, mask,
   46117                 :          12 :                                          cclauses, if_p);
   46118                 :         228 :           block = begin_omp_parallel ();
   46119                 :         228 :           save = cp_parser_begin_omp_structured_block (parser);
   46120                 :         228 :           tree ret = cp_parser_omp_master (parser, pragma_tok, p_name, mask,
   46121                 :             :                                            cclauses, if_p);
   46122                 :         228 :           cp_parser_end_omp_structured_block (parser, save);
   46123                 :         228 :           stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   46124                 :             :                                       block);
   46125                 :         228 :           if (ret == NULL_TREE)
   46126                 :             :             return ret;
   46127                 :             :           /* master doesn't have any clauses and during gimplification
   46128                 :             :              isn't represented by a gimplification omp context, so for
   46129                 :             :              #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
   46130                 :             :              so that
   46131                 :             :              #pragma omp parallel master
   46132                 :             :              #pragma omp taskloop simd lastprivate (x)
   46133                 :             :              isn't confused with
   46134                 :             :              #pragma omp parallel master taskloop simd lastprivate (x)  */
   46135                 :         224 :           if (OMP_MASTER_COMBINED (ret))
   46136                 :         159 :             OMP_PARALLEL_COMBINED (stmt) = 1;
   46137                 :         224 :           return stmt;
   46138                 :             :         }
   46139                 :        1472 :       else if (strcmp (p, "loop") == 0)
   46140                 :             :         {
   46141                 :         137 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46142                 :         137 :           if (cclauses == NULL)
   46143                 :          77 :             cclauses = cclauses_buf;
   46144                 :             : 
   46145                 :         137 :           cp_lexer_consume_token (parser->lexer);
   46146                 :         137 :           if (!flag_openmp)  /* flag_openmp_simd  */
   46147                 :           8 :             return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
   46148                 :           8 :                                        cclauses, if_p);
   46149                 :         129 :           block = begin_omp_parallel ();
   46150                 :         129 :           save = cp_parser_begin_omp_structured_block (parser);
   46151                 :         129 :           tree ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
   46152                 :             :                                          cclauses, if_p);
   46153                 :         129 :           cp_parser_end_omp_structured_block (parser, save);
   46154                 :         129 :           stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   46155                 :             :                                       block);
   46156                 :         129 :           if (ret == NULL_TREE)
   46157                 :             :             return ret;
   46158                 :         129 :           OMP_PARALLEL_COMBINED (stmt) = 1;
   46159                 :         129 :           return stmt;
   46160                 :             :         }
   46161                 :        1335 :       else if (!flag_openmp)  /* flag_openmp_simd  */
   46162                 :             :         {
   46163                 :           4 :           cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46164                 :           4 :           return NULL_TREE;
   46165                 :             :         }
   46166                 :        1331 :       else if (cclauses == NULL && strcmp (p, "sections") == 0)
   46167                 :             :         {
   46168                 :         150 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46169                 :         150 :           cclauses = cclauses_buf;
   46170                 :             : 
   46171                 :         150 :           cp_lexer_consume_token (parser->lexer);
   46172                 :         150 :           block = begin_omp_parallel ();
   46173                 :         150 :           save = cp_parser_begin_omp_structured_block (parser);
   46174                 :         150 :           cp_parser_omp_sections (parser, pragma_tok, p_name, mask, cclauses);
   46175                 :         150 :           cp_parser_end_omp_structured_block (parser, save);
   46176                 :         150 :           stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   46177                 :             :                                       block);
   46178                 :         150 :           OMP_PARALLEL_COMBINED (stmt) = 1;
   46179                 :         150 :           return stmt;
   46180                 :             :         }
   46181                 :             :     }
   46182                 :        1541 :   else if (!flag_openmp)  /* flag_openmp_simd  */
   46183                 :             :     {
   46184                 :           4 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46185                 :           4 :       return NULL_TREE;
   46186                 :             :     }
   46187                 :             : 
   46188                 :        2718 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   46189                 :             :                                        cclauses == NULL);
   46190                 :        2718 :   if (cclauses)
   46191                 :             :     {
   46192                 :          66 :       cp_omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
   46193                 :          66 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
   46194                 :             :     }
   46195                 :             : 
   46196                 :        2718 :   block = begin_omp_parallel ();
   46197                 :        2718 :   save = cp_parser_begin_omp_structured_block (parser);
   46198                 :        2718 :   parser->omp_attrs_forbidden_p = true;
   46199                 :        2718 :   cp_parser_statement (parser, NULL_TREE, false, if_p);
   46200                 :        2718 :   cp_parser_end_omp_structured_block (parser, save);
   46201                 :        2718 :   stmt = finish_omp_parallel (clauses, block);
   46202                 :        2718 :   return stmt;
   46203                 :             : }
   46204                 :             : 
   46205                 :             : /* OpenMP 2.5:
   46206                 :             :    # pragma omp single single-clause[optseq] new-line
   46207                 :             :      structured-block  */
   46208                 :             : 
   46209                 :             : #define OMP_SINGLE_CLAUSE_MASK                                  \
   46210                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   46211                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   46212                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE)    \
   46213                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   46214                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   46215                 :             : 
   46216                 :             : static tree
   46217                 :         434 : cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   46218                 :             : {
   46219                 :         434 :   tree stmt = make_node (OMP_SINGLE);
   46220                 :         434 :   TREE_TYPE (stmt) = void_type_node;
   46221                 :         434 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   46222                 :             : 
   46223                 :         868 :   OMP_SINGLE_CLAUSES (stmt)
   46224                 :         434 :     = cp_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
   46225                 :             :                                  "#pragma omp single", pragma_tok);
   46226                 :         434 :   OMP_SINGLE_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
   46227                 :             : 
   46228                 :         434 :   return add_stmt (stmt);
   46229                 :             : }
   46230                 :             : 
   46231                 :             : /* OpenMP 5.1:
   46232                 :             :    # pragma omp scope scope-clause[optseq] new-line
   46233                 :             :      structured-block  */
   46234                 :             : 
   46235                 :             : #define OMP_SCOPE_CLAUSE_MASK                                   \
   46236                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   46237                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   46238                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   46239                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   46240                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   46241                 :             : 
   46242                 :             : static tree
   46243                 :         133 : cp_parser_omp_scope (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   46244                 :             : {
   46245                 :         133 :   tree stmt = make_node (OMP_SCOPE);
   46246                 :         133 :   TREE_TYPE (stmt) = void_type_node;
   46247                 :         133 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   46248                 :             : 
   46249                 :         266 :   OMP_SCOPE_CLAUSES (stmt)
   46250                 :         133 :     = cp_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
   46251                 :             :                                  "#pragma omp scope", pragma_tok);
   46252                 :         133 :   OMP_SCOPE_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
   46253                 :             : 
   46254                 :         133 :   return add_stmt (stmt);
   46255                 :             : }
   46256                 :             : 
   46257                 :             : /* OpenMP 3.0:
   46258                 :             :    # pragma omp task task-clause[optseq] new-line
   46259                 :             :      structured-block  */
   46260                 :             : 
   46261                 :             : #define OMP_TASK_CLAUSE_MASK                                    \
   46262                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   46263                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
   46264                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)        \
   46265                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   46266                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   46267                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   46268                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)  \
   46269                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)      \
   46270                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   46271                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)       \
   46272                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   46273                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)   \
   46274                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
   46275                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
   46276                 :             : 
   46277                 :             : static tree
   46278                 :        2478 : cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   46279                 :             : {
   46280                 :        2478 :   tree clauses, block;
   46281                 :        2478 :   unsigned int save;
   46282                 :             : 
   46283                 :        2478 :   clauses = cp_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
   46284                 :             :                                        "#pragma omp task", pragma_tok);
   46285                 :        2478 :   block = begin_omp_task ();
   46286                 :        2478 :   save = cp_parser_begin_omp_structured_block (parser);
   46287                 :        2478 :   parser->omp_attrs_forbidden_p = true;
   46288                 :        2478 :   cp_parser_statement (parser, NULL_TREE, false, if_p);
   46289                 :        2478 :   cp_parser_end_omp_structured_block (parser, save);
   46290                 :        2478 :   return finish_omp_task (clauses, block);
   46291                 :             : }
   46292                 :             : 
   46293                 :             : /* OpenMP 3.0:
   46294                 :             :    # pragma omp taskwait new-line
   46295                 :             : 
   46296                 :             :    OpenMP 5.0:
   46297                 :             :    # pragma omp taskwait taskwait-clause[opt] new-line  */
   46298                 :             : 
   46299                 :             : #define OMP_TASKWAIT_CLAUSE_MASK                                \
   46300                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   46301                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   46302                 :             : 
   46303                 :             : static void
   46304                 :         161 : cp_parser_omp_taskwait (cp_parser *parser, cp_token *pragma_tok)
   46305                 :             : {
   46306                 :         161 :   tree clauses
   46307                 :         161 :     = cp_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
   46308                 :             :                                  "#pragma omp taskwait", pragma_tok);
   46309                 :             : 
   46310                 :         161 :   if (clauses)
   46311                 :             :     {
   46312                 :          42 :       tree stmt = make_node (OMP_TASK);
   46313                 :          42 :       TREE_TYPE (stmt) = void_node;
   46314                 :          42 :       OMP_TASK_CLAUSES (stmt) = clauses;
   46315                 :          42 :       OMP_TASK_BODY (stmt) = NULL_TREE;
   46316                 :          42 :       SET_EXPR_LOCATION (stmt, pragma_tok->location);
   46317                 :          42 :       add_stmt (stmt);
   46318                 :             :     }
   46319                 :             :   else
   46320                 :         119 :     finish_omp_taskwait ();
   46321                 :         161 : }
   46322                 :             : 
   46323                 :             : /* OpenMP 3.1:
   46324                 :             :    # pragma omp taskyield new-line  */
   46325                 :             : 
   46326                 :             : static void
   46327                 :          17 : cp_parser_omp_taskyield (cp_parser *parser, cp_token *pragma_tok)
   46328                 :             : {
   46329                 :           0 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   46330                 :           0 :   finish_omp_taskyield ();
   46331                 :           0 : }
   46332                 :             : 
   46333                 :             : /* OpenMP 4.0:
   46334                 :             :    # pragma omp taskgroup new-line
   46335                 :             :      structured-block
   46336                 :             : 
   46337                 :             :    OpenMP 5.0:
   46338                 :             :    # pragma omp taskgroup taskgroup-clause[optseq] new-line  */
   46339                 :             : 
   46340                 :             : #define OMP_TASKGROUP_CLAUSE_MASK                               \
   46341                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   46342                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
   46343                 :             : 
   46344                 :             : static tree
   46345                 :         345 : cp_parser_omp_taskgroup (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   46346                 :             : {
   46347                 :         345 :   tree clauses
   46348                 :         345 :     = cp_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
   46349                 :             :                                  "#pragma omp taskgroup", pragma_tok);
   46350                 :         345 :   return c_finish_omp_taskgroup (input_location,
   46351                 :             :                                  cp_parser_omp_structured_block (parser,
   46352                 :             :                                                                  if_p),
   46353                 :         345 :                                  clauses);
   46354                 :             : }
   46355                 :             : 
   46356                 :             : 
   46357                 :             : /* OpenMP 2.5:
   46358                 :             :    # pragma omp threadprivate (variable-list) */
   46359                 :             : 
   46360                 :             : static void
   46361                 :         277 : cp_parser_omp_threadprivate (cp_parser *parser, cp_token *pragma_tok)
   46362                 :             : {
   46363                 :         277 :   tree vars;
   46364                 :             : 
   46365                 :         277 :   vars = cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
   46366                 :         277 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   46367                 :             : 
   46368                 :         277 :   finish_omp_threadprivate (vars);
   46369                 :         277 : }
   46370                 :             : 
   46371                 :             : /* OpenMP 4.0:
   46372                 :             :    # pragma omp cancel cancel-clause[optseq] new-line  */
   46373                 :             : 
   46374                 :             : #define OMP_CANCEL_CLAUSE_MASK                                  \
   46375                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)       \
   46376                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)            \
   46377                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)       \
   46378                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)      \
   46379                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
   46380                 :             : 
   46381                 :             : static void
   46382                 :         779 : cp_parser_omp_cancel (cp_parser *parser, cp_token *pragma_tok)
   46383                 :             : {
   46384                 :         779 :   tree clauses = cp_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
   46385                 :             :                                             "#pragma omp cancel", pragma_tok);
   46386                 :         779 :   finish_omp_cancel (clauses);
   46387                 :         779 : }
   46388                 :             : 
   46389                 :             : /* OpenMP 4.0:
   46390                 :             :    # pragma omp cancellation point cancelpt-clause[optseq] new-line  */
   46391                 :             : 
   46392                 :             : #define OMP_CANCELLATION_POINT_CLAUSE_MASK                      \
   46393                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)       \
   46394                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)            \
   46395                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)       \
   46396                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
   46397                 :             : 
   46398                 :             : static bool
   46399                 :         700 : cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok,
   46400                 :             :                                   enum pragma_context context)
   46401                 :             : {
   46402                 :         700 :   tree clauses;
   46403                 :         700 :   bool point_seen = false;
   46404                 :             : 
   46405                 :         700 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   46406                 :             :     {
   46407                 :         700 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   46408                 :         700 :       const char *p = IDENTIFIER_POINTER (id);
   46409                 :             : 
   46410                 :         700 :       if (strcmp (p, "point") == 0)
   46411                 :             :         {
   46412                 :         692 :           cp_lexer_consume_token (parser->lexer);
   46413                 :         692 :           point_seen = true;
   46414                 :             :         }
   46415                 :             :     }
   46416                 :         692 :   if (!point_seen)
   46417                 :             :     {
   46418                 :           8 :       cp_parser_error (parser, "expected %<point%>");
   46419                 :           8 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46420                 :           8 :       return false;
   46421                 :             :     }
   46422                 :             : 
   46423                 :         692 :   if (context != pragma_compound)
   46424                 :             :     {
   46425                 :          40 :       if (context == pragma_stmt)
   46426                 :          36 :         error_at (pragma_tok->location,
   46427                 :             :                   "%<#pragma %s%> may only be used in compound statements",
   46428                 :             :                   "omp cancellation point");
   46429                 :             :       else
   46430                 :           4 :         cp_parser_error (parser, "expected declaration specifiers");
   46431                 :          40 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46432                 :          40 :       return true;
   46433                 :             :     }
   46434                 :             : 
   46435                 :         652 :   clauses = cp_parser_omp_all_clauses (parser,
   46436                 :         652 :                                        OMP_CANCELLATION_POINT_CLAUSE_MASK,
   46437                 :             :                                        "#pragma omp cancellation point",
   46438                 :             :                                        pragma_tok);
   46439                 :         652 :   finish_omp_cancellation_point (clauses);
   46440                 :         652 :   return true;
   46441                 :             : }
   46442                 :             : 
   46443                 :             : /* OpenMP 4.0:
   46444                 :             :    #pragma omp distribute distribute-clause[optseq] new-line
   46445                 :             :      for-loop  */
   46446                 :             : 
   46447                 :             : #define OMP_DISTRIBUTE_CLAUSE_MASK                              \
   46448                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   46449                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   46450                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   46451                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
   46452                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   46453                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   46454                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   46455                 :             : 
   46456                 :             : static tree
   46457                 :        4559 : cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok,
   46458                 :             :                           char *p_name, omp_clause_mask mask, tree *cclauses,
   46459                 :             :                           bool *if_p)
   46460                 :             : {
   46461                 :        4559 :   tree clauses, sb, ret;
   46462                 :        4559 :   unsigned int save;
   46463                 :        4559 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   46464                 :             : 
   46465                 :        4559 :   strcat (p_name, " distribute");
   46466                 :        4559 :   mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
   46467                 :             : 
   46468                 :        4559 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   46469                 :             :     {
   46470                 :        4386 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   46471                 :        4386 :       const char *p = IDENTIFIER_POINTER (id);
   46472                 :        4386 :       bool simd = false;
   46473                 :        4386 :       bool parallel = false;
   46474                 :             : 
   46475                 :        4386 :       if (strcmp (p, "simd") == 0)
   46476                 :             :         simd = true;
   46477                 :             :       else
   46478                 :        3815 :         parallel = strcmp (p, "parallel") == 0;
   46479                 :        4386 :       if (parallel || simd)
   46480                 :             :         {
   46481                 :        4010 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46482                 :        4010 :           if (cclauses == NULL)
   46483                 :        1492 :             cclauses = cclauses_buf;
   46484                 :        4010 :           cp_lexer_consume_token (parser->lexer);
   46485                 :        4010 :           if (!flag_openmp)  /* flag_openmp_simd  */
   46486                 :             :             {
   46487                 :          60 :               if (simd)
   46488                 :          24 :                 return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
   46489                 :          24 :                                            cclauses, if_p);
   46490                 :             :               else
   46491                 :          36 :                 return cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
   46492                 :          36 :                                                cclauses, if_p);
   46493                 :             :             }
   46494                 :        3950 :           sb = begin_omp_structured_block ();
   46495                 :        3950 :           save = cp_parser_begin_omp_structured_block (parser);
   46496                 :        3950 :           if (simd)
   46497                 :         547 :             ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
   46498                 :             :                                       cclauses, if_p);
   46499                 :             :           else
   46500                 :        3403 :             ret = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
   46501                 :             :                                           cclauses, if_p);
   46502                 :        3950 :           cp_parser_end_omp_structured_block (parser, save);
   46503                 :        3950 :           tree body = finish_omp_structured_block (sb);
   46504                 :        3950 :           if (ret == NULL)
   46505                 :             :             return ret;
   46506                 :        3946 :           ret = make_node (OMP_DISTRIBUTE);
   46507                 :        3946 :           TREE_TYPE (ret) = void_type_node;
   46508                 :        3946 :           OMP_FOR_BODY (ret) = body;
   46509                 :        3946 :           OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
   46510                 :        3946 :           SET_EXPR_LOCATION (ret, loc);
   46511                 :        3946 :           add_stmt (ret);
   46512                 :        3946 :           return ret;
   46513                 :             :         }
   46514                 :             :     }
   46515                 :         549 :   if (!flag_openmp)  /* flag_openmp_simd  */
   46516                 :             :     {
   46517                 :           8 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46518                 :           8 :       return NULL_TREE;
   46519                 :             :     }
   46520                 :             : 
   46521                 :         541 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   46522                 :             :                                        cclauses == NULL);
   46523                 :         541 :   if (cclauses)
   46524                 :             :     {
   46525                 :         292 :       cp_omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
   46526                 :         292 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
   46527                 :             :     }
   46528                 :             : 
   46529                 :         541 :   keep_next_level (true);
   46530                 :         541 :   sb = begin_omp_structured_block ();
   46531                 :         541 :   save = cp_parser_begin_omp_structured_block (parser);
   46532                 :             : 
   46533                 :         541 :   ret = cp_parser_omp_for_loop (parser, OMP_DISTRIBUTE, clauses, NULL, if_p);
   46534                 :             : 
   46535                 :         541 :   cp_parser_end_omp_structured_block (parser, save);
   46536                 :         541 :   add_stmt (finish_omp_structured_block (sb));
   46537                 :             : 
   46538                 :         541 :   return ret;
   46539                 :             : }
   46540                 :             : 
   46541                 :             : /* OpenMP 4.0:
   46542                 :             :    # pragma omp teams teams-clause[optseq] new-line
   46543                 :             :      structured-block  */
   46544                 :             : 
   46545                 :             : #define OMP_TEAMS_CLAUSE_MASK                                   \
   46546                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   46547                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   46548                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   46549                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   46550                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)      \
   46551                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)   \
   46552                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   46553                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
   46554                 :             : 
   46555                 :             : static tree
   46556                 :        5059 : cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
   46557                 :             :                      char *p_name, omp_clause_mask mask, tree *cclauses,
   46558                 :             :                      bool *if_p)
   46559                 :             : {
   46560                 :        5059 :   tree clauses, sb, ret;
   46561                 :        5059 :   unsigned int save;
   46562                 :        5059 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   46563                 :             : 
   46564                 :        5059 :   strcat (p_name, " teams");
   46565                 :        5059 :   mask |= OMP_TEAMS_CLAUSE_MASK;
   46566                 :             : 
   46567                 :        5059 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   46568                 :             :     {
   46569                 :        3472 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   46570                 :        3472 :       const char *p = IDENTIFIER_POINTER (id);
   46571                 :        3472 :       if (strcmp (p, "distribute") == 0)
   46572                 :             :         {
   46573                 :        2818 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46574                 :        2818 :           if (cclauses == NULL)
   46575                 :        1740 :             cclauses = cclauses_buf;
   46576                 :             : 
   46577                 :        2818 :           cp_lexer_consume_token (parser->lexer);
   46578                 :        2818 :           if (!flag_openmp)  /* flag_openmp_simd  */
   46579                 :          48 :             return cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
   46580                 :          48 :                                              cclauses, if_p);
   46581                 :        2770 :           keep_next_level (true);
   46582                 :        2770 :           sb = begin_omp_structured_block ();
   46583                 :        2770 :           save = cp_parser_begin_omp_structured_block (parser);
   46584                 :        2770 :           ret = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
   46585                 :             :                                           cclauses, if_p);
   46586                 :        2770 :           cp_parser_end_omp_structured_block (parser, save);
   46587                 :        2770 :           tree body = finish_omp_structured_block (sb);
   46588                 :        2770 :           if (ret == NULL)
   46589                 :             :             return ret;
   46590                 :        2770 :           clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   46591                 :        2770 :           ret = make_node (OMP_TEAMS);
   46592                 :        2770 :           TREE_TYPE (ret) = void_type_node;
   46593                 :        2770 :           OMP_TEAMS_CLAUSES (ret) = clauses;
   46594                 :        2770 :           OMP_TEAMS_BODY (ret) = body;
   46595                 :        2770 :           OMP_TEAMS_COMBINED (ret) = 1;
   46596                 :        2770 :           SET_EXPR_LOCATION (ret, loc);
   46597                 :        2770 :           return add_stmt (ret);
   46598                 :             :         }
   46599                 :         654 :       else if (strcmp (p, "loop") == 0)
   46600                 :             :         {
   46601                 :         122 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   46602                 :         122 :           if (cclauses == NULL)
   46603                 :          64 :             cclauses = cclauses_buf;
   46604                 :             : 
   46605                 :         122 :           cp_lexer_consume_token (parser->lexer);
   46606                 :         122 :           if (!flag_openmp)  /* flag_openmp_simd  */
   46607                 :           8 :             return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
   46608                 :           8 :                                        cclauses, if_p);
   46609                 :         114 :           keep_next_level (true);
   46610                 :         114 :           sb = begin_omp_structured_block ();
   46611                 :         114 :           save = cp_parser_begin_omp_structured_block (parser);
   46612                 :         114 :           ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
   46613                 :             :                                     cclauses, if_p);
   46614                 :         114 :           cp_parser_end_omp_structured_block (parser, save);
   46615                 :         114 :           tree body = finish_omp_structured_block (sb);
   46616                 :         114 :           if (ret == NULL)
   46617                 :             :             return ret;
   46618                 :         114 :           clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   46619                 :         114 :           ret = make_node (OMP_TEAMS);
   46620                 :         114 :           TREE_TYPE (ret) = void_type_node;
   46621                 :         114 :           OMP_TEAMS_CLAUSES (ret) = clauses;
   46622                 :         114 :           OMP_TEAMS_BODY (ret) = body;
   46623                 :         114 :           OMP_TEAMS_COMBINED (ret) = 1;
   46624                 :         114 :           SET_EXPR_LOCATION (ret, loc);
   46625                 :         114 :           return add_stmt (ret);
   46626                 :             :         }
   46627                 :             :     }
   46628                 :        2119 :   if (!flag_openmp)  /* flag_openmp_simd  */
   46629                 :             :     {
   46630                 :           8 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46631                 :           8 :       return NULL_TREE;
   46632                 :             :     }
   46633                 :             : 
   46634                 :        2111 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   46635                 :             :                                        cclauses == NULL);
   46636                 :        2111 :   if (cclauses)
   46637                 :             :     {
   46638                 :        1125 :       cp_omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
   46639                 :        1125 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   46640                 :             :     }
   46641                 :             : 
   46642                 :        2111 :   tree stmt = make_node (OMP_TEAMS);
   46643                 :        2111 :   TREE_TYPE (stmt) = void_type_node;
   46644                 :        2111 :   OMP_TEAMS_CLAUSES (stmt) = clauses;
   46645                 :        2111 :   keep_next_level (true);
   46646                 :        2111 :   OMP_TEAMS_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
   46647                 :        2111 :   SET_EXPR_LOCATION (stmt, loc);
   46648                 :             : 
   46649                 :        2111 :   return add_stmt (stmt);
   46650                 :             : }
   46651                 :             : 
   46652                 :             : /* OpenMP 4.0:
   46653                 :             :    # pragma omp target data target-data-clause[optseq] new-line
   46654                 :             :      structured-block  */
   46655                 :             : 
   46656                 :             : #define OMP_TARGET_DATA_CLAUSE_MASK                             \
   46657                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   46658                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   46659                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   46660                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
   46661                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
   46662                 :             : 
   46663                 :             : static tree
   46664                 :         390 : cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   46665                 :             : {
   46666                 :         390 :   if (flag_openmp)
   46667                 :         390 :     omp_requires_mask
   46668                 :         390 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   46669                 :             : 
   46670                 :         390 :   tree clauses
   46671                 :         390 :     = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
   46672                 :         390 :                                  "#pragma omp target data", pragma_tok);
   46673                 :         390 :   c_omp_adjust_map_clauses (clauses, false);
   46674                 :         390 :   int map_seen = 0;
   46675                 :        1064 :   for (tree *pc = &clauses; *pc;)
   46676                 :             :     {
   46677                 :         674 :       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
   46678                 :         499 :         switch (OMP_CLAUSE_MAP_KIND (*pc))
   46679                 :             :           {
   46680                 :             :           case GOMP_MAP_TO:
   46681                 :             :           case GOMP_MAP_ALWAYS_TO:
   46682                 :             :           case GOMP_MAP_PRESENT_TO:
   46683                 :             :           case GOMP_MAP_ALWAYS_PRESENT_TO:
   46684                 :             :           case GOMP_MAP_FROM:
   46685                 :             :           case GOMP_MAP_ALWAYS_FROM:
   46686                 :             :           case GOMP_MAP_PRESENT_FROM:
   46687                 :             :           case GOMP_MAP_ALWAYS_PRESENT_FROM:
   46688                 :             :           case GOMP_MAP_TOFROM:
   46689                 :             :           case GOMP_MAP_ALWAYS_TOFROM:
   46690                 :             :           case GOMP_MAP_PRESENT_TOFROM:
   46691                 :             :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   46692                 :             :           case GOMP_MAP_ALLOC:
   46693                 :             :           case GOMP_MAP_PRESENT_ALLOC:
   46694                 :         674 :             map_seen = 3;
   46695                 :             :             break;
   46696                 :             :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   46697                 :             :           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   46698                 :             :           case GOMP_MAP_ALWAYS_POINTER:
   46699                 :             :           case GOMP_MAP_ATTACH_DETACH:
   46700                 :             :           case GOMP_MAP_ATTACH:
   46701                 :             :             break;
   46702                 :           0 :           default:
   46703                 :           0 :             map_seen |= 1;
   46704                 :           0 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   46705                 :             :                       "%<#pragma omp target data%> with map-type other "
   46706                 :             :                       "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
   46707                 :             :                       "on %<map%> clause");
   46708                 :           0 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   46709                 :           0 :             continue;
   46710                 :             :           }
   46711                 :         175 :       else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
   46712                 :         175 :                || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
   46713                 :             :         map_seen = 3;
   46714                 :         674 :       pc = &OMP_CLAUSE_CHAIN (*pc);
   46715                 :             :     }
   46716                 :             : 
   46717                 :         390 :   if (map_seen != 3)
   46718                 :             :     {
   46719                 :           8 :       if (map_seen == 0)
   46720                 :           8 :         error_at (pragma_tok->location,
   46721                 :             :                   "%<#pragma omp target data%> must contain at least "
   46722                 :             :                   "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
   46723                 :             :                   "clause");
   46724                 :           8 :       return NULL_TREE;
   46725                 :             :     }
   46726                 :             : 
   46727                 :         382 :   tree stmt = make_node (OMP_TARGET_DATA);
   46728                 :         382 :   TREE_TYPE (stmt) = void_type_node;
   46729                 :         382 :   OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
   46730                 :             : 
   46731                 :         382 :   keep_next_level (true);
   46732                 :         382 :   OMP_TARGET_DATA_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
   46733                 :             : 
   46734                 :         382 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   46735                 :         382 :   return add_stmt (stmt);
   46736                 :             : }
   46737                 :             : 
   46738                 :             : /* OpenMP 4.5:
   46739                 :             :    # pragma omp target enter data target-enter-data-clause[optseq] new-line
   46740                 :             :      structured-block  */
   46741                 :             : 
   46742                 :             : #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK                       \
   46743                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   46744                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   46745                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   46746                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   46747                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   46748                 :             : 
   46749                 :             : static bool
   46750                 :         408 : cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
   46751                 :             :                                  enum pragma_context context)
   46752                 :             : {
   46753                 :         408 :   bool data_seen = false;
   46754                 :         408 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   46755                 :             :     {
   46756                 :         408 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   46757                 :         408 :       const char *p = IDENTIFIER_POINTER (id);
   46758                 :             : 
   46759                 :         408 :       if (strcmp (p, "data") == 0)
   46760                 :             :         {
   46761                 :         408 :           cp_lexer_consume_token (parser->lexer);
   46762                 :         408 :           data_seen = true;
   46763                 :             :         }
   46764                 :             :     }
   46765                 :         408 :   if (!data_seen)
   46766                 :             :     {
   46767                 :           0 :       cp_parser_error (parser, "expected %<data%>");
   46768                 :           0 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46769                 :           0 :       return false;
   46770                 :             :     }
   46771                 :             : 
   46772                 :         408 :   if (context == pragma_stmt)
   46773                 :             :     {
   46774                 :          32 :       error_at (pragma_tok->location,
   46775                 :             :                 "%<#pragma %s%> may only be used in compound statements",
   46776                 :             :                 "omp target enter data");
   46777                 :          32 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46778                 :          32 :       return true;
   46779                 :             :     }
   46780                 :             : 
   46781                 :         376 :   if (flag_openmp)
   46782                 :         376 :     omp_requires_mask
   46783                 :         376 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   46784                 :             : 
   46785                 :         376 :   tree clauses
   46786                 :         376 :     = cp_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
   46787                 :         376 :                                  "#pragma omp target enter data", pragma_tok);
   46788                 :         376 :   c_omp_adjust_map_clauses (clauses, false);
   46789                 :         376 :   int map_seen = 0;
   46790                 :        1157 :   for (tree *pc = &clauses; *pc;)
   46791                 :             :     {
   46792                 :         781 :       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
   46793                 :         700 :         switch (OMP_CLAUSE_MAP_KIND (*pc))
   46794                 :             :           {
   46795                 :             :           case GOMP_MAP_TO:
   46796                 :             :           case GOMP_MAP_ALWAYS_TO:
   46797                 :             :           case GOMP_MAP_PRESENT_TO:
   46798                 :             :           case GOMP_MAP_ALWAYS_PRESENT_TO:
   46799                 :             :           case GOMP_MAP_ALLOC:
   46800                 :             :           case GOMP_MAP_PRESENT_ALLOC:
   46801                 :         574 :             map_seen = 3;
   46802                 :             :             break;
   46803                 :          28 :           case GOMP_MAP_TOFROM:
   46804                 :          28 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
   46805                 :          28 :             map_seen = 3;
   46806                 :          28 :             break;
   46807                 :          12 :           case GOMP_MAP_ALWAYS_TOFROM:
   46808                 :          12 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
   46809                 :          12 :             map_seen = 3;
   46810                 :          12 :             break;
   46811                 :           8 :           case GOMP_MAP_PRESENT_TOFROM:
   46812                 :           8 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
   46813                 :           8 :             map_seen = 3;
   46814                 :           8 :             break;
   46815                 :           8 :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   46816                 :           8 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
   46817                 :           8 :             map_seen = 3;
   46818                 :           8 :             break;
   46819                 :             :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   46820                 :             :           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   46821                 :             :           case GOMP_MAP_ALWAYS_POINTER:
   46822                 :             :           case GOMP_MAP_ATTACH_DETACH:
   46823                 :             :           case GOMP_MAP_ATTACH:
   46824                 :             :             break;
   46825                 :           8 :           default:
   46826                 :           8 :             map_seen |= 1;
   46827                 :           8 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   46828                 :             :                       "%<#pragma omp target enter data%> with map-type other "
   46829                 :             :                       "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
   46830                 :           8 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   46831                 :           8 :             continue;
   46832                 :             :           }
   46833                 :         773 :       pc = &OMP_CLAUSE_CHAIN (*pc);
   46834                 :             :     }
   46835                 :             : 
   46836                 :         376 :   if (map_seen != 3)
   46837                 :             :     {
   46838                 :           8 :       if (map_seen == 0)
   46839                 :           0 :         error_at (pragma_tok->location,
   46840                 :             :                   "%<#pragma omp target enter data%> must contain at least "
   46841                 :             :                   "one %<map%> clause");
   46842                 :           8 :       return true;
   46843                 :             :     }
   46844                 :             : 
   46845                 :         368 :   tree stmt = make_node (OMP_TARGET_ENTER_DATA);
   46846                 :         368 :   TREE_TYPE (stmt) = void_type_node;
   46847                 :         368 :   OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
   46848                 :         368 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   46849                 :         368 :   add_stmt (stmt);
   46850                 :         368 :   return true;
   46851                 :             : }
   46852                 :             : 
   46853                 :             : /* OpenMP 4.5:
   46854                 :             :    # pragma omp target exit data target-enter-data-clause[optseq] new-line
   46855                 :             :      structured-block  */
   46856                 :             : 
   46857                 :             : #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK                        \
   46858                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   46859                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   46860                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   46861                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   46862                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   46863                 :             : 
   46864                 :             : static bool
   46865                 :         353 : cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
   46866                 :             :                                 enum pragma_context context)
   46867                 :             : {
   46868                 :         353 :   bool data_seen = false;
   46869                 :         353 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   46870                 :             :     {
   46871                 :         353 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   46872                 :         353 :       const char *p = IDENTIFIER_POINTER (id);
   46873                 :             : 
   46874                 :         353 :       if (strcmp (p, "data") == 0)
   46875                 :             :         {
   46876                 :         353 :           cp_lexer_consume_token (parser->lexer);
   46877                 :         353 :           data_seen = true;
   46878                 :             :         }
   46879                 :             :     }
   46880                 :         353 :   if (!data_seen)
   46881                 :             :     {
   46882                 :           0 :       cp_parser_error (parser, "expected %<data%>");
   46883                 :           0 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46884                 :           0 :       return false;
   46885                 :             :     }
   46886                 :             : 
   46887                 :         353 :   if (context == pragma_stmt)
   46888                 :             :     {
   46889                 :          32 :       error_at (pragma_tok->location,
   46890                 :             :                 "%<#pragma %s%> may only be used in compound statements",
   46891                 :             :                 "omp target exit data");
   46892                 :          32 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46893                 :          32 :       return true;
   46894                 :             :     }
   46895                 :             : 
   46896                 :         321 :   if (flag_openmp)
   46897                 :         321 :     omp_requires_mask
   46898                 :         321 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   46899                 :             : 
   46900                 :         321 :   tree clauses
   46901                 :         321 :     = cp_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
   46902                 :             :                                  "#pragma omp target exit data", pragma_tok,
   46903                 :             :                                  false);
   46904                 :         321 :   clauses = finish_omp_clauses (clauses, C_ORT_OMP_EXIT_DATA);
   46905                 :         321 :   c_omp_adjust_map_clauses (clauses, false);
   46906                 :         321 :   int map_seen = 0;
   46907                 :        1014 :   for (tree *pc = &clauses; *pc;)
   46908                 :             :     {
   46909                 :         693 :       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
   46910                 :         613 :         switch (OMP_CLAUSE_MAP_KIND (*pc))
   46911                 :             :           {
   46912                 :             :           case GOMP_MAP_FROM:
   46913                 :             :           case GOMP_MAP_ALWAYS_FROM:
   46914                 :             :           case GOMP_MAP_PRESENT_FROM:
   46915                 :             :           case GOMP_MAP_ALWAYS_PRESENT_FROM:
   46916                 :             :           case GOMP_MAP_RELEASE:
   46917                 :             :           case GOMP_MAP_DELETE:
   46918                 :         509 :             map_seen = 3;
   46919                 :             :             break;
   46920                 :          20 :           case GOMP_MAP_TOFROM:
   46921                 :          20 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
   46922                 :          20 :             map_seen = 3;
   46923                 :          20 :             break;
   46924                 :           4 :           case GOMP_MAP_ALWAYS_TOFROM:
   46925                 :           4 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
   46926                 :           4 :             map_seen = 3;
   46927                 :           4 :             break;
   46928                 :           0 :           case GOMP_MAP_PRESENT_TOFROM:
   46929                 :           0 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
   46930                 :           0 :             map_seen = 3;
   46931                 :           0 :             break;
   46932                 :           0 :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   46933                 :           0 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
   46934                 :           0 :             map_seen = 3;
   46935                 :           0 :             break;
   46936                 :             :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   46937                 :             :           case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
   46938                 :             :           case GOMP_MAP_ALWAYS_POINTER:
   46939                 :             :           case GOMP_MAP_ATTACH_DETACH:
   46940                 :             :           case GOMP_MAP_DETACH:
   46941                 :             :             break;
   46942                 :           8 :           default:
   46943                 :           8 :             map_seen |= 1;
   46944                 :           8 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   46945                 :             :                       "%<#pragma omp target exit data%> with map-type other "
   46946                 :             :                       "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
   46947                 :             :                       "on %<map%> clause");
   46948                 :           8 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   46949                 :           8 :             continue;
   46950                 :             :           }
   46951                 :         685 :       pc = &OMP_CLAUSE_CHAIN (*pc);
   46952                 :             :     }
   46953                 :             : 
   46954                 :         321 :   if (map_seen != 3)
   46955                 :             :     {
   46956                 :           8 :       if (map_seen == 0)
   46957                 :           0 :         error_at (pragma_tok->location,
   46958                 :             :                   "%<#pragma omp target exit data%> must contain at least "
   46959                 :             :                   "one %<map%> clause");
   46960                 :           8 :       return true;
   46961                 :             :     }
   46962                 :             : 
   46963                 :         313 :   tree stmt = make_node (OMP_TARGET_EXIT_DATA);
   46964                 :         313 :   TREE_TYPE (stmt) = void_type_node;
   46965                 :         313 :   OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
   46966                 :         313 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   46967                 :         313 :   add_stmt (stmt);
   46968                 :         313 :   return true;
   46969                 :             : }
   46970                 :             : 
   46971                 :             : /* OpenMP 4.0:
   46972                 :             :    # pragma omp target update target-update-clause[optseq] new-line */
   46973                 :             : 
   46974                 :             : #define OMP_TARGET_UPDATE_CLAUSE_MASK                           \
   46975                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM)           \
   46976                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)             \
   46977                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   46978                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   46979                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   46980                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   46981                 :             : 
   46982                 :             : static bool
   46983                 :        2982 : cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
   46984                 :             :                              enum pragma_context context)
   46985                 :             : {
   46986                 :        2982 :   if (context == pragma_stmt)
   46987                 :             :     {
   46988                 :          32 :       error_at (pragma_tok->location,
   46989                 :             :                 "%<#pragma %s%> may only be used in compound statements",
   46990                 :             :                 "omp target update");
   46991                 :          32 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   46992                 :          32 :       return true;
   46993                 :             :     }
   46994                 :             : 
   46995                 :        2950 :   tree clauses
   46996                 :        2950 :     = cp_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
   46997                 :             :                                  "#pragma omp target update", pragma_tok);
   46998                 :        2950 :   if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
   46999                 :        2950 :       && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
   47000                 :             :     {
   47001                 :           0 :       error_at (pragma_tok->location,
   47002                 :             :                 "%<#pragma omp target update%> must contain at least one "
   47003                 :             :                 "%<from%> or %<to%> clauses");
   47004                 :           0 :       return true;
   47005                 :             :     }
   47006                 :             : 
   47007                 :        2950 :   if (flag_openmp)
   47008                 :        2950 :     omp_requires_mask
   47009                 :        2950 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   47010                 :             : 
   47011                 :        2950 :   tree stmt = make_node (OMP_TARGET_UPDATE);
   47012                 :        2950 :   TREE_TYPE (stmt) = void_type_node;
   47013                 :        2950 :   OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
   47014                 :        2950 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   47015                 :        2950 :   add_stmt (stmt);
   47016                 :        2950 :   return true;
   47017                 :             : }
   47018                 :             : 
   47019                 :             : /* OpenMP 4.0:
   47020                 :             :    # pragma omp target target-clause[optseq] new-line
   47021                 :             :      structured-block  */
   47022                 :             : 
   47023                 :             : #define OMP_TARGET_CLAUSE_MASK                                  \
   47024                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   47025                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   47026                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   47027                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   47028                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
   47029                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   47030                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   47031                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP)     \
   47032                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   47033                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)   \
   47034                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)   \
   47035                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
   47036                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
   47037                 :             : 
   47038                 :             : static bool
   47039                 :       11136 : cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
   47040                 :             :                       enum pragma_context context, bool *if_p)
   47041                 :             : {
   47042                 :       11136 :   if (flag_openmp)
   47043                 :       11080 :     omp_requires_mask
   47044                 :       11080 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   47045                 :             : 
   47046                 :       11136 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   47047                 :             :     {
   47048                 :        9830 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   47049                 :        9830 :       const char *p = IDENTIFIER_POINTER (id);
   47050                 :        9830 :       enum tree_code ccode = ERROR_MARK;
   47051                 :             : 
   47052                 :        9830 :       if (strcmp (p, "teams") == 0)
   47053                 :             :         ccode = OMP_TEAMS;
   47054                 :        7565 :       else if (strcmp (p, "parallel") == 0)
   47055                 :             :         ccode = OMP_PARALLEL;
   47056                 :        6983 :       else if (strcmp (p, "simd") == 0)
   47057                 :             :         ccode = OMP_SIMD;
   47058                 :        6839 :       if (ccode != ERROR_MARK)
   47059                 :             :         {
   47060                 :        2991 :           tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
   47061                 :        2991 :           char p_name[sizeof ("#pragma omp target teams distribute "
   47062                 :             :                               "parallel for simd")];
   47063                 :             : 
   47064                 :        2991 :           cp_lexer_consume_token (parser->lexer);
   47065                 :        2991 :           strcpy (p_name, "#pragma omp target");
   47066                 :        2991 :           if (!flag_openmp)  /* flag_openmp_simd  */
   47067                 :             :             {
   47068                 :          52 :               tree stmt;
   47069                 :          52 :               switch (ccode)
   47070                 :             :                 {
   47071                 :          32 :                 case OMP_TEAMS:
   47072                 :          32 :                   stmt = cp_parser_omp_teams (parser, pragma_tok, p_name,
   47073                 :          32 :                                               OMP_TARGET_CLAUSE_MASK,
   47074                 :             :                                               cclauses, if_p);
   47075                 :          32 :                   break;
   47076                 :          16 :                 case OMP_PARALLEL:
   47077                 :          16 :                   stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name,
   47078                 :          16 :                                                  OMP_TARGET_CLAUSE_MASK,
   47079                 :             :                                                  cclauses, if_p);
   47080                 :          16 :                   break;
   47081                 :           4 :                 case OMP_SIMD:
   47082                 :           4 :                   stmt = cp_parser_omp_simd (parser, pragma_tok, p_name,
   47083                 :           4 :                                              OMP_TARGET_CLAUSE_MASK,
   47084                 :             :                                              cclauses, if_p);
   47085                 :           4 :                   break;
   47086                 :           0 :                 default:
   47087                 :           0 :                   gcc_unreachable ();
   47088                 :             :                 }
   47089                 :          52 :               return stmt != NULL_TREE;
   47090                 :             :             }
   47091                 :        2939 :           keep_next_level (true);
   47092                 :        2939 :           tree sb = begin_omp_structured_block (), ret;
   47093                 :        2939 :           unsigned save = cp_parser_begin_omp_structured_block (parser);
   47094                 :        2939 :           switch (ccode)
   47095                 :             :             {
   47096                 :        2233 :             case OMP_TEAMS:
   47097                 :        2233 :               ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
   47098                 :        2233 :                                          OMP_TARGET_CLAUSE_MASK, cclauses,
   47099                 :             :                                          if_p);
   47100                 :        2233 :               break;
   47101                 :         566 :             case OMP_PARALLEL:
   47102                 :         566 :               ret = cp_parser_omp_parallel (parser, pragma_tok, p_name,
   47103                 :         566 :                                             OMP_TARGET_CLAUSE_MASK, cclauses,
   47104                 :             :                                             if_p);
   47105                 :         566 :               break;
   47106                 :         140 :             case OMP_SIMD:
   47107                 :         140 :               ret = cp_parser_omp_simd (parser, pragma_tok, p_name,
   47108                 :         140 :                                         OMP_TARGET_CLAUSE_MASK, cclauses,
   47109                 :             :                                         if_p);
   47110                 :         140 :               break;
   47111                 :           0 :             default:
   47112                 :           0 :               gcc_unreachable ();
   47113                 :             :             }
   47114                 :        2939 :           cp_parser_end_omp_structured_block (parser, save);
   47115                 :        2939 :           tree body = finish_omp_structured_block (sb);
   47116                 :        2939 :           if (ret == NULL_TREE)
   47117                 :             :             return false;
   47118                 :        2939 :           if (ccode == OMP_TEAMS && !processing_template_decl)
   47119                 :             :             /* For combined target teams, ensure the num_teams and
   47120                 :             :                thread_limit clause expressions are evaluated on the host,
   47121                 :             :                before entering the target construct.  */
   47122                 :        3622 :             for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   47123                 :        3622 :                  c; c = OMP_CLAUSE_CHAIN (c))
   47124                 :        1495 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
   47125                 :        1495 :                   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
   47126                 :         658 :                 for (int i = 0;
   47127                 :        1084 :                      i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
   47128                 :         658 :                   if (OMP_CLAUSE_OPERAND (c, i)
   47129                 :         658 :                       && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
   47130                 :             :                     {
   47131                 :         429 :                       tree expr = OMP_CLAUSE_OPERAND (c, i);
   47132                 :         429 :                       expr = force_target_expr (TREE_TYPE (expr), expr,
   47133                 :             :                                                 tf_none);
   47134                 :         429 :                       if (expr == error_mark_node)
   47135                 :           0 :                         continue;
   47136                 :         429 :                       tree tmp = TARGET_EXPR_SLOT (expr);
   47137                 :         429 :                       add_stmt (expr);
   47138                 :         429 :                       OMP_CLAUSE_OPERAND (c, i) = expr;
   47139                 :         429 :                       tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   47140                 :             :                                                   OMP_CLAUSE_FIRSTPRIVATE);
   47141                 :         429 :                       OMP_CLAUSE_DECL (tc) = tmp;
   47142                 :         429 :                       OMP_CLAUSE_CHAIN (tc)
   47143                 :         429 :                         = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
   47144                 :         429 :                       cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
   47145                 :             :                     }
   47146                 :        2939 :           c_omp_adjust_map_clauses (cclauses[C_OMP_CLAUSE_SPLIT_TARGET], true);
   47147                 :        2939 :           finish_omp_target (pragma_tok->location,
   47148                 :             :                              cclauses[C_OMP_CLAUSE_SPLIT_TARGET], body, true);
   47149                 :        2939 :           return true;
   47150                 :             :         }
   47151                 :        6839 :       else if (!flag_openmp)  /* flag_openmp_simd  */
   47152                 :             :         {
   47153                 :           0 :           cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   47154                 :           0 :           return false;
   47155                 :             :         }
   47156                 :        6839 :       else if (strcmp (p, "data") == 0)
   47157                 :             :         {
   47158                 :         390 :           cp_lexer_consume_token (parser->lexer);
   47159                 :         390 :           cp_parser_omp_target_data (parser, pragma_tok, if_p);
   47160                 :         390 :           return true;
   47161                 :             :         }
   47162                 :        6449 :       else if (strcmp (p, "enter") == 0)
   47163                 :             :         {
   47164                 :         408 :           cp_lexer_consume_token (parser->lexer);
   47165                 :         408 :           return cp_parser_omp_target_enter_data (parser, pragma_tok, context);
   47166                 :             :         }
   47167                 :        6041 :       else if (strcmp (p, "exit") == 0)
   47168                 :             :         {
   47169                 :         353 :           cp_lexer_consume_token (parser->lexer);
   47170                 :         353 :           return cp_parser_omp_target_exit_data (parser, pragma_tok, context);
   47171                 :             :         }
   47172                 :        5688 :       else if (strcmp (p, "update") == 0)
   47173                 :             :         {
   47174                 :        2982 :           cp_lexer_consume_token (parser->lexer);
   47175                 :        2982 :           return cp_parser_omp_target_update (parser, pragma_tok, context);
   47176                 :             :         }
   47177                 :             :     }
   47178                 :        4012 :   if (!flag_openmp)  /* flag_openmp_simd  */
   47179                 :             :     {
   47180                 :           4 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   47181                 :           4 :       return false;
   47182                 :             :     }
   47183                 :             : 
   47184                 :        4008 :   tree clauses = cp_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
   47185                 :             :                                             "#pragma omp target", pragma_tok,
   47186                 :             :                                             false);
   47187                 :        8838 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   47188                 :        4830 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
   47189                 :             :       {
   47190                 :         116 :         tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
   47191                 :         116 :         OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
   47192                 :         116 :         OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
   47193                 :         116 :         OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
   47194                 :         116 :         OMP_CLAUSE_CHAIN (c) = nc;
   47195                 :             :       }
   47196                 :        4008 :   clauses = finish_omp_clauses (clauses, C_ORT_OMP_TARGET);
   47197                 :             : 
   47198                 :        4008 :   c_omp_adjust_map_clauses (clauses, true);
   47199                 :        4008 :   keep_next_level (true);
   47200                 :        4008 :   tree body = cp_parser_omp_structured_block (parser, if_p);
   47201                 :             : 
   47202                 :        4008 :   finish_omp_target (pragma_tok->location, clauses, body, false);
   47203                 :        4008 :   return true;
   47204                 :             : }
   47205                 :             : 
   47206                 :             : /* OpenACC 2.0:
   47207                 :             :    # pragma acc cache (variable-list) new-line
   47208                 :             : 
   47209                 :             :    OpenACC 2.7:
   47210                 :             :    # pragma acc cache (readonly: variable-list) new-line
   47211                 :             : */
   47212                 :             : 
   47213                 :             : static tree
   47214                 :         888 : cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
   47215                 :             : {
   47216                 :             :   /* Don't create location wrapper nodes within 'OMP_CLAUSE__CACHE_'
   47217                 :             :      clauses.  */
   47218                 :         888 :   auto_suppress_location_wrappers sentinel;
   47219                 :             : 
   47220                 :         888 :   tree stmt, clauses = NULL_TREE;
   47221                 :         888 :   bool readonly = false;
   47222                 :             : 
   47223                 :         888 :   if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   47224                 :             :     {
   47225                 :         872 :       cp_token *token = cp_lexer_peek_token (parser->lexer);
   47226                 :         872 :       if (token->type == CPP_NAME
   47227                 :         840 :           && !strcmp (IDENTIFIER_POINTER (token->u.value), "readonly")
   47228                 :         888 :           && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
   47229                 :             :         {
   47230                 :          16 :           cp_lexer_consume_token (parser->lexer);
   47231                 :          16 :           cp_lexer_consume_token (parser->lexer);
   47232                 :          16 :           readonly = true;
   47233                 :             :         }
   47234                 :         872 :       clauses = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE__CACHE_,
   47235                 :             :                                                 NULL, NULL);
   47236                 :             :     }
   47237                 :             : 
   47238                 :         872 :   if (readonly)
   47239                 :          32 :     for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   47240                 :          16 :       OMP_CLAUSE__CACHE__READONLY (c) = 1;
   47241                 :             : 
   47242                 :         888 :   clauses = finish_omp_clauses (clauses, C_ORT_ACC);
   47243                 :             : 
   47244                 :         888 :   cp_parser_require_pragma_eol (parser, cp_lexer_peek_token (parser->lexer));
   47245                 :             : 
   47246                 :         888 :   stmt = make_node (OACC_CACHE);
   47247                 :         888 :   TREE_TYPE (stmt) = void_type_node;
   47248                 :         888 :   OACC_CACHE_CLAUSES (stmt) = clauses;
   47249                 :         888 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   47250                 :         888 :   add_stmt (stmt);
   47251                 :             : 
   47252                 :         888 :   return stmt;
   47253                 :             : }
   47254                 :             : 
   47255                 :             : /* OpenACC 2.0:
   47256                 :             :    # pragma acc data oacc-data-clause[optseq] new-line
   47257                 :             :      structured-block  */
   47258                 :             : 
   47259                 :             : #define OACC_DATA_CLAUSE_MASK                                           \
   47260                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   47261                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   47262                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   47263                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   47264                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   47265                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   47266                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH)                \
   47267                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   47268                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   47269                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   47270                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) )
   47271                 :             : 
   47272                 :             : static tree
   47273                 :         780 : cp_parser_oacc_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   47274                 :             : {
   47275                 :         780 :   tree stmt, clauses, block;
   47276                 :         780 :   unsigned int save;
   47277                 :             : 
   47278                 :         780 :   clauses = cp_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
   47279                 :             :                                         "#pragma acc data", pragma_tok);
   47280                 :             : 
   47281                 :         780 :   block = begin_omp_parallel ();
   47282                 :         780 :   save = cp_parser_begin_omp_structured_block (parser);
   47283                 :         780 :   cp_parser_statement (parser, NULL_TREE, false, if_p);
   47284                 :         780 :   cp_parser_end_omp_structured_block (parser, save);
   47285                 :         780 :   stmt = finish_oacc_data (clauses, block);
   47286                 :         780 :   return stmt;
   47287                 :             : }
   47288                 :             : 
   47289                 :             : /* OpenACC 2.0:
   47290                 :             :   # pragma acc host_data <clauses> new-line
   47291                 :             :   structured-block  */
   47292                 :             : 
   47293                 :             : #define OACC_HOST_DATA_CLAUSE_MASK                                      \
   47294                 :             :   ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)                \
   47295                 :             :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                        \
   47296                 :             :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
   47297                 :             : 
   47298                 :             : static tree
   47299                 :          80 : cp_parser_oacc_host_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   47300                 :             : {
   47301                 :          80 :   tree stmt, clauses, block;
   47302                 :          80 :   unsigned int save;
   47303                 :             : 
   47304                 :          80 :   clauses = cp_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
   47305                 :             :                                         "#pragma acc host_data", pragma_tok,
   47306                 :             :                                         false);
   47307                 :          80 :   if (!omp_find_clause (clauses, OMP_CLAUSE_USE_DEVICE_PTR))
   47308                 :             :     {
   47309                 :           8 :       error_at (pragma_tok->location,
   47310                 :             :                 "%<host_data%> construct requires %<use_device%> clause");
   47311                 :           8 :       return error_mark_node;
   47312                 :             :     }
   47313                 :          72 :   clauses = finish_omp_clauses (clauses, C_ORT_ACC);
   47314                 :          72 :   block = begin_omp_parallel ();
   47315                 :          72 :   save = cp_parser_begin_omp_structured_block (parser);
   47316                 :          72 :   cp_parser_statement (parser, NULL_TREE, false, if_p);
   47317                 :          72 :   cp_parser_end_omp_structured_block (parser, save);
   47318                 :          72 :   stmt = finish_oacc_host_data (clauses, block);
   47319                 :          72 :   return stmt;
   47320                 :             : }
   47321                 :             : 
   47322                 :             : /* OpenACC 2.0:
   47323                 :             :    # pragma acc declare oacc-data-clause[optseq] new-line
   47324                 :             : */
   47325                 :             : 
   47326                 :             : #define OACC_DECLARE_CLAUSE_MASK                                        \
   47327                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   47328                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   47329                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   47330                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   47331                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   47332                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT)       \
   47333                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK)          \
   47334                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) )
   47335                 :             : 
   47336                 :             : static tree
   47337                 :         541 : cp_parser_oacc_declare (cp_parser *parser, cp_token *pragma_tok)
   47338                 :             : {
   47339                 :         541 :   tree clauses, stmt;
   47340                 :         541 :   bool error = false;
   47341                 :         541 :   bool found_in_scope = global_bindings_p ();
   47342                 :             : 
   47343                 :         541 :   clauses = cp_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
   47344                 :             :                                         "#pragma acc declare", pragma_tok);
   47345                 :             : 
   47346                 :             : 
   47347                 :         541 :   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
   47348                 :             :     {
   47349                 :           8 :       error_at (pragma_tok->location,
   47350                 :             :                 "no valid clauses specified in %<#pragma acc declare%>");
   47351                 :           8 :       return NULL_TREE;
   47352                 :             :     }
   47353                 :             : 
   47354                 :        1114 :   for (tree t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
   47355                 :             :     {
   47356                 :         581 :       location_t loc = OMP_CLAUSE_LOCATION (t);
   47357                 :         581 :       tree decl = OMP_CLAUSE_DECL (t);
   47358                 :         581 :       if (!DECL_P (decl))
   47359                 :             :         {
   47360                 :           4 :           error_at (loc, "array section in %<#pragma acc declare%>");
   47361                 :           4 :           error = true;
   47362                 :           4 :           continue;
   47363                 :             :         }
   47364                 :         577 :       gcc_assert (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_MAP);
   47365                 :         577 :       switch (OMP_CLAUSE_MAP_KIND (t))
   47366                 :             :         {
   47367                 :             :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   47368                 :             :         case GOMP_MAP_ALLOC:
   47369                 :             :         case GOMP_MAP_TO:
   47370                 :             :         case GOMP_MAP_FORCE_DEVICEPTR:
   47371                 :             :         case GOMP_MAP_DEVICE_RESIDENT:
   47372                 :             :           break;
   47373                 :             : 
   47374                 :          52 :         case GOMP_MAP_LINK:
   47375                 :          52 :           if (!global_bindings_p ()
   47376                 :          52 :               && (TREE_STATIC (decl)
   47377                 :          24 :                || !DECL_EXTERNAL (decl)))
   47378                 :             :             {
   47379                 :           8 :               error_at (loc,
   47380                 :             :                         "%qD must be a global variable in "
   47381                 :             :                         "%<#pragma acc declare link%>",
   47382                 :             :                         decl);
   47383                 :           8 :               error = true;
   47384                 :           8 :               continue;
   47385                 :             :             }
   47386                 :             :           break;
   47387                 :             : 
   47388                 :         151 :         default:
   47389                 :         151 :           if (global_bindings_p ())
   47390                 :             :             {
   47391                 :          20 :               error_at (loc, "invalid OpenACC clause at file scope");
   47392                 :          20 :               error = true;
   47393                 :          20 :               continue;
   47394                 :             :             }
   47395                 :         131 :           if (DECL_EXTERNAL (decl))
   47396                 :             :             {
   47397                 :          40 :               error_at (loc,
   47398                 :             :                         "invalid use of %<extern%> variable %qD "
   47399                 :             :                         "in %<#pragma acc declare%>", decl);
   47400                 :          40 :               error = true;
   47401                 :          40 :               continue;
   47402                 :             :             }
   47403                 :          91 :           else if (TREE_PUBLIC (decl))
   47404                 :             :             {
   47405                 :           8 :               error_at (loc,
   47406                 :             :                         "invalid use of %<global%> variable %qD "
   47407                 :             :                         "in %<#pragma acc declare%>", decl);
   47408                 :           8 :               error = true;
   47409                 :           8 :               continue;
   47410                 :             :             }
   47411                 :             :           break;
   47412                 :             :         }
   47413                 :             : 
   47414                 :         501 :       if (!found_in_scope)
   47415                 :             :         /* This seems to ignore the existence of cleanup scopes?
   47416                 :             :            What is the meaning for local extern decls?  The local
   47417                 :             :            extern is in this scope, but it is referring to a decl that
   47418                 :             :            is namespace scope.  */
   47419                 :         347 :         for (tree d = current_binding_level->names; d; d = TREE_CHAIN (d))
   47420                 :         331 :           if (d == decl)
   47421                 :             :             {
   47422                 :             :               found_in_scope = true;
   47423                 :             :               break;
   47424                 :             :             }
   47425                 :         326 :       if (!found_in_scope)
   47426                 :             :         {
   47427                 :          16 :           error_at (loc,
   47428                 :             :                     "%qD must be a variable declared in the same scope as "
   47429                 :             :                     "%<#pragma acc declare%>", decl);
   47430                 :          16 :           error = true;
   47431                 :          16 :           continue;
   47432                 :             :         }
   47433                 :             : 
   47434                 :         485 :       if (!error)
   47435                 :             :         {
   47436                 :         485 :           if (DECL_LOCAL_DECL_P (decl))
   47437                 :             :             /* We need to mark the aliased decl, as that is the entity
   47438                 :             :                that is being referred to.  This won't work for
   47439                 :             :                dependent variables, but it didn't work for them before
   47440                 :             :                DECL_LOCAL_DECL_P was a thing either.  But then
   47441                 :             :                dependent local extern variable decls are as rare as
   47442                 :             :                hen's teeth.  */
   47443                 :         124 :             if (auto alias = DECL_LOCAL_DECL_ALIAS (decl))
   47444                 :         124 :               if (alias != error_mark_node)
   47445                 :         485 :                 decl = alias;
   47446                 :             : 
   47447                 :         485 :           if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
   47448                 :         914 :               || lookup_attribute ("omp declare target link",
   47449                 :         429 :                                    DECL_ATTRIBUTES (decl)))
   47450                 :             :             {
   47451                 :          68 :               error_at (loc, "variable %qD used more than once with "
   47452                 :             :                         "%<#pragma acc declare%>", decl);
   47453                 :          68 :               error = true;
   47454                 :          68 :               continue;
   47455                 :             :             }
   47456                 :             : 
   47457                 :         417 :           tree id;
   47458                 :         417 :           if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
   47459                 :          28 :             id = get_identifier ("omp declare target link");
   47460                 :             :           else
   47461                 :         389 :             id = get_identifier ("omp declare target");
   47462                 :             : 
   47463                 :         417 :           DECL_ATTRIBUTES (decl)
   47464                 :         417 :             = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   47465                 :         417 :           if (current_binding_level->kind == sk_namespace)
   47466                 :             :             {
   47467                 :         165 :               symtab_node *node = symtab_node::get (decl);
   47468                 :         165 :               if (node != NULL)
   47469                 :             :                 {
   47470                 :         117 :                   node->offloadable = 1;
   47471                 :         117 :                   if (ENABLE_OFFLOADING)
   47472                 :             :                     {
   47473                 :             :                       g->have_offload = true;
   47474                 :             :                       if (is_a <varpool_node *> (node))
   47475                 :             :                         vec_safe_push (offload_vars, decl);
   47476                 :             :                     }
   47477                 :             :                 }
   47478                 :             :             }
   47479                 :             :         }
   47480                 :             :     }
   47481                 :             : 
   47482                 :         533 :   if (error || current_binding_level->kind == sk_namespace)
   47483                 :             :     return NULL_TREE;
   47484                 :             : 
   47485                 :         244 :   stmt = make_node (OACC_DECLARE);
   47486                 :         244 :   TREE_TYPE (stmt) = void_type_node;
   47487                 :         244 :   OACC_DECLARE_CLAUSES (stmt) = clauses;
   47488                 :         244 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   47489                 :             : 
   47490                 :         244 :   add_stmt (stmt);
   47491                 :             : 
   47492                 :         244 :   return NULL_TREE;
   47493                 :             : }
   47494                 :             : 
   47495                 :             : /* OpenACC 2.0:
   47496                 :             :    # pragma acc enter data oacc-enter-data-clause[optseq] new-line
   47497                 :             : 
   47498                 :             :    or
   47499                 :             : 
   47500                 :             :    # pragma acc exit data oacc-exit-data-clause[optseq] new-line
   47501                 :             : 
   47502                 :             :    LOC is the location of the #pragma token.
   47503                 :             : */
   47504                 :             : 
   47505                 :             : #define OACC_ENTER_DATA_CLAUSE_MASK                                     \
   47506                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   47507                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   47508                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   47509                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   47510                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   47511                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   47512                 :             : 
   47513                 :             : #define OACC_EXIT_DATA_CLAUSE_MASK                                      \
   47514                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   47515                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   47516                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   47517                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE)                \
   47518                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH)                \
   47519                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE)              \
   47520                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   47521                 :             : 
   47522                 :             : static tree
   47523                 :         797 : cp_parser_oacc_enter_exit_data (cp_parser *parser, cp_token *pragma_tok,
   47524                 :             :                                 bool enter)
   47525                 :             : {
   47526                 :         797 :   location_t loc = pragma_tok->location;
   47527                 :         797 :   tree stmt, clauses;
   47528                 :         797 :   const char *p = "";
   47529                 :             : 
   47530                 :         797 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   47531                 :         769 :     p = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
   47532                 :             : 
   47533                 :         797 :   if (strcmp (p, "data") != 0)
   47534                 :             :     {
   47535                 :          80 :       error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
   47536                 :             :                 enter ? "enter" : "exit");
   47537                 :          56 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   47538                 :          56 :       return NULL_TREE;
   47539                 :             :     }
   47540                 :             : 
   47541                 :         741 :   cp_lexer_consume_token (parser->lexer);
   47542                 :             : 
   47543                 :         741 :   if (enter)
   47544                 :         368 :     clauses = cp_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
   47545                 :             :                                          "#pragma acc enter data", pragma_tok);
   47546                 :             :   else
   47547                 :         373 :     clauses = cp_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
   47548                 :             :                                          "#pragma acc exit data", pragma_tok);
   47549                 :             : 
   47550                 :         741 :   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
   47551                 :             :     {
   47552                 :         132 :       error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
   47553                 :             :                 enter ? "enter" : "exit");
   47554                 :         132 :       return NULL_TREE;
   47555                 :             :     }
   47556                 :             : 
   47557                 :         609 :   stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
   47558                 :         609 :   TREE_TYPE (stmt) = void_type_node;
   47559                 :         609 :   OMP_STANDALONE_CLAUSES (stmt) = clauses;
   47560                 :         609 :   SET_EXPR_LOCATION (stmt, loc);
   47561                 :         609 :   add_stmt (stmt);
   47562                 :         609 :   return stmt;
   47563                 :             : }
   47564                 :             : 
   47565                 :             : /* OpenACC 2.0:
   47566                 :             :    # pragma acc loop oacc-loop-clause[optseq] new-line
   47567                 :             :      structured-block  */
   47568                 :             : 
   47569                 :             : #define OACC_LOOP_CLAUSE_MASK                                           \
   47570                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE)              \
   47571                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)               \
   47572                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)             \
   47573                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)          \
   47574                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)                \
   47575                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)                \
   47576                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO)          \
   47577                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT)           \
   47578                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)                   \
   47579                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE))
   47580                 :             : 
   47581                 :             : static tree
   47582                 :        5452 : cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
   47583                 :             :                      omp_clause_mask mask, tree *cclauses, bool *if_p)
   47584                 :             : {
   47585                 :        5452 :   bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
   47586                 :             : 
   47587                 :        5452 :   strcat (p_name, " loop");
   47588                 :        5452 :   mask |= OACC_LOOP_CLAUSE_MASK;
   47589                 :             : 
   47590                 :        5452 :   tree clauses = cp_parser_oacc_all_clauses (parser, mask, p_name, pragma_tok,
   47591                 :             :                                              /*finish_p=*/cclauses == NULL,
   47592                 :             :                                              /*target=*/is_parallel);
   47593                 :        5452 :   if (cclauses)
   47594                 :             :     {
   47595                 :        1193 :       clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
   47596                 :        1193 :       if (*cclauses)
   47597                 :         237 :         *cclauses = finish_omp_clauses (*cclauses, C_ORT_ACC_TARGET);
   47598                 :        1193 :       if (clauses)
   47599                 :         701 :         clauses = finish_omp_clauses (clauses, C_ORT_ACC);
   47600                 :             :     }
   47601                 :             : 
   47602                 :        5452 :   tree block = begin_omp_structured_block ();
   47603                 :        5452 :   int save = cp_parser_begin_omp_structured_block (parser);
   47604                 :        5452 :   tree stmt = cp_parser_omp_for_loop (parser, OACC_LOOP, clauses, NULL, if_p);
   47605                 :        5452 :   cp_parser_end_omp_structured_block (parser, save);
   47606                 :             : 
   47607                 :             :   /* Later processing of combined acc loop constructs gets confused
   47608                 :             :      by an extra level of empty nested BIND_EXPRs, so flatten them.  */
   47609                 :        5452 :   block = finish_omp_structured_block (block);
   47610                 :        5452 :   if (TREE_CODE (block) == BIND_EXPR
   47611                 :        1488 :       && TREE_CODE (BIND_EXPR_BODY (block)) == BIND_EXPR
   47612                 :        6568 :       && !BIND_EXPR_VARS (block))
   47613                 :        1116 :     block = BIND_EXPR_BODY (block);
   47614                 :        5452 :   add_stmt (block);
   47615                 :             : 
   47616                 :        5452 :   return stmt;
   47617                 :             : }
   47618                 :             : 
   47619                 :             : /* OpenACC 2.0:
   47620                 :             :    # pragma acc kernels oacc-kernels-clause[optseq] new-line
   47621                 :             :      structured-block
   47622                 :             : 
   47623                 :             :    or
   47624                 :             : 
   47625                 :             :    # pragma acc parallel oacc-parallel-clause[optseq] new-line
   47626                 :             :      structured-block
   47627                 :             : 
   47628                 :             :    OpenACC 2.6:
   47629                 :             : 
   47630                 :             :    # pragma acc serial oacc-serial-clause[optseq] new-line
   47631                 :             : */
   47632                 :             : 
   47633                 :             : #define OACC_KERNELS_CLAUSE_MASK                                        \
   47634                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   47635                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   47636                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   47637                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   47638                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   47639                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   47640                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   47641                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   47642                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   47643                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   47644                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)             \
   47645                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)           \
   47646                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)               \
   47647                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   47648                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
   47649                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   47650                 :             : 
   47651                 :             : #define OACC_PARALLEL_CLAUSE_MASK                                       \
   47652                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   47653                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   47654                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   47655                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   47656                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   47657                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   47658                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   47659                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   47660                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)  \
   47661                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   47662                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   47663                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)             \
   47664                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)           \
   47665                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)               \
   47666                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)               \
   47667                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)             \
   47668                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   47669                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)       \
   47670                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   47671                 :             : 
   47672                 :             : #define OACC_SERIAL_CLAUSE_MASK                                         \
   47673                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   47674                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   47675                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   47676                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   47677                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   47678                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   47679                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   47680                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   47681                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   47682                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   47683                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)               \
   47684                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)  \
   47685                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)               \
   47686                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)             \
   47687                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   47688                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   47689                 :             : 
   47690                 :             : static tree
   47691                 :        4836 : cp_parser_oacc_compute (cp_parser *parser, cp_token *pragma_tok,
   47692                 :             :                         char *p_name, bool *if_p)
   47693                 :             : {
   47694                 :        4836 :   omp_clause_mask mask;
   47695                 :        4836 :   enum tree_code code;
   47696                 :        4836 :   switch (cp_parser_pragma_kind (pragma_tok))
   47697                 :             :     {
   47698                 :        1537 :     case PRAGMA_OACC_KERNELS:
   47699                 :        1537 :       strcat (p_name, " kernels");
   47700                 :        1537 :       mask = OACC_KERNELS_CLAUSE_MASK;
   47701                 :        1537 :       code = OACC_KERNELS;
   47702                 :        1537 :       break;
   47703                 :        3225 :     case PRAGMA_OACC_PARALLEL:
   47704                 :        3225 :       strcat (p_name, " parallel");
   47705                 :        3225 :       mask = OACC_PARALLEL_CLAUSE_MASK;
   47706                 :        3225 :       code = OACC_PARALLEL;
   47707                 :        3225 :       break;
   47708                 :          74 :     case PRAGMA_OACC_SERIAL:
   47709                 :          74 :       strcat (p_name, " serial");
   47710                 :          74 :       mask = OACC_SERIAL_CLAUSE_MASK;
   47711                 :          74 :       code = OACC_SERIAL;
   47712                 :          74 :       break;
   47713                 :           0 :     default:
   47714                 :           0 :       gcc_unreachable ();
   47715                 :             :     }
   47716                 :             : 
   47717                 :        4836 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   47718                 :             :     {
   47719                 :        3627 :       const char *p
   47720                 :        3627 :         = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
   47721                 :        3627 :       if (strcmp (p, "loop") == 0)
   47722                 :             :         {
   47723                 :        1193 :           cp_lexer_consume_token (parser->lexer);
   47724                 :        1193 :           tree block = begin_omp_parallel ();
   47725                 :        1193 :           tree clauses;
   47726                 :        1193 :           tree stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask,
   47727                 :             :                                            &clauses, if_p);
   47728                 :        1193 :           protected_set_expr_location (stmt, pragma_tok->location);
   47729                 :        1193 :           return finish_omp_construct (code, block, clauses);
   47730                 :             :         }
   47731                 :             :     }
   47732                 :             : 
   47733                 :        3643 :   tree clauses = cp_parser_oacc_all_clauses (parser, mask, p_name, pragma_tok,
   47734                 :             :                                              /*finish_p=*/true,
   47735                 :             :                                              /*target=*/true);
   47736                 :             : 
   47737                 :        3643 :   tree block = begin_omp_parallel ();
   47738                 :        3643 :   unsigned int save = cp_parser_begin_omp_structured_block (parser);
   47739                 :        3643 :   cp_parser_statement (parser, NULL_TREE, false, if_p);
   47740                 :        3643 :   cp_parser_end_omp_structured_block (parser, save);
   47741                 :        3643 :   return finish_omp_construct (code, block, clauses);
   47742                 :             : }
   47743                 :             : 
   47744                 :             : /* OpenACC 2.0:
   47745                 :             :    # pragma acc update oacc-update-clause[optseq] new-line
   47746                 :             : */
   47747                 :             : 
   47748                 :             : #define OACC_UPDATE_CLAUSE_MASK                                         \
   47749                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   47750                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE)                \
   47751                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)          \
   47752                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   47753                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT)            \
   47754                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   47755                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT))
   47756                 :             : 
   47757                 :             : static tree
   47758                 :         237 : cp_parser_oacc_update (cp_parser *parser, cp_token *pragma_tok)
   47759                 :             : {
   47760                 :         237 :   tree stmt, clauses;
   47761                 :             : 
   47762                 :         237 :   clauses = cp_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
   47763                 :             :                                          "#pragma acc update", pragma_tok);
   47764                 :             : 
   47765                 :         237 :   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
   47766                 :             :     {
   47767                 :           4 :       error_at (pragma_tok->location,
   47768                 :             :                 "%<#pragma acc update%> must contain at least one "
   47769                 :             :                 "%<device%> or %<host%> or %<self%> clause");
   47770                 :           4 :       return NULL_TREE;
   47771                 :             :     }
   47772                 :             : 
   47773                 :         233 :   stmt = make_node (OACC_UPDATE);
   47774                 :         233 :   TREE_TYPE (stmt) = void_type_node;
   47775                 :         233 :   OACC_UPDATE_CLAUSES (stmt) = clauses;
   47776                 :         233 :   SET_EXPR_LOCATION (stmt, pragma_tok->location);
   47777                 :         233 :   add_stmt (stmt);
   47778                 :         233 :   return stmt;
   47779                 :             : }
   47780                 :             : 
   47781                 :             : /* OpenACC 2.0:
   47782                 :             :    # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
   47783                 :             : 
   47784                 :             :    LOC is the location of the #pragma token.
   47785                 :             : */
   47786                 :             : 
   47787                 :             : #define OACC_WAIT_CLAUSE_MASK                                   \
   47788                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC))
   47789                 :             : 
   47790                 :             : static tree
   47791                 :         162 : cp_parser_oacc_wait (cp_parser *parser, cp_token *pragma_tok)
   47792                 :             : {
   47793                 :         162 :   tree clauses, list = NULL_TREE, stmt = NULL_TREE;
   47794                 :         162 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   47795                 :             : 
   47796                 :         162 :   if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
   47797                 :          79 :     list = cp_parser_oacc_wait_list (parser, loc, list);
   47798                 :             : 
   47799                 :         162 :   clauses = cp_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK,
   47800                 :             :                                         "#pragma acc wait", pragma_tok);
   47801                 :             : 
   47802                 :         162 :   stmt = c_finish_oacc_wait (loc, list, clauses);
   47803                 :         162 :   stmt = finish_expr_stmt (stmt);
   47804                 :             : 
   47805                 :         162 :   return stmt;
   47806                 :             : }
   47807                 :             : 
   47808                 :             : /* OpenMP 4.0:
   47809                 :             :    # pragma omp declare simd declare-simd-clauses[optseq] new-line  */
   47810                 :             : 
   47811                 :             : #define OMP_DECLARE_SIMD_CLAUSE_MASK                            \
   47812                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)        \
   47813                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
   47814                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)        \
   47815                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)        \
   47816                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH)       \
   47817                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
   47818                 :             : 
   47819                 :             : static void
   47820                 :        2548 : cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok,
   47821                 :             :                             enum pragma_context context,
   47822                 :             :                             bool variant_p)
   47823                 :             : {
   47824                 :        2548 :   bool first_p = parser->omp_declare_simd == NULL;
   47825                 :        2548 :   cp_omp_declare_simd_data data;
   47826                 :        2548 :   if (first_p)
   47827                 :             :     {
   47828                 :        2316 :       data.error_seen = false;
   47829                 :        2316 :       data.fndecl_seen = false;
   47830                 :        2316 :       data.variant_p = variant_p;
   47831                 :        2316 :       data.tokens = vNULL;
   47832                 :        2316 :       data.attribs[0] = NULL;
   47833                 :        2316 :       data.attribs[1] = NULL;
   47834                 :        2316 :       data.loc = UNKNOWN_LOCATION;
   47835                 :             :       /* It is safe to take the address of a local variable; it will only be
   47836                 :             :          used while this scope is live.  */
   47837                 :        2316 :       parser->omp_declare_simd = &data;
   47838                 :             :     }
   47839                 :         232 :   else if (parser->omp_declare_simd->variant_p != variant_p)
   47840                 :             :     {
   47841                 :           0 :       error_at (pragma_tok->location,
   47842                 :             :                 "%<#pragma omp declare %s%> followed by "
   47843                 :             :                 "%<#pragma omp declare %s%>",
   47844                 :             :                 parser->omp_declare_simd->variant_p ? "variant" : "simd",
   47845                 :             :                 parser->omp_declare_simd->variant_p ? "simd" : "variant");
   47846                 :           0 :       parser->omp_declare_simd->error_seen = true;
   47847                 :             :     }
   47848                 :             : 
   47849                 :             :   /* Store away all pragma tokens.  */
   47850                 :       37170 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   47851                 :       34622 :     cp_lexer_consume_token (parser->lexer);
   47852                 :        2548 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   47853                 :        2548 :   struct cp_token_cache *cp
   47854                 :        2548 :     = cp_token_cache_new (pragma_tok, cp_lexer_peek_token (parser->lexer));
   47855                 :        2548 :   parser->omp_declare_simd->tokens.safe_push (cp);
   47856                 :             : 
   47857                 :        2548 :   if (first_p)
   47858                 :             :     {
   47859                 :        2560 :       while (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
   47860                 :         244 :         cp_parser_pragma (parser, context, NULL);
   47861                 :        2316 :       switch (context)
   47862                 :             :         {
   47863                 :        1969 :         case pragma_external:
   47864                 :        1969 :           cp_parser_declaration (parser, NULL_TREE);
   47865                 :        1969 :           break;
   47866                 :         298 :         case pragma_member:
   47867                 :         298 :           cp_parser_member_declaration (parser);
   47868                 :         298 :           break;
   47869                 :           0 :         case pragma_objc_icode:
   47870                 :           0 :           cp_parser_block_declaration (parser, /*statement_p=*/false);
   47871                 :           0 :           break;
   47872                 :          49 :         default:
   47873                 :          49 :           cp_parser_declaration_statement (parser);
   47874                 :          49 :           break;
   47875                 :             :         }
   47876                 :        2316 :       if (parser->omp_declare_simd
   47877                 :        1894 :           && !parser->omp_declare_simd->error_seen
   47878                 :        1886 :           && !parser->omp_declare_simd->fndecl_seen)
   47879                 :          16 :         error_at (pragma_tok->location,
   47880                 :             :                   "%<#pragma omp declare %s%> not immediately followed by "
   47881                 :             :                   "function declaration or definition",
   47882                 :          16 :                   parser->omp_declare_simd->variant_p ? "variant" : "simd");
   47883                 :        2316 :       data.tokens.release ();
   47884                 :        2316 :       parser->omp_declare_simd = NULL;
   47885                 :             :     }
   47886                 :        2548 : }
   47887                 :             : 
   47888                 :             : /* OpenMP 5.0:
   47889                 :             : 
   47890                 :             :    trait-selector:
   47891                 :             :      trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
   47892                 :             : 
   47893                 :             :    trait-score:
   47894                 :             :      score(score-expression)
   47895                 :             : 
   47896                 :             :    Note that this function returns a list of trait selectors for the
   47897                 :             :    trait-selector-set SET.  */
   47898                 :             : 
   47899                 :             : static tree
   47900                 :        1473 : cp_parser_omp_context_selector (cp_parser *parser, enum omp_tss_code set,
   47901                 :             :                                 bool has_parms_p)
   47902                 :             : {
   47903                 :        1473 :   tree ret = NULL_TREE;
   47904                 :        1855 :   do
   47905                 :             :     {
   47906                 :        1855 :       tree selector;
   47907                 :        1855 :       if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)
   47908                 :        1855 :           || cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   47909                 :        1847 :         selector = cp_lexer_peek_token (parser->lexer)->u.value;
   47910                 :             :       else
   47911                 :             :         {
   47912                 :           8 :           cp_parser_error (parser, "expected trait selector name");
   47913                 :           8 :           return error_mark_node;
   47914                 :             :         }
   47915                 :             : 
   47916                 :        1847 :       enum omp_ts_code sel
   47917                 :        1847 :         = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector));
   47918                 :             : 
   47919                 :        1847 :       if (sel == OMP_TRAIT_INVALID)
   47920                 :             :         {
   47921                 :             :           /* Per the spec, "Implementations can ignore specified selectors
   47922                 :             :              that are not those described in this section"; however, we
   47923                 :             :              must record such selectors because they cause match failures.  */
   47924                 :          72 :           warning_at (cp_lexer_peek_token (parser->lexer)->location,
   47925                 :             :                       OPT_Wopenmp,
   47926                 :             :                       "unknown selector %qs for context selector set %qs",
   47927                 :          72 :                       IDENTIFIER_POINTER (selector),  omp_tss_map[set]);
   47928                 :          72 :           cp_lexer_consume_token (parser->lexer);
   47929                 :          72 :           ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret);
   47930                 :          72 :           if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   47931                 :          96 :             for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1;
   47932                 :          96 :                  n; --n)
   47933                 :          76 :               cp_lexer_consume_token (parser->lexer);
   47934                 :          72 :           if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   47935                 :             :             {
   47936                 :           4 :               cp_lexer_consume_token (parser->lexer);
   47937                 :           4 :               continue;
   47938                 :             :             }
   47939                 :             :           else
   47940                 :             :             break;
   47941                 :             :         }
   47942                 :             : 
   47943                 :        1775 :       cp_lexer_consume_token (parser->lexer);
   47944                 :             : 
   47945                 :        1775 :       tree properties = NULL_TREE;
   47946                 :        1775 :       tree scoreval = NULL_TREE;
   47947                 :        1775 :       enum omp_tp_type property_kind = omp_ts_map[sel].tp_type;
   47948                 :        1775 :       bool allow_score = omp_ts_map[sel].allow_score;
   47949                 :        1775 :       tree t;
   47950                 :             : 
   47951                 :        1775 :       if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   47952                 :             :         {
   47953                 :        1229 :           if (property_kind == OMP_TRAIT_PROPERTY_NONE)
   47954                 :             :             {
   47955                 :          24 :               error ("selector %qs does not accept any properties",
   47956                 :          24 :                      IDENTIFIER_POINTER (selector));
   47957                 :          65 :               return error_mark_node;
   47958                 :             :             }
   47959                 :             : 
   47960                 :        1205 :           matching_parens parens;
   47961                 :        1205 :           parens.consume_open (parser);
   47962                 :             : 
   47963                 :        1205 :           cp_token *token = cp_lexer_peek_token (parser->lexer);
   47964                 :        1205 :           if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   47965                 :         768 :               && strcmp (IDENTIFIER_POINTER (token->u.value), "score") == 0
   47966                 :        1477 :               && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
   47967                 :             :             {
   47968                 :         272 :               cp_lexer_save_tokens (parser->lexer);
   47969                 :         272 :               cp_lexer_consume_token (parser->lexer);
   47970                 :         272 :               cp_lexer_consume_token (parser->lexer);
   47971                 :         272 :               if (cp_parser_skip_to_closing_parenthesis (parser, false, false,
   47972                 :             :                                                          true)
   47973                 :         272 :                   && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
   47974                 :             :                 {
   47975                 :         266 :                   cp_lexer_rollback_tokens (parser->lexer);
   47976                 :         266 :                   cp_lexer_consume_token (parser->lexer);
   47977                 :             : 
   47978                 :         266 :                   matching_parens parens2;
   47979                 :         266 :                   parens2.require_open (parser);
   47980                 :         266 :                   tree score = cp_parser_constant_expression (parser);
   47981                 :         266 :                   if (!parens2.require_close (parser))
   47982                 :           0 :                     cp_parser_skip_to_closing_parenthesis (parser, true,
   47983                 :             :                                                            false, true);
   47984                 :         266 :                   cp_parser_require (parser, CPP_COLON, RT_COLON);
   47985                 :         266 :                   if (!allow_score)
   47986                 :          16 :                     error_at (token->location,
   47987                 :             :                               "%<score%> cannot be specified in traits "
   47988                 :             :                               "in the %qs trait-selector-set",
   47989                 :             :                               omp_tss_map[set]);
   47990                 :         250 :                   else if (score != error_mark_node)
   47991                 :             :                     {
   47992                 :         249 :                       score = fold_non_dependent_expr (score);
   47993                 :         249 :                       if (value_dependent_expression_p (score))
   47994                 :             :                         scoreval = score;
   47995                 :         426 :                       else if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
   47996                 :         423 :                                || TREE_CODE (score) != INTEGER_CST)
   47997                 :           3 :                         error_at (token->location, "%<score%> argument must "
   47998                 :             :                                   "be constant integer expression");
   47999                 :         210 :                       else if (tree_int_cst_sgn (score) < 0)
   48000                 :           4 :                         error_at (token->location, "%<score%> argument must "
   48001                 :             :                                   "be non-negative");
   48002                 :             :                       else
   48003                 :             :                         scoreval = score;
   48004                 :             :                     }
   48005                 :             :                 }
   48006                 :             :               else
   48007                 :           6 :                 cp_lexer_rollback_tokens (parser->lexer);
   48008                 :             : 
   48009                 :         272 :               token = cp_lexer_peek_token (parser->lexer);
   48010                 :             :             }
   48011                 :             : 
   48012                 :        1205 :           switch (property_kind)
   48013                 :             :             {
   48014                 :          92 :             case OMP_TRAIT_PROPERTY_ID:
   48015                 :          92 :               if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)
   48016                 :          92 :                   || cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   48017                 :             :                 {
   48018                 :          88 :                   tree prop = cp_lexer_peek_token (parser->lexer)->u.value;
   48019                 :          88 :                   cp_lexer_consume_token (parser->lexer);
   48020                 :          88 :                   properties = make_trait_property (prop, NULL_TREE,
   48021                 :             :                                                     properties);
   48022                 :             :                 }
   48023                 :             :               else
   48024                 :             :                 {
   48025                 :           4 :                   cp_parser_error (parser, "expected identifier");
   48026                 :           4 :                   return error_mark_node;
   48027                 :             :                 }
   48028                 :          88 :               break;
   48029                 :         804 :             case OMP_TRAIT_PROPERTY_NAME_LIST:
   48030                 :         996 :               do
   48031                 :             :                 {
   48032                 :         804 :                   tree prop = OMP_TP_NAMELIST_NODE;
   48033                 :         804 :                   tree value = NULL_TREE;
   48034                 :         804 :                   if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)
   48035                 :         804 :                       || cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   48036                 :             :                     {
   48037                 :         620 :                       value = cp_lexer_peek_token (parser->lexer)->u.value;
   48038                 :         620 :                       cp_lexer_consume_token (parser->lexer);
   48039                 :             :                     }
   48040                 :         184 :                   else if (cp_lexer_next_token_is (parser->lexer, CPP_STRING))
   48041                 :         164 :                     value = cp_parser_string_literal (parser,
   48042                 :             :                                                       /*translate=*/false,
   48043                 :             :                                                       /*wide_ok=*/false);
   48044                 :             :                   else
   48045                 :             :                     {
   48046                 :          20 :                       cp_parser_error (parser, "expected identifier or "
   48047                 :             :                                                "string literal");
   48048                 :          20 :                       return error_mark_node;
   48049                 :             :                     }
   48050                 :             : 
   48051                 :         784 :                   properties = make_trait_property (prop, value, properties);
   48052                 :             : 
   48053                 :         784 :                   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   48054                 :         192 :                     cp_lexer_consume_token (parser->lexer);
   48055                 :             :                   else
   48056                 :             :                     break;
   48057                 :         192 :                 }
   48058                 :             :               while (1);
   48059                 :             :               break;
   48060                 :         433 :             case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
   48061                 :         433 :             case OMP_TRAIT_PROPERTY_BOOL_EXPR:
   48062                 :             :               /* FIXME: this is bogus, the expression need
   48063                 :             :                  not be constant.  */
   48064                 :         433 :               t = cp_parser_constant_expression (parser);
   48065                 :         433 :               if (t != error_mark_node)
   48066                 :             :                 {
   48067                 :         416 :                   t = fold_non_dependent_expr (t);
   48068                 :         416 :                   if (!value_dependent_expression_p (t)
   48069                 :         416 :                       && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
   48070                 :         377 :                           || !tree_fits_shwi_p (t)))
   48071                 :           3 :                     error_at (token->location, "property must be "
   48072                 :             :                               "constant integer expression");
   48073                 :             :                   else
   48074                 :         413 :                     properties = make_trait_property (NULL_TREE, t,
   48075                 :             :                                                       properties);
   48076                 :             :                 }
   48077                 :             :               else
   48078                 :          17 :                 return error_mark_node;
   48079                 :             :               break;
   48080                 :          68 :             case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
   48081                 :          68 :               if (sel == OMP_TRAIT_CONSTRUCT_SIMD)
   48082                 :             :                 {
   48083                 :          68 :                   if (!has_parms_p)
   48084                 :             :                     {
   48085                 :           0 :                       error_at (token->location, "properties for %<simd%> "
   48086                 :             :                                 "selector may not be specified in "
   48087                 :             :                                 "%<metadirective%>");
   48088                 :           0 :                       return error_mark_node;
   48089                 :             :                     }
   48090                 :          68 :                   properties
   48091                 :          68 :                     = cp_parser_omp_all_clauses (parser,
   48092                 :          68 :                                                  OMP_DECLARE_SIMD_CLAUSE_MASK,
   48093                 :             :                                                  "simd", NULL, true, 2);
   48094                 :             :                 }
   48095                 :           0 :               else if (sel == OMP_TRAIT_IMPLEMENTATION_REQUIRES)
   48096                 :             :                 {
   48097                 :             :                   /* FIXME: The "requires" selector was added in OpenMP 5.1.
   48098                 :             :                      Currently only the now-deprecated syntax
   48099                 :             :                      from OpenMP 5.0 is supported.  */
   48100                 :           0 :                   sorry_at (token->location,
   48101                 :             :                             "%<requires%> selector is not supported yet");
   48102                 :           0 :                   return error_mark_node;
   48103                 :             :                 }
   48104                 :             :               else
   48105                 :           0 :                 gcc_unreachable ();
   48106                 :          68 :               break;
   48107                 :           0 :             default:
   48108                 :           0 :               gcc_unreachable ();
   48109                 :             :             }
   48110                 :             : 
   48111                 :        1164 :           if (!parens.require_close (parser))
   48112                 :          12 :             cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
   48113                 :             : 
   48114                 :        1164 :           properties = nreverse (properties);
   48115                 :             :         }
   48116                 :         546 :       else if (property_kind != OMP_TRAIT_PROPERTY_NONE
   48117                 :         546 :                && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST
   48118                 :          32 :                && property_kind != OMP_TRAIT_PROPERTY_EXTENSION)
   48119                 :             :         {
   48120                 :          32 :           cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
   48121                 :          32 :           return error_mark_node;
   48122                 :             :         }
   48123                 :             : 
   48124                 :        1678 :       ret = make_trait_selector (sel, scoreval, properties, ret);
   48125                 :             : 
   48126                 :        1678 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   48127                 :         378 :         cp_lexer_consume_token (parser->lexer);
   48128                 :             :       else
   48129                 :             :         break;
   48130                 :             :     }
   48131                 :             :   while (1);
   48132                 :             : 
   48133                 :        1368 :   return nreverse (ret);
   48134                 :             : }
   48135                 :             : 
   48136                 :             : /* OpenMP 5.0:
   48137                 :             : 
   48138                 :             :    trait-set-selector[,trait-set-selector[,...]]
   48139                 :             : 
   48140                 :             :    trait-set-selector:
   48141                 :             :      trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
   48142                 :             : 
   48143                 :             :    trait-set-selector-name:
   48144                 :             :      constructor
   48145                 :             :      device
   48146                 :             :      implementation
   48147                 :             :      user  */
   48148                 :             : 
   48149                 :             : static tree
   48150                 :        1369 : cp_parser_omp_context_selector_specification (cp_parser *parser,
   48151                 :             :                                               bool has_parms_p)
   48152                 :             : {
   48153                 :        1369 :   tree ret = NULL_TREE;
   48154                 :        1641 :   do
   48155                 :             :     {
   48156                 :        1505 :       const char *setp = "";
   48157                 :        1505 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   48158                 :        1497 :         setp
   48159                 :        1497 :           = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
   48160                 :        1505 :       enum omp_tss_code set = omp_lookup_tss_code (setp);
   48161                 :             : 
   48162                 :        1505 :       if (set == OMP_TRAIT_SET_INVALID)
   48163                 :             :         {
   48164                 :          20 :           cp_parser_error (parser, "expected context selector set name");
   48165                 :          32 :           return error_mark_node;
   48166                 :             :         }
   48167                 :             : 
   48168                 :        1485 :       cp_lexer_consume_token (parser->lexer);
   48169                 :             : 
   48170                 :        1485 :       if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
   48171                 :           4 :         return error_mark_node;
   48172                 :             : 
   48173                 :        1481 :       matching_braces braces;
   48174                 :        1481 :       if (!braces.require_open (parser))
   48175                 :           8 :         return error_mark_node;
   48176                 :             : 
   48177                 :        1473 :       tree selectors
   48178                 :        1473 :         = cp_parser_omp_context_selector (parser, set, has_parms_p);
   48179                 :        1473 :       if (selectors == error_mark_node)
   48180                 :             :         {
   48181                 :         105 :           cp_parser_skip_to_closing_brace (parser);
   48182                 :         105 :           ret = error_mark_node;
   48183                 :             :         }
   48184                 :        1368 :       else if (ret != error_mark_node)
   48185                 :        1368 :         ret = make_trait_set_selector (set, selectors, ret);
   48186                 :             : 
   48187                 :        1473 :       braces.require_close (parser);
   48188                 :             : 
   48189                 :        1473 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   48190                 :         136 :         cp_lexer_consume_token (parser->lexer);
   48191                 :             :       else
   48192                 :             :         break;
   48193                 :         136 :     }
   48194                 :             :   while (1);
   48195                 :             : 
   48196                 :        1337 :   if (ret == error_mark_node)
   48197                 :             :     return ret;
   48198                 :        1232 :   return nreverse (ret);
   48199                 :             : }
   48200                 :             : 
   48201                 :             : /* Assumption clauses:
   48202                 :             :    OpenMP 5.1
   48203                 :             :    absent (directive-name-list)
   48204                 :             :    contains (directive-name-list)
   48205                 :             :    holds (expression)
   48206                 :             :    no_openmp
   48207                 :             :    no_openmp_routines
   48208                 :             :    no_parallelism  */
   48209                 :             : 
   48210                 :             : static void
   48211                 :         458 : cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
   48212                 :             :                                   bool is_assume)
   48213                 :             : {
   48214                 :         458 :   bool no_openmp = false;
   48215                 :         458 :   bool no_openmp_routines = false;
   48216                 :         458 :   bool no_parallelism = false;
   48217                 :         458 :   bitmap_head absent_head, contains_head;
   48218                 :             : 
   48219                 :         458 :   bitmap_obstack_initialize (NULL);
   48220                 :         458 :   bitmap_initialize (&absent_head, &bitmap_default_obstack);
   48221                 :         458 :   bitmap_initialize (&contains_head, &bitmap_default_obstack);
   48222                 :             : 
   48223                 :         458 :   if (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL))
   48224                 :          12 :     error_at (cp_lexer_peek_token (parser->lexer)->location,
   48225                 :             :               "expected at least one assumption clause");
   48226                 :             : 
   48227                 :        1253 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   48228                 :             :     {
   48229                 :         807 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   48230                 :         807 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   48231                 :         189 :         cp_lexer_consume_token (parser->lexer);
   48232                 :             : 
   48233                 :         807 :       if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   48234                 :             :         break;
   48235                 :             : 
   48236                 :         807 :       const char *p
   48237                 :         807 :         = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
   48238                 :         807 :       location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
   48239                 :             : 
   48240                 :         807 :       if (!strcmp (p, "no_openmp"))
   48241                 :             :         {
   48242                 :          58 :           cp_lexer_consume_token (parser->lexer);
   48243                 :          58 :           if (no_openmp)
   48244                 :          12 :             error_at (cloc, "too many %qs clauses", "no_openmp");
   48245                 :             :           no_openmp = true;
   48246                 :             :         }
   48247                 :         749 :       else if (!strcmp (p, "no_openmp_routines"))
   48248                 :             :         {
   48249                 :          59 :           cp_lexer_consume_token (parser->lexer);
   48250                 :          59 :           if (no_openmp_routines)
   48251                 :          12 :             error_at (cloc, "too many %qs clauses", "no_openmp_routines");
   48252                 :             :           no_openmp_routines = true;
   48253                 :             :         }
   48254                 :         690 :       else if (!strcmp (p, "no_parallelism"))
   48255                 :             :         {
   48256                 :          67 :           cp_lexer_consume_token (parser->lexer);
   48257                 :          67 :           if (no_parallelism)
   48258                 :          12 :             error_at (cloc, "too many %qs clauses", "no_parallelism");
   48259                 :             :           no_parallelism = true;
   48260                 :             :         }
   48261                 :         623 :       else if (!strcmp (p, "holds"))
   48262                 :             :         {
   48263                 :          66 :           cp_lexer_consume_token (parser->lexer);
   48264                 :          66 :           matching_parens parens;
   48265                 :          66 :           if (parens.require_open (parser))
   48266                 :             :             {
   48267                 :          66 :               location_t eloc = cp_lexer_peek_token (parser->lexer)->location;
   48268                 :          66 :               tree t = cp_parser_assignment_expression (parser);
   48269                 :          66 :               if (!type_dependent_expression_p (t))
   48270                 :          66 :                 t = contextual_conv_bool (t, tf_warning_or_error);
   48271                 :          66 :               if (is_assume && !error_operand_p (t))
   48272                 :          38 :                 finish_expr_stmt (build_assume_call (eloc, t));
   48273                 :          66 :               if (!parens.require_close (parser))
   48274                 :           0 :                 cp_parser_skip_to_closing_parenthesis (parser,
   48275                 :             :                                                        /*recovering=*/true,
   48276                 :             :                                                        /*or_comma=*/false,
   48277                 :             :                                                        /*consume_paren=*/true);
   48278                 :             :             }
   48279                 :             :         }
   48280                 :         557 :       else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
   48281                 :             :         {
   48282                 :         521 :           cp_lexer_consume_token (parser->lexer);
   48283                 :         521 :           matching_parens parens;
   48284                 :         521 :           if (parens.require_open (parser))
   48285                 :             :             {
   48286                 :        2127 :               do
   48287                 :             :                 {
   48288                 :        1324 :                   const char *directive[3] = {};
   48289                 :        1324 :                   int i;
   48290                 :        1324 :                   location_t dloc
   48291                 :        1324 :                     = cp_lexer_peek_token (parser->lexer)->location;
   48292                 :        3015 :                   for (i = 0; i < 3; i++)
   48293                 :             :                     {
   48294                 :        2883 :                       tree id;
   48295                 :        2883 :                       if (cp_lexer_nth_token_is (parser->lexer, i + 1, CPP_NAME))
   48296                 :        1648 :                         id = cp_lexer_peek_nth_token (parser->lexer,
   48297                 :             :                                                       i + 1)->u.value;
   48298                 :        1235 :                       else if (cp_lexer_nth_token_is (parser->lexer, i + 1,
   48299                 :             :                                                       CPP_KEYWORD))
   48300                 :             :                         {
   48301                 :          43 :                           enum rid rid
   48302                 :             :                             = cp_lexer_peek_nth_token (parser->lexer,
   48303                 :          43 :                                                        i + 1)->keyword;
   48304                 :          43 :                           id = ridpointers[rid];
   48305                 :             :                         }
   48306                 :             :                       else
   48307                 :             :                         break;
   48308                 :        1691 :                       directive[i] = IDENTIFIER_POINTER (id);
   48309                 :             :                     }
   48310                 :        1324 :                   if (i == 0)
   48311                 :           0 :                     error_at (dloc, "expected directive name");
   48312                 :             :                   else
   48313                 :             :                     {
   48314                 :        1324 :                       const struct c_omp_directive *dir
   48315                 :        1324 :                         = c_omp_categorize_directive (directive[0],
   48316                 :             :                                                       directive[1],
   48317                 :             :                                                       directive[2]);
   48318                 :        1324 :                       if (dir == NULL
   48319                 :        1312 :                           || dir->kind == C_OMP_DIR_DECLARATIVE
   48320                 :        1300 :                           || dir->kind == C_OMP_DIR_INFORMATIONAL
   48321                 :        1252 :                           || dir->id == PRAGMA_OMP_END
   48322                 :        1252 :                           || (!dir->second && directive[1])
   48323                 :        1216 :                           || (!dir->third && directive[2]))
   48324                 :         108 :                         error_at (dloc, "unknown OpenMP directive name in "
   48325                 :             :                                         "%qs clause argument", p);
   48326                 :             :                       else
   48327                 :             :                         {
   48328                 :        1216 :                           int id = dir - c_omp_directives;
   48329                 :        1383 :                           if (bitmap_bit_p (p[0] == 'a' ? &contains_head
   48330                 :             :                                                         : &absent_head, id))
   48331                 :          72 :                             error_at (dloc, "%<%s%s%s%s%s%> directive "
   48332                 :             :                                             "mentioned in both %<absent%> and "
   48333                 :             :                                             "%<contains%> clauses",
   48334                 :             :                                       directive[0],
   48335                 :             :                                       directive[1] ? " " : "",
   48336                 :             :                                       directive[1] ? directive[1] : "",
   48337                 :             :                                       directive[2] ? " " : "",
   48338                 :             :                                       directive[2] ? directive[2] : "");
   48339                 :        1347 :                           else if (!bitmap_set_bit (p[0] == 'a'
   48340                 :             :                                                     ? &absent_head
   48341                 :             :                                                     : &contains_head, id))
   48342                 :         144 :                             error_at (dloc, "%<%s%s%s%s%s%> directive "
   48343                 :             :                                             "mentioned multiple times in %qs "
   48344                 :             :                                             "clauses",
   48345                 :             :                                       directive[0],
   48346                 :             :                                       directive[1] ? " " : "",
   48347                 :             :                                       directive[1] ? directive[1] : "",
   48348                 :             :                                       directive[2] ? " " : "",
   48349                 :             :                                       directive[2] ? directive[2] : "", p);
   48350                 :             :                         }
   48351                 :        3015 :                       for (; i; --i)
   48352                 :        1691 :                         cp_lexer_consume_token (parser->lexer);
   48353                 :             :                     }
   48354                 :        1324 :                   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   48355                 :         803 :                     cp_lexer_consume_token (parser->lexer);
   48356                 :             :                   else
   48357                 :             :                     break;
   48358                 :         803 :                 }
   48359                 :             :               while (1);
   48360                 :         521 :               if (!parens.require_close (parser))
   48361                 :           0 :                 cp_parser_skip_to_closing_parenthesis (parser,
   48362                 :             :                                                        /*recovering=*/true,
   48363                 :             :                                                        /*or_comma=*/false,
   48364                 :             :                                                        /*consume_paren=*/true);
   48365                 :             :             }
   48366                 :         521 :         }
   48367                 :          36 :       else if (startswith (p, "ext_"))
   48368                 :             :         {
   48369                 :          24 :           warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
   48370                 :          24 :           cp_lexer_consume_token (parser->lexer);
   48371                 :          24 :           if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   48372                 :         120 :             for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1;
   48373                 :         120 :                  n; --n)
   48374                 :         108 :               cp_lexer_consume_token (parser->lexer);
   48375                 :             :         }
   48376                 :             :       else
   48377                 :             :         {
   48378                 :          12 :           cp_lexer_consume_token (parser->lexer);
   48379                 :          12 :           error_at (cloc, "expected assumption clause");
   48380                 :          12 :           break;
   48381                 :             :         }
   48382                 :             :     }
   48383                 :         458 :   cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   48384                 :         458 : }
   48385                 :             : 
   48386                 :             : /* OpenMP 5.1
   48387                 :             :    # pragma omp assume clauses[optseq] new-line  */
   48388                 :             : 
   48389                 :             : static void
   48390                 :         156 : cp_parser_omp_assume (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   48391                 :             : {
   48392                 :         156 :   cp_parser_omp_assumption_clauses (parser, pragma_tok, true);
   48393                 :         156 :   add_stmt (cp_parser_omp_structured_block (parser, if_p));
   48394                 :         156 : }
   48395                 :             : 
   48396                 :             : /* OpenMP 5.1
   48397                 :             :    # pragma omp assumes clauses[optseq] new-line  */
   48398                 :             : 
   48399                 :             : static bool
   48400                 :         140 : cp_parser_omp_assumes (cp_parser *parser, cp_token *pragma_tok)
   48401                 :             : {
   48402                 :           0 :   cp_parser_omp_assumption_clauses (parser, pragma_tok, false);
   48403                 :         140 :   return false;
   48404                 :             : }
   48405                 :             : 
   48406                 :             : /* Finalize #pragma omp declare variant after a fndecl has been parsed, and put
   48407                 :             :    that into "omp declare variant base" attribute.  */
   48408                 :             : 
   48409                 :             : static tree
   48410                 :        1409 : cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
   48411                 :             :                                tree attrs)
   48412                 :             : {
   48413                 :        1409 :   matching_parens parens;
   48414                 :        1409 :   if (!parens.require_open (parser))
   48415                 :             :     {
   48416                 :          12 :      fail:
   48417                 :         177 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   48418                 :         177 :       return attrs;
   48419                 :             :     }
   48420                 :             : 
   48421                 :        1397 :   bool template_p;
   48422                 :        1397 :   cp_id_kind idk = CP_ID_KIND_NONE;
   48423                 :        1397 :   cp_token *varid_token = cp_lexer_peek_token (parser->lexer);
   48424                 :        1397 :   cp_expr varid
   48425                 :        1397 :     = cp_parser_id_expression (parser, /*template_keyword_p=*/false,
   48426                 :             :                                /*check_dependency_p=*/true,
   48427                 :             :                                /*template_p=*/&template_p,
   48428                 :             :                                /*declarator_p=*/false,
   48429                 :             :                                /*optional_p=*/false);
   48430                 :        1397 :   parens.require_close (parser);
   48431                 :             : 
   48432                 :        1397 :   tree variant;
   48433                 :        1397 :   if (TREE_CODE (varid) == TEMPLATE_ID_EXPR
   48434                 :        1365 :       || TREE_CODE (varid) == TYPE_DECL
   48435                 :        2762 :       || varid == error_mark_node)
   48436                 :             :     variant = varid;
   48437                 :        1349 :   else if (varid_token->type == CPP_NAME && varid_token->error_reported)
   48438                 :             :     variant = NULL_TREE;
   48439                 :             :   else
   48440                 :             :     {
   48441                 :        1349 :       tree ambiguous_decls;
   48442                 :        1349 :       variant = cp_parser_lookup_name (parser, varid, none_type,
   48443                 :             :                                        template_p, /*is_namespace=*/false,
   48444                 :             :                                        /*check_dependency=*/true,
   48445                 :             :                                        &ambiguous_decls,
   48446                 :             :                                        varid.get_location ());
   48447                 :        1349 :       if (ambiguous_decls)
   48448                 :           0 :         variant = NULL_TREE;
   48449                 :             :     }
   48450                 :        1397 :   if (variant == NULL_TREE)
   48451                 :           0 :     variant = error_mark_node;
   48452                 :        1397 :   else if (TREE_CODE (variant) != SCOPE_REF)
   48453                 :             :     {
   48454                 :        1397 :       const char *error_msg;
   48455                 :        1397 :       variant
   48456                 :        1397 :         = finish_id_expression (varid, variant, parser->scope,
   48457                 :             :                                 &idk, false, true,
   48458                 :             :                                 &parser->non_integral_constant_expression_p,
   48459                 :             :                                 template_p, true, false, false, &error_msg,
   48460                 :             :                                 varid.get_location ());
   48461                 :        1397 :       if (error_msg)
   48462                 :           0 :         cp_parser_error (parser, error_msg);
   48463                 :             :     }
   48464                 :        1397 :   location_t caret_loc = get_pure_location (varid.get_location ());
   48465                 :        1397 :   location_t start_loc = get_start (varid_token->location);
   48466                 :        1397 :   location_t finish_loc = get_finish (varid.get_location ());
   48467                 :        1397 :   location_t varid_loc = make_location (caret_loc, start_loc, finish_loc);
   48468                 :             : 
   48469                 :        1397 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   48470                 :        1397 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   48471                 :          20 :     cp_lexer_consume_token (parser->lexer);
   48472                 :             : 
   48473                 :        1397 :   const char *clause = "";
   48474                 :        1397 :   location_t match_loc = cp_lexer_peek_token (parser->lexer)->location;
   48475                 :        1397 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   48476                 :        1377 :     clause = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
   48477                 :        1397 :   if (strcmp (clause, "match"))
   48478                 :             :     {
   48479                 :          24 :       cp_parser_error (parser, "expected %<match%>");
   48480                 :          24 :       goto fail;
   48481                 :             :     }
   48482                 :             : 
   48483                 :        1373 :   cp_lexer_consume_token (parser->lexer);
   48484                 :             : 
   48485                 :        1373 :   if (!parens.require_open (parser))
   48486                 :           4 :     goto fail;
   48487                 :             : 
   48488                 :        1369 :   tree ctx = cp_parser_omp_context_selector_specification (parser, true);
   48489                 :        1369 :   if (ctx == error_mark_node)
   48490                 :         137 :     goto fail;
   48491                 :        1232 :   ctx = omp_check_context_selector (match_loc, ctx);
   48492                 :        1232 :   if (ctx != error_mark_node && variant != error_mark_node)
   48493                 :             :     {
   48494                 :        1192 :       tree match_loc_node = maybe_wrap_with_location (integer_zero_node,
   48495                 :             :                                                       match_loc);
   48496                 :        1192 :       tree loc_node = maybe_wrap_with_location (integer_zero_node, varid_loc);
   48497                 :        1192 :       loc_node = tree_cons (match_loc_node,
   48498                 :             :                             build_int_cst (integer_type_node, idk),
   48499                 :             :                             build_tree_list (loc_node, integer_zero_node));
   48500                 :        1192 :       attrs = tree_cons (get_identifier ("omp declare variant base"),
   48501                 :             :                          tree_cons (variant, ctx, loc_node), attrs);
   48502                 :        1192 :       if (processing_template_decl)
   48503                 :          52 :         ATTR_IS_DEPENDENT (attrs) = 1;
   48504                 :             :     }
   48505                 :             : 
   48506                 :        1232 :   parens.require_close (parser);
   48507                 :        1232 :   cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   48508                 :        1232 :   return attrs;
   48509                 :             : }
   48510                 :             : 
   48511                 :             : 
   48512                 :             : /* Finalize #pragma omp declare simd clauses after direct declarator has
   48513                 :             :    been parsed, and put that into "omp declare simd" attribute.  */
   48514                 :             : 
   48515                 :             : static tree
   48516                 :        2430 : cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
   48517                 :             : {
   48518                 :        2430 :   struct cp_token_cache *ce;
   48519                 :        2430 :   cp_omp_declare_simd_data *data = parser->omp_declare_simd;
   48520                 :        2430 :   int i;
   48521                 :             : 
   48522                 :        2430 :   if (!data->error_seen && data->fndecl_seen)
   48523                 :             :     {
   48524                 :           8 :       error ("%<#pragma omp declare %s%> not immediately followed by "
   48525                 :             :              "a single function declaration or definition",
   48526                 :           8 :              data->variant_p ? "variant" : "simd");
   48527                 :           8 :       data->error_seen = true;
   48528                 :             :     }
   48529                 :        2430 :   if (data->error_seen)
   48530                 :             :     return attrs;
   48531                 :             : 
   48532                 :        4866 :   FOR_EACH_VEC_ELT (data->tokens, i, ce)
   48533                 :             :     {
   48534                 :        2444 :       tree c, cl;
   48535                 :             : 
   48536                 :        2444 :       cp_parser_push_lexer_for_tokens (parser, ce);
   48537                 :        2444 :       parser->lexer->in_pragma = true;
   48538                 :        2444 :       gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);
   48539                 :        2444 :       cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
   48540                 :        2444 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   48541                 :        2444 :       const char *kind = IDENTIFIER_POINTER (id);
   48542                 :        2444 :       cp_lexer_consume_token (parser->lexer);
   48543                 :        2444 :       if (strcmp (kind, "simd") == 0)
   48544                 :             :         {
   48545                 :        1059 :           cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
   48546                 :             :                                           "#pragma omp declare simd",
   48547                 :             :                                           pragma_tok);
   48548                 :        1059 :           if (cl)
   48549                 :         893 :             cl = tree_cons (NULL_TREE, cl, NULL_TREE);
   48550                 :        1059 :           c = build_tree_list (get_identifier ("omp declare simd"), cl);
   48551                 :        1059 :           TREE_CHAIN (c) = attrs;
   48552                 :        1059 :           if (processing_template_decl)
   48553                 :         176 :             ATTR_IS_DEPENDENT (c) = 1;
   48554                 :             :           attrs = c;
   48555                 :             :         }
   48556                 :             :       else
   48557                 :             :         {
   48558                 :        1385 :           gcc_assert (strcmp (kind, "variant") == 0);
   48559                 :        1385 :           attrs
   48560                 :        1385 :             = cp_finish_omp_declare_variant (parser, pragma_tok, attrs);
   48561                 :             :         }
   48562                 :        2444 :       cp_parser_pop_lexer (parser);
   48563                 :             :     }
   48564                 :             : 
   48565                 :             :   cp_lexer *lexer = NULL;
   48566                 :        7266 :   for (int i = 0; i < 2; i++)
   48567                 :             :     {
   48568                 :        4844 :       if (data->attribs[i] == NULL)
   48569                 :        4628 :         continue;
   48570                 :         534 :       for (tree *pa = data->attribs[i]; *pa; )
   48571                 :         318 :         if (get_attribute_namespace (*pa) == omp_identifier
   48572                 :         318 :             && is_attribute_p ("directive", get_attribute_name (*pa)))
   48573                 :             :           {
   48574                 :         636 :             for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
   48575                 :             :               {
   48576                 :         324 :                 tree d = TREE_VALUE (a);
   48577                 :         324 :                 gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
   48578                 :         324 :                 cp_token *first = DEFPARSE_TOKENS (d)->first;
   48579                 :         324 :                 cp_token *last = DEFPARSE_TOKENS (d)->last;
   48580                 :         324 :                 const char *directive[3] = {};
   48581                 :        1002 :                 for (int j = 0; j < 3; j++)
   48582                 :             :                   {
   48583                 :         924 :                     tree id = NULL_TREE;
   48584                 :         924 :                     if (first + j == last)
   48585                 :             :                       break;
   48586                 :         822 :                     if (first[j].type == CPP_NAME)
   48587                 :         678 :                       id = first[j].u.value;
   48588                 :         144 :                     else if (first[j].type == CPP_KEYWORD)
   48589                 :           0 :                       id = ridpointers[(int) first[j].keyword];
   48590                 :             :                     else
   48591                 :             :                       break;
   48592                 :         678 :                     directive[j] = IDENTIFIER_POINTER (id);
   48593                 :             :                   }
   48594                 :         324 :                 const c_omp_directive *dir = NULL;
   48595                 :         324 :                 if (directive[0])
   48596                 :         324 :                   dir = c_omp_categorize_directive (directive[0], directive[1],
   48597                 :             :                                                     directive[2]);
   48598                 :         324 :                 if (dir == NULL)
   48599                 :             :                   {
   48600                 :          24 :                     error_at (first->location,
   48601                 :             :                               "unknown OpenMP directive name in "
   48602                 :             :                               "%qs attribute argument",
   48603                 :          24 :                               TREE_PUBLIC (d)
   48604                 :             :                               ? "omp::decl" : "omp::directive");
   48605                 :          48 :                     continue;
   48606                 :             :                   }
   48607                 :         300 :                 if (dir->id != PRAGMA_OMP_DECLARE
   48608                 :         276 :                     || (strcmp (directive[1], "simd") != 0
   48609                 :          24 :                         && strcmp (directive[1], "variant") != 0))
   48610                 :             :                   {
   48611                 :          24 :                     error_at (first->location,
   48612                 :             :                               "OpenMP directive other than %<declare simd%> "
   48613                 :             :                               "or %<declare variant%> appertains to a "
   48614                 :             :                               "declaration");
   48615                 :          24 :                     continue;
   48616                 :             :                   }
   48617                 :             : 
   48618                 :         276 :                 if (parser->omp_attrs_forbidden_p)
   48619                 :             :                   {
   48620                 :           6 :                     error_at (first->location,
   48621                 :             :                               "mixing OpenMP directives with attribute and "
   48622                 :             :                               "pragma syntax on the same statement");
   48623                 :           6 :                     parser->omp_attrs_forbidden_p = false;
   48624                 :             :                   }
   48625                 :             : 
   48626                 :         276 :                 if (!flag_openmp && strcmp (directive[1], "simd") != 0)
   48627                 :           0 :                   continue;
   48628                 :         276 :                 if (lexer == NULL)
   48629                 :             :                   {
   48630                 :         198 :                     lexer = cp_lexer_alloc ();
   48631                 :         198 :                     lexer->debugging_p = parser->lexer->debugging_p;
   48632                 :             :                   }
   48633                 :         276 :                 vec_safe_reserve (lexer->buffer, (last - first) + 2);
   48634                 :         276 :                 cp_token tok = {};
   48635                 :         276 :                 tok.type = CPP_PRAGMA;
   48636                 :         276 :                 tok.keyword = RID_MAX;
   48637                 :         276 :                 tok.u.value = build_int_cst (NULL, PRAGMA_OMP_DECLARE);
   48638                 :         276 :                 tok.location = first->location;
   48639                 :         276 :                 lexer->buffer->quick_push (tok);
   48640                 :        2871 :                 while (++first < last)
   48641                 :        2319 :                   lexer->buffer->quick_push (*first);
   48642                 :         276 :                 tok = {};
   48643                 :         276 :                 tok.type = CPP_PRAGMA_EOL;
   48644                 :         276 :                 tok.keyword = RID_MAX;
   48645                 :         276 :                 tok.location = last->location;
   48646                 :         276 :                 lexer->buffer->quick_push (tok);
   48647                 :         276 :                 tok = {};
   48648                 :         276 :                 tok.type = CPP_EOF;
   48649                 :         276 :                 tok.keyword = RID_MAX;
   48650                 :         276 :                 tok.location = last->location;
   48651                 :         276 :                 lexer->buffer->quick_push (tok);
   48652                 :         276 :                 lexer->next = parser->lexer;
   48653                 :         276 :                 lexer->next_token = lexer->buffer->address ();
   48654                 :         276 :                 lexer->last_token = lexer->next_token
   48655                 :         276 :                                     + lexer->buffer->length ()
   48656                 :         276 :                       - 1;
   48657                 :         276 :                 lexer->in_omp_attribute_pragma = true;
   48658                 :         276 :                 parser->lexer = lexer;
   48659                 :             :                 /* Move the current source position to that of the first token
   48660                 :             :                    in the new lexer.  */
   48661                 :         276 :                 cp_lexer_set_source_position_from_token (lexer->next_token);
   48662                 :             : 
   48663                 :         276 :                 cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
   48664                 :         276 :                 tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   48665                 :         276 :                 const char *kind = IDENTIFIER_POINTER (id);
   48666                 :         276 :                 cp_lexer_consume_token (parser->lexer);
   48667                 :             : 
   48668                 :         276 :                 tree c, cl;
   48669                 :         276 :                 if (strcmp (kind, "simd") == 0)
   48670                 :             :                   {
   48671                 :         252 :                     if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   48672                 :         252 :                         && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   48673                 :          96 :                       cp_lexer_consume_token (parser->lexer);
   48674                 :             : 
   48675                 :         252 :                     omp_clause_mask mask = OMP_DECLARE_SIMD_CLAUSE_MASK;
   48676                 :         252 :                     cl = cp_parser_omp_all_clauses (parser, mask,
   48677                 :             :                                                     "#pragma omp declare simd",
   48678                 :             :                                                     pragma_tok);
   48679                 :         252 :                     if (cl)
   48680                 :         174 :                       cl = tree_cons (NULL_TREE, cl, NULL_TREE);
   48681                 :         252 :                     c = build_tree_list (get_identifier ("omp declare simd"),
   48682                 :             :                                          cl);
   48683                 :         252 :                     TREE_CHAIN (c) = attrs;
   48684                 :         252 :                     if (processing_template_decl)
   48685                 :           0 :                       ATTR_IS_DEPENDENT (c) = 1;
   48686                 :         252 :                     attrs = c;
   48687                 :             :                   }
   48688                 :             :                 else
   48689                 :             :                   {
   48690                 :          24 :                     gcc_assert (strcmp (kind, "variant") == 0);
   48691                 :          24 :                     attrs
   48692                 :          24 :                       = cp_finish_omp_declare_variant (parser, pragma_tok,
   48693                 :             :                                                        attrs);
   48694                 :             :                   }
   48695                 :         276 :                 gcc_assert (parser->lexer != lexer);
   48696                 :         552 :                 vec_safe_truncate (lexer->buffer, 0);
   48697                 :             :               }
   48698                 :         312 :             *pa = TREE_CHAIN (*pa);
   48699                 :             :           }
   48700                 :             :         else
   48701                 :           6 :           pa = &TREE_CHAIN (*pa);
   48702                 :             :     }
   48703                 :        2422 :   if (lexer)
   48704                 :         198 :     cp_lexer_destroy (lexer);
   48705                 :             : 
   48706                 :        2422 :   data->fndecl_seen = true;
   48707                 :        2422 :   return attrs;
   48708                 :             : }
   48709                 :             : 
   48710                 :             : /* D should be DEFERRED_PARSE from omp::decl attribute.  If it contains
   48711                 :             :    a threadprivate, groupprivate, allocate or declare target directive,
   48712                 :             :    return true and parse it for DECL.  */
   48713                 :             : 
   48714                 :             : bool
   48715                 :         117 : cp_maybe_parse_omp_decl (tree decl, tree d)
   48716                 :             : {
   48717                 :         117 :   gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
   48718                 :         117 :   cp_token *first = DEFPARSE_TOKENS (d)->first;
   48719                 :         117 :   cp_token *last = DEFPARSE_TOKENS (d)->last;
   48720                 :         117 :   const char *directive[3] = {};
   48721                 :         345 :   for (int j = 0; j < 3; j++)
   48722                 :             :     {
   48723                 :         306 :       tree id = NULL_TREE;
   48724                 :         306 :       if (first + j == last)
   48725                 :             :         break;
   48726                 :         246 :       if (first[j].type == CPP_NAME)
   48727                 :         228 :         id = first[j].u.value;
   48728                 :          18 :       else if (first[j].type == CPP_KEYWORD)
   48729                 :           0 :         id = ridpointers[(int) first[j].keyword];
   48730                 :             :       else
   48731                 :             :         break;
   48732                 :         228 :       directive[j] = IDENTIFIER_POINTER (id);
   48733                 :             :     }
   48734                 :         117 :   const c_omp_directive *dir = NULL;
   48735                 :         117 :   if (directive[0])
   48736                 :         117 :     dir = c_omp_categorize_directive (directive[0], directive[1],
   48737                 :             :                                       directive[2]);
   48738                 :         117 :   if (dir == NULL)
   48739                 :             :     {
   48740                 :           3 :       error_at (first->location,
   48741                 :             :                 "unknown OpenMP directive name in "
   48742                 :             :                 "%qs attribute argument", "omp::decl");
   48743                 :           3 :       return false;
   48744                 :             :     }
   48745                 :         114 :   if (dir->id != PRAGMA_OMP_THREADPRIVATE
   48746                 :             :       /* && dir->id != PRAGMA_OMP_GROUPPRIVATE */
   48747                 :          69 :       && dir->id != PRAGMA_OMP_ALLOCATE
   48748                 :          69 :       && (dir->id != PRAGMA_OMP_DECLARE
   48749                 :          69 :           || strcmp (directive[1], "target") != 0))
   48750                 :             :     return false;
   48751                 :             : 
   48752                 :         114 :   if (!flag_openmp && !dir->simd)
   48753                 :             :     return true;
   48754                 :             : 
   48755                 :         114 :   cp_parser *parser = the_parser;
   48756                 :         114 :   cp_lexer *lexer = cp_lexer_alloc ();
   48757                 :         114 :   lexer->debugging_p = parser->lexer->debugging_p;
   48758                 :         114 :   lexer->in_omp_decl_attribute = decl;
   48759                 :         114 :   vec_safe_reserve (lexer->buffer, last - first + 3, true);
   48760                 :         114 :   cp_token tok = {};
   48761                 :         114 :   tok.type = CPP_PRAGMA;
   48762                 :         114 :   tok.keyword = RID_MAX;
   48763                 :         114 :   tok.u.value = build_int_cst (NULL, dir->id);
   48764                 :         114 :   tok.location = first->location;
   48765                 :         114 :   lexer->buffer->quick_push (tok);
   48766                 :         492 :   while (++first < last)
   48767                 :         264 :     lexer->buffer->quick_push (*first);
   48768                 :         114 :   tok = {};
   48769                 :         114 :   tok.type = CPP_PRAGMA_EOL;
   48770                 :         114 :   tok.keyword = RID_MAX;
   48771                 :         114 :   tok.location = last->location;
   48772                 :         114 :   lexer->buffer->quick_push (tok);
   48773                 :         114 :   tok = {};
   48774                 :         114 :   tok.type = CPP_EOF;
   48775                 :         114 :   tok.keyword = RID_MAX;
   48776                 :         114 :   tok.location = last->location;
   48777                 :         114 :   lexer->buffer->quick_push (tok);
   48778                 :         114 :   lexer->next = parser->lexer;
   48779                 :         114 :   lexer->next_token = lexer->buffer->address ();
   48780                 :         114 :   lexer->last_token = lexer->next_token
   48781                 :         114 :                       + lexer->buffer->length ()
   48782                 :         114 :                       - 1;
   48783                 :         114 :   lexer->in_omp_attribute_pragma = true;
   48784                 :         114 :   parser->lexer = lexer;
   48785                 :             :   /* Move the current source position to that of the first token in the
   48786                 :             :      new lexer.  */
   48787                 :         114 :   cp_lexer_set_source_position_from_token (lexer->next_token);
   48788                 :         114 :   cp_parser_pragma (parser, pragma_external, NULL);
   48789                 :             : 
   48790                 :         114 :   return true;
   48791                 :             : }
   48792                 :             : 
   48793                 :             : /* Helper for cp_parser_omp_declare_target, handle one to or link clause
   48794                 :             :    on #pragma omp declare target.  Return false if errors were reported.  */
   48795                 :             : 
   48796                 :             : static bool
   48797                 :         639 : handle_omp_declare_target_clause (tree c, tree t, int device_type,
   48798                 :             :                                   bool indirect)
   48799                 :             : {
   48800                 :         639 :   tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
   48801                 :         639 :   tree at2 = lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t));
   48802                 :         639 :   tree id;
   48803                 :         639 :   if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
   48804                 :             :     {
   48805                 :          76 :       id = get_identifier ("omp declare target link");
   48806                 :          76 :       std::swap (at1, at2);
   48807                 :             :     }
   48808                 :             :   else
   48809                 :         563 :     id = get_identifier ("omp declare target");
   48810                 :         639 :   if (at2)
   48811                 :             :     {
   48812                 :          24 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
   48813                 :          12 :         error_at (OMP_CLAUSE_LOCATION (c),
   48814                 :             :                   "%qD specified both in declare target %<link%> and %qs"
   48815                 :          12 :                   " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
   48816                 :             :       else
   48817                 :          12 :         error_at (OMP_CLAUSE_LOCATION (c),
   48818                 :             :                   "%qD specified both in declare target %<link%> and "
   48819                 :             :                   "%<to%> or %<enter%> clauses", t);
   48820                 :          24 :       return false;
   48821                 :             :     }
   48822                 :         615 :   if (!at1)
   48823                 :             :     {
   48824                 :         473 :       DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   48825                 :         473 :       if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
   48826                 :             :         return true;
   48827                 :             : 
   48828                 :         469 :       symtab_node *node = symtab_node::get (t);
   48829                 :         469 :       if (node != NULL)
   48830                 :             :         {
   48831                 :         295 :           node->offloadable = 1;
   48832                 :         295 :           if (ENABLE_OFFLOADING)
   48833                 :             :             {
   48834                 :             :               g->have_offload = true;
   48835                 :             :               if (is_a <varpool_node *> (node))
   48836                 :             :                 vec_safe_push (offload_vars, t);
   48837                 :             :             }
   48838                 :             :         }
   48839                 :             :     }
   48840                 :         611 :   if (TREE_CODE (t) != FUNCTION_DECL)
   48841                 :             :     return true;
   48842                 :         269 :   if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
   48843                 :             :     {
   48844                 :          51 :       tree at3 = lookup_attribute ("omp declare target host",
   48845                 :          51 :                                    DECL_ATTRIBUTES (t));
   48846                 :          51 :       if (at3 == NULL_TREE)
   48847                 :             :         {
   48848                 :          43 :           id = get_identifier ("omp declare target host");
   48849                 :          43 :           DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   48850                 :             :         }
   48851                 :             :     }
   48852                 :         269 :   if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
   48853                 :             :     {
   48854                 :          48 :       tree at3 = lookup_attribute ("omp declare target nohost",
   48855                 :          48 :                                    DECL_ATTRIBUTES (t));
   48856                 :          48 :       if (at3 == NULL_TREE)
   48857                 :             :         {
   48858                 :          40 :           id = get_identifier ("omp declare target nohost");
   48859                 :          40 :           DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   48860                 :             :         }
   48861                 :             :     }
   48862                 :         269 :   if (indirect)
   48863                 :             :     {
   48864                 :          50 :       tree at4 = lookup_attribute ("omp declare target indirect",
   48865                 :          50 :                                    DECL_ATTRIBUTES (t));
   48866                 :          50 :       if (at4 == NULL_TREE)
   48867                 :             :         {
   48868                 :          50 :           id = get_identifier ("omp declare target indirect");
   48869                 :          50 :           DECL_ATTRIBUTES (t)
   48870                 :         100 :             = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   48871                 :             :         }
   48872                 :             :     }
   48873                 :             :   return true;
   48874                 :             : }
   48875                 :             : 
   48876                 :             : /* OpenMP 4.0:
   48877                 :             :    # pragma omp declare target new-line
   48878                 :             :    declarations and definitions
   48879                 :             :    # pragma omp end declare target new-line
   48880                 :             : 
   48881                 :             :    OpenMP 4.5:
   48882                 :             :    # pragma omp declare target ( extended-list ) new-line
   48883                 :             : 
   48884                 :             :    # pragma omp declare target declare-target-clauses[seq] new-line  */
   48885                 :             : 
   48886                 :             : #define OMP_DECLARE_TARGET_CLAUSE_MASK                          \
   48887                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)             \
   48888                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER)  \
   48889                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)           \
   48890                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)    \
   48891                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
   48892                 :             : 
   48893                 :             : static void
   48894                 :         781 : cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
   48895                 :             : {
   48896                 :         781 :   tree clauses = NULL_TREE;
   48897                 :         781 :   int device_type = 0;
   48898                 :         781 :   bool indirect = false;
   48899                 :         781 :   bool only_device_type_or_indirect = true;
   48900                 :         781 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
   48901                 :         781 :       || (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   48902                 :          19 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)))
   48903                 :         472 :     clauses
   48904                 :         472 :       = cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
   48905                 :             :                                    "#pragma omp declare target", pragma_tok);
   48906                 :         309 :   else if (parser->lexer->in_omp_decl_attribute
   48907                 :         309 :            || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   48908                 :             :     {
   48909                 :          72 :       clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER,
   48910                 :             :                                         clauses);
   48911                 :          72 :       clauses = finish_omp_clauses (clauses, C_ORT_OMP);
   48912                 :          72 :       cp_parser_require_pragma_eol (parser, pragma_tok);
   48913                 :             :     }
   48914                 :             :   else
   48915                 :             :     {
   48916                 :         237 :       cp_omp_declare_target_attr a
   48917                 :         237 :         = { parser->lexer->in_omp_attribute_pragma, -1, false };
   48918                 :         237 :       vec_safe_push (scope_chain->omp_declare_target_attribute, a);
   48919                 :         237 :       cp_parser_require_pragma_eol (parser, pragma_tok);
   48920                 :         237 :       return;
   48921                 :             :     }
   48922                 :        1352 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   48923                 :             :     {
   48924                 :         808 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
   48925                 :          97 :         device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
   48926                 :         808 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
   48927                 :          80 :         indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
   48928                 :             :     }
   48929                 :        1352 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   48930                 :             :     {
   48931                 :         808 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
   48932                 :         808 :           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
   48933                 :         177 :         continue;
   48934                 :         631 :       tree t = OMP_CLAUSE_DECL (c);
   48935                 :         631 :       only_device_type_or_indirect = false;
   48936                 :         631 :       if (!handle_omp_declare_target_clause (c, t, device_type, indirect))
   48937                 :          24 :         continue;
   48938                 :         269 :       if (VAR_OR_FUNCTION_DECL_P (t)
   48939                 :         607 :           && DECL_LOCAL_DECL_P (t)
   48940                 :           8 :           && DECL_LANG_SPECIFIC (t)
   48941                 :           8 :           && DECL_LOCAL_DECL_ALIAS (t)
   48942                 :         615 :           && DECL_LOCAL_DECL_ALIAS (t) != error_mark_node)
   48943                 :           8 :         handle_omp_declare_target_clause (c, DECL_LOCAL_DECL_ALIAS (t),
   48944                 :             :                                           device_type, indirect);
   48945                 :             :     }
   48946                 :         544 :   if ((device_type || indirect) && only_device_type_or_indirect)
   48947                 :          17 :     error_at (OMP_CLAUSE_LOCATION (clauses),
   48948                 :             :               "directive with only %<device_type%> or %<indirect%> clauses");
   48949                 :         544 :   if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
   48950                 :           4 :     error_at (OMP_CLAUSE_LOCATION (clauses),
   48951                 :             :               "%<device_type%> clause must specify 'any' when used with "
   48952                 :             :               "an %<indirect%> clause");
   48953                 :             : }
   48954                 :             : 
   48955                 :             : /* OpenMP 5.1
   48956                 :             :    # pragma omp begin assumes clauses[optseq] new-line
   48957                 :             : 
   48958                 :             :    # pragma omp begin declare target clauses[optseq] new-line  */
   48959                 :             : 
   48960                 :             : #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK                    \
   48961                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)    \
   48962                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
   48963                 :             : 
   48964                 :             : static void
   48965                 :         305 : cp_parser_omp_begin (cp_parser *parser, cp_token *pragma_tok)
   48966                 :             : {
   48967                 :         305 :   const char *p = "";
   48968                 :         305 :   bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
   48969                 :         305 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   48970                 :             :     {
   48971                 :         305 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   48972                 :         305 :       p = IDENTIFIER_POINTER (id);
   48973                 :             :     }
   48974                 :         305 :   if (strcmp (p, "declare") == 0)
   48975                 :             :     {
   48976                 :         143 :       cp_lexer_consume_token (parser->lexer);
   48977                 :         143 :       p = "";
   48978                 :         143 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   48979                 :             :         {
   48980                 :         143 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   48981                 :         143 :           p = IDENTIFIER_POINTER (id);
   48982                 :             :         }
   48983                 :         143 :       if (strcmp (p, "target") == 0)
   48984                 :             :         {
   48985                 :         143 :           cp_lexer_consume_token (parser->lexer);
   48986                 :         143 :           tree clauses
   48987                 :         143 :             = cp_parser_omp_all_clauses (parser,
   48988                 :         143 :                                          OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
   48989                 :             :                                          "#pragma omp begin declare target",
   48990                 :             :                                          pragma_tok);
   48991                 :         143 :           int device_type = 0;
   48992                 :         143 :           bool indirect = 0;
   48993                 :         229 :           for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   48994                 :             :             {
   48995                 :          86 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
   48996                 :          52 :                 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
   48997                 :          86 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
   48998                 :          34 :                 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
   48999                 :             :             }
   49000                 :         143 :           cp_omp_declare_target_attr a
   49001                 :         143 :             = { in_omp_attribute_pragma, device_type, indirect };
   49002                 :         143 :           vec_safe_push (scope_chain->omp_declare_target_attribute, a);
   49003                 :             :         }
   49004                 :             :       else
   49005                 :             :         {
   49006                 :           0 :           cp_parser_error (parser, "expected %<target%>");
   49007                 :           0 :           cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49008                 :             :         }
   49009                 :             :     }
   49010                 :         162 :   else if (strcmp (p, "assumes") == 0)
   49011                 :             :     {
   49012                 :         162 :       cp_lexer_consume_token (parser->lexer);
   49013                 :         162 :       cp_parser_omp_assumption_clauses (parser, pragma_tok, false);
   49014                 :         162 :       cp_omp_begin_assumes_data a = { in_omp_attribute_pragma };
   49015                 :         162 :       vec_safe_push (scope_chain->omp_begin_assumes, a);
   49016                 :             :     }
   49017                 :             :   else
   49018                 :             :     {
   49019                 :           0 :       cp_parser_error (parser, "expected %<declare target%> or %<assumes%>");
   49020                 :           0 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49021                 :             :     }
   49022                 :         305 : }
   49023                 :             : 
   49024                 :             : /* OpenMP 4.0:
   49025                 :             :    # pragma omp end declare target new-line
   49026                 :             : 
   49027                 :             :    OpenMP 5.1:
   49028                 :             :    # pragma omp end assumes new-line  */
   49029                 :             : 
   49030                 :             : static void
   49031                 :         534 : cp_parser_omp_end (cp_parser *parser, cp_token *pragma_tok)
   49032                 :             : {
   49033                 :         534 :   const char *p = "";
   49034                 :         534 :   bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
   49035                 :         534 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49036                 :             :     {
   49037                 :         534 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   49038                 :         534 :       p = IDENTIFIER_POINTER (id);
   49039                 :             :     }
   49040                 :         534 :   if (strcmp (p, "declare") == 0)
   49041                 :             :     {
   49042                 :         372 :       cp_lexer_consume_token (parser->lexer);
   49043                 :         372 :       p = "";
   49044                 :         372 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49045                 :             :         {
   49046                 :         372 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   49047                 :         372 :           p = IDENTIFIER_POINTER (id);
   49048                 :             :         }
   49049                 :         372 :       if (strcmp (p, "target") == 0)
   49050                 :         372 :         cp_lexer_consume_token (parser->lexer);
   49051                 :             :       else
   49052                 :             :         {
   49053                 :           0 :           cp_parser_error (parser, "expected %<target%>");
   49054                 :           0 :           cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49055                 :           0 :           return;
   49056                 :             :         }
   49057                 :         372 :       cp_parser_require_pragma_eol (parser, pragma_tok);
   49058                 :         372 :       if (!vec_safe_length (scope_chain->omp_declare_target_attribute))
   49059                 :           8 :         error_at (pragma_tok->location,
   49060                 :             :                   "%<#pragma omp end declare target%> without corresponding "
   49061                 :             :                   "%<#pragma omp declare target%> or "
   49062                 :             :                   "%<#pragma omp begin declare target%>");
   49063                 :             :       else
   49064                 :             :         {
   49065                 :         364 :           cp_omp_declare_target_attr
   49066                 :         364 :             a = scope_chain->omp_declare_target_attribute->pop ();
   49067                 :         364 :           if (a.attr_syntax != in_omp_attribute_pragma)
   49068                 :             :             {
   49069                 :          48 :               if (a.attr_syntax)
   49070                 :          36 :                 error_at (pragma_tok->location,
   49071                 :             :                           "%qs in attribute syntax terminated "
   49072                 :             :                           "with %qs in pragma syntax",
   49073                 :             :                           a.device_type >= 0 ? "begin declare target"
   49074                 :             :                                              : "declare target",
   49075                 :             :                           "end declare target");
   49076                 :             :               else
   49077                 :          36 :                 error_at (pragma_tok->location,
   49078                 :             :                           "%qs in pragma syntax terminated "
   49079                 :             :                           "with %qs in attribute syntax",
   49080                 :             :                           a.device_type >= 0 ? "begin declare target"
   49081                 :             :                                              : "declare target",
   49082                 :             :                           "end declare target");
   49083                 :             :             }
   49084                 :             :         }
   49085                 :             :     }
   49086                 :         162 :   else if (strcmp (p, "assumes") == 0)
   49087                 :             :     {
   49088                 :         162 :       cp_lexer_consume_token (parser->lexer);
   49089                 :         162 :       cp_parser_require_pragma_eol (parser, pragma_tok);
   49090                 :         162 :       if (!vec_safe_length (scope_chain->omp_begin_assumes))
   49091                 :           4 :         error_at (pragma_tok->location,
   49092                 :             :                   "%qs without corresponding %qs",
   49093                 :             :                   "#pragma omp end assumes", "#pragma omp begin assumes");
   49094                 :             :       else
   49095                 :             :         {
   49096                 :         158 :           cp_omp_begin_assumes_data
   49097                 :         158 :             a = scope_chain->omp_begin_assumes->pop ();
   49098                 :         158 :           if (a.attr_syntax != in_omp_attribute_pragma)
   49099                 :             :             {
   49100                 :          24 :               if (a.attr_syntax)
   49101                 :          12 :                 error_at (pragma_tok->location,
   49102                 :             :                           "%qs in attribute syntax terminated "
   49103                 :             :                           "with %qs in pragma syntax",
   49104                 :             :                           "begin assumes", "end assumes");
   49105                 :             :               else
   49106                 :          12 :                 error_at (pragma_tok->location,
   49107                 :             :                           "%qs in pragma syntax terminated "
   49108                 :             :                           "with %qs in attribute syntax",
   49109                 :             :                           "begin assumes", "end assumes");
   49110                 :             :             }
   49111                 :             :         }
   49112                 :             :     }
   49113                 :             :   else
   49114                 :             :     {
   49115                 :           0 :       cp_parser_error (parser, "expected %<declare%> or %<assumes%>");
   49116                 :           0 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49117                 :           0 :       return;
   49118                 :             :     }
   49119                 :             : }
   49120                 :             : 
   49121                 :             : /* Helper function of cp_parser_omp_declare_reduction.  Parse the combiner
   49122                 :             :    expression and optional initializer clause of
   49123                 :             :    #pragma omp declare reduction.  We store the expression(s) as
   49124                 :             :    either 3, 6 or 7 special statements inside of the artificial function's
   49125                 :             :    body.  The first two statements are DECL_EXPRs for the artificial
   49126                 :             :    OMP_OUT resp. OMP_IN variables, followed by a statement with the combiner
   49127                 :             :    expression that uses those variables.
   49128                 :             :    If there was any INITIALIZER clause, this is followed by further statements,
   49129                 :             :    the fourth and fifth statements are DECL_EXPRs for the artificial
   49130                 :             :    OMP_PRIV resp. OMP_ORIG variables.  If the INITIALIZER clause wasn't the
   49131                 :             :    constructor variant (first token after open paren is not omp_priv),
   49132                 :             :    then the sixth statement is a statement with the function call expression
   49133                 :             :    that uses the OMP_PRIV and optionally OMP_ORIG variable.
   49134                 :             :    Otherwise, the sixth statement is whatever statement cp_finish_decl emits
   49135                 :             :    to initialize the OMP_PRIV artificial variable and there is seventh
   49136                 :             :    statement, a DECL_EXPR of the OMP_PRIV statement again.  */
   49137                 :             : 
   49138                 :             : static bool
   49139                 :         918 : cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
   49140                 :             : {
   49141                 :         918 :   tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
   49142                 :         918 :   gcc_assert (TYPE_REF_P (type));
   49143                 :         918 :   type = TREE_TYPE (type);
   49144                 :         918 :   tree omp_out = build_lang_decl (VAR_DECL, get_identifier ("omp_out"), type);
   49145                 :         918 :   DECL_ARTIFICIAL (omp_out) = 1;
   49146                 :         918 :   pushdecl (omp_out);
   49147                 :         918 :   add_decl_expr (omp_out);
   49148                 :         918 :   tree omp_in = build_lang_decl (VAR_DECL, get_identifier ("omp_in"), type);
   49149                 :         918 :   DECL_ARTIFICIAL (omp_in) = 1;
   49150                 :         918 :   pushdecl (omp_in);
   49151                 :         918 :   add_decl_expr (omp_in);
   49152                 :         918 :   tree combiner;
   49153                 :         918 :   tree omp_priv = NULL_TREE, omp_orig = NULL_TREE, initializer = NULL_TREE;
   49154                 :             : 
   49155                 :         918 :   keep_next_level (true);
   49156                 :         918 :   tree block = begin_omp_structured_block ();
   49157                 :         918 :   combiner = cp_parser_expression (parser);
   49158                 :         918 :   finish_expr_stmt (combiner);
   49159                 :         918 :   block = finish_omp_structured_block (block);
   49160                 :         918 :   if (processing_template_decl)
   49161                 :         338 :     block = build_stmt (input_location, EXPR_STMT, block);
   49162                 :         918 :   add_stmt (block);
   49163                 :             : 
   49164                 :         918 :   if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
   49165                 :             :     return false;
   49166                 :             : 
   49167                 :         914 :   if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   49168                 :         914 :       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   49169                 :           7 :     cp_lexer_consume_token (parser->lexer);
   49170                 :             : 
   49171                 :         914 :   const char *p = "";
   49172                 :         914 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49173                 :             :     {
   49174                 :         363 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   49175                 :         363 :       p = IDENTIFIER_POINTER (id);
   49176                 :             :     }
   49177                 :             : 
   49178                 :         914 :   if (strcmp (p, "initializer") == 0)
   49179                 :             :     {
   49180                 :         363 :       cp_lexer_consume_token (parser->lexer);
   49181                 :         363 :       matching_parens parens;
   49182                 :         363 :       if (!parens.require_open (parser))
   49183                 :           8 :         return false;
   49184                 :             : 
   49185                 :         363 :       p = "";
   49186                 :         363 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49187                 :             :         {
   49188                 :         361 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   49189                 :         361 :           p = IDENTIFIER_POINTER (id);
   49190                 :             :         }
   49191                 :             : 
   49192                 :         363 :       omp_priv = build_lang_decl (VAR_DECL, get_identifier ("omp_priv"), type);
   49193                 :         363 :       DECL_ARTIFICIAL (omp_priv) = 1;
   49194                 :         363 :       pushdecl (omp_priv);
   49195                 :         363 :       add_decl_expr (omp_priv);
   49196                 :         363 :       omp_orig = build_lang_decl (VAR_DECL, get_identifier ("omp_orig"), type);
   49197                 :         363 :       DECL_ARTIFICIAL (omp_orig) = 1;
   49198                 :         363 :       pushdecl (omp_orig);
   49199                 :         363 :       add_decl_expr (omp_orig);
   49200                 :             : 
   49201                 :         363 :       keep_next_level (true);
   49202                 :         363 :       block = begin_omp_structured_block ();
   49203                 :             : 
   49204                 :         363 :       bool ctor = false;
   49205                 :         363 :       if (strcmp (p, "omp_priv") == 0)
   49206                 :             :         {
   49207                 :         208 :           bool is_non_constant_init;
   49208                 :         208 :           ctor = true;
   49209                 :         208 :           cp_lexer_consume_token (parser->lexer);
   49210                 :             :           /* Reject initializer (omp_priv) and initializer (omp_priv ()).  */
   49211                 :         208 :           if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
   49212                 :         208 :               || (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
   49213                 :          92 :                   && cp_lexer_peek_nth_token (parser->lexer, 2)->type
   49214                 :             :                      == CPP_CLOSE_PAREN
   49215                 :           4 :                   && cp_lexer_peek_nth_token (parser->lexer, 3)->type
   49216                 :             :                      == CPP_CLOSE_PAREN))
   49217                 :             :             {
   49218                 :           8 :               finish_omp_structured_block (block);
   49219                 :           8 :               error ("invalid initializer clause");
   49220                 :           8 :               return false;
   49221                 :             :             }
   49222                 :         200 :           initializer = cp_parser_initializer (parser,
   49223                 :             :                                                /*is_direct_init=*/nullptr,
   49224                 :             :                                                &is_non_constant_init);
   49225                 :         200 :           cp_finish_decl (omp_priv, initializer, !is_non_constant_init,
   49226                 :             :                           NULL_TREE, LOOKUP_ONLYCONVERTING);
   49227                 :             :         }
   49228                 :             :       else
   49229                 :             :         {
   49230                 :         155 :           cp_parser_parse_tentatively (parser);
   49231                 :             :           /* Don't create location wrapper nodes here.  */
   49232                 :         155 :           auto_suppress_location_wrappers sentinel;
   49233                 :         155 :           tree fn_name = cp_parser_id_expression (parser, /*template_p=*/false,
   49234                 :             :                                                   /*check_dependency_p=*/true,
   49235                 :             :                                                   /*template_p=*/NULL,
   49236                 :             :                                                   /*declarator_p=*/false,
   49237                 :             :                                                   /*optional_p=*/false);
   49238                 :         155 :           vec<tree, va_gc> *args;
   49239                 :         155 :           if (fn_name == error_mark_node
   49240                 :         155 :               || cp_parser_error_occurred (parser)
   49241                 :         155 :               || !cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
   49242                 :         155 :               || ((args = cp_parser_parenthesized_expression_list
   49243                 :         155 :                                 (parser, non_attr, /*cast_p=*/false,
   49244                 :             :                                  /*allow_expansion_p=*/true,
   49245                 :             :                                  /*non_constant_p=*/NULL)),
   49246                 :         163 :                   cp_parser_error_occurred (parser)))
   49247                 :             :             {
   49248                 :           0 :               finish_omp_structured_block (block);
   49249                 :           0 :               cp_parser_abort_tentative_parse (parser);
   49250                 :           0 :               cp_parser_error (parser, "expected id-expression (arguments)");
   49251                 :           0 :               return false;
   49252                 :             :             }
   49253                 :             :           unsigned int i;
   49254                 :             :           tree arg;
   49255                 :         163 :           FOR_EACH_VEC_SAFE_ELT (args, i, arg)
   49256                 :         155 :             if (arg == omp_priv
   49257                 :         155 :                 || (TREE_CODE (arg) == ADDR_EXPR
   49258                 :          57 :                     && TREE_OPERAND (arg, 0) == omp_priv))
   49259                 :             :               break;
   49260                 :         155 :           cp_parser_abort_tentative_parse (parser);
   49261                 :         155 :           if (arg == NULL_TREE)
   49262                 :           8 :             error ("one of the initializer call arguments should be %<omp_priv%>"
   49263                 :             :                    " or %<&omp_priv%>");
   49264                 :         155 :           initializer = cp_parser_postfix_expression (parser, false, false, false,
   49265                 :             :                                                       false, NULL);
   49266                 :         155 :           finish_expr_stmt (initializer);
   49267                 :             :         }
   49268                 :             : 
   49269                 :         355 :       block = finish_omp_structured_block (block);
   49270                 :         355 :       cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL);
   49271                 :         355 :       if (processing_template_decl)
   49272                 :         106 :         block = build_stmt (input_location, EXPR_STMT, block);
   49273                 :         355 :       add_stmt (block);
   49274                 :             : 
   49275                 :         355 :       if (ctor)
   49276                 :         200 :         add_decl_expr (omp_orig);
   49277                 :             : 
   49278                 :         355 :       if (!parens.require_close (parser))
   49279                 :             :         return false;
   49280                 :             :     }
   49281                 :             : 
   49282                 :         906 :   if (!cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL))
   49283                 :           0 :     cp_parser_required_error (parser, RT_PRAGMA_EOL, /*keyword=*/false,
   49284                 :             :                               UNKNOWN_LOCATION);
   49285                 :             : 
   49286                 :             :   return true;
   49287                 :             : }
   49288                 :             : 
   49289                 :             : /* OpenMP 4.0
   49290                 :             :    #pragma omp declare reduction (reduction-id : typename-list : expression) \
   49291                 :             :       initializer-clause[opt] new-line
   49292                 :             : 
   49293                 :             :    initializer-clause:
   49294                 :             :       initializer (omp_priv initializer)
   49295                 :             :       initializer (function-name (argument-list))  */
   49296                 :             : 
   49297                 :             : static void
   49298                 :         962 : cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
   49299                 :             :                                  enum pragma_context)
   49300                 :             : {
   49301                 :         962 :   auto_vec<tree> types;
   49302                 :         962 :   enum tree_code reduc_code = ERROR_MARK;
   49303                 :         962 :   tree reduc_id = NULL_TREE, orig_reduc_id = NULL_TREE, type;
   49304                 :         962 :   unsigned int i;
   49305                 :         962 :   cp_token *first_token;
   49306                 :         962 :   cp_token_cache *cp;
   49307                 :         962 :   int errs;
   49308                 :         962 :   void *p;
   49309                 :             : 
   49310                 :             :   /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
   49311                 :         962 :   p = obstack_alloc (&declarator_obstack, 0);
   49312                 :             : 
   49313                 :         962 :   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
   49314                 :           4 :     goto fail;
   49315                 :             : 
   49316                 :         958 :   switch (cp_lexer_peek_token (parser->lexer)->type)
   49317                 :             :     {
   49318                 :             :     case CPP_PLUS:
   49319                 :             :       reduc_code = PLUS_EXPR;
   49320                 :             :       break;
   49321                 :          80 :     case CPP_MULT:
   49322                 :          80 :       reduc_code = MULT_EXPR;
   49323                 :          80 :       break;
   49324                 :           4 :     case CPP_MINUS:
   49325                 :           4 :       reduc_code = MINUS_EXPR;
   49326                 :           4 :       break;
   49327                 :           4 :     case CPP_AND:
   49328                 :           4 :       reduc_code = BIT_AND_EXPR;
   49329                 :           4 :       break;
   49330                 :           0 :     case CPP_XOR:
   49331                 :           0 :       reduc_code = BIT_XOR_EXPR;
   49332                 :           0 :       break;
   49333                 :          64 :     case CPP_OR:
   49334                 :          64 :       reduc_code = BIT_IOR_EXPR;
   49335                 :          64 :       break;
   49336                 :           0 :     case CPP_AND_AND:
   49337                 :           0 :       reduc_code = TRUTH_ANDIF_EXPR;
   49338                 :           0 :       break;
   49339                 :           0 :     case CPP_OR_OR:
   49340                 :           0 :       reduc_code = TRUTH_ORIF_EXPR;
   49341                 :           0 :       break;
   49342                 :         574 :     case CPP_NAME:
   49343                 :         574 :       reduc_id = orig_reduc_id = cp_parser_identifier (parser);
   49344                 :         574 :       break;
   49345                 :           0 :     default:
   49346                 :           0 :       cp_parser_error (parser, "expected %<+%>, %<*%>, %<-%>, %<&%>, %<^%>, "
   49347                 :             :                                "%<|%>, %<&&%>, %<||%> or identifier");
   49348                 :           0 :       goto fail;
   49349                 :             :     }
   49350                 :             : 
   49351                 :         958 :   if (reduc_code != ERROR_MARK)
   49352                 :         384 :     cp_lexer_consume_token (parser->lexer);
   49353                 :             : 
   49354                 :         958 :   reduc_id = omp_reduction_id (reduc_code, reduc_id, NULL_TREE);
   49355                 :         958 :   if (reduc_id == error_mark_node)
   49356                 :           0 :     goto fail;
   49357                 :             : 
   49358                 :         958 :   if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
   49359                 :           0 :     goto fail;
   49360                 :             : 
   49361                 :             :   /* Types may not be defined in declare reduction type list.  */
   49362                 :         958 :   const char *saved_message;
   49363                 :         958 :   saved_message = parser->type_definition_forbidden_message;
   49364                 :         958 :   parser->type_definition_forbidden_message
   49365                 :         958 :     = G_("types may not be defined in declare reduction type list");
   49366                 :         958 :   bool saved_colon_corrects_to_scope_p;
   49367                 :         958 :   saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
   49368                 :         958 :   parser->colon_corrects_to_scope_p = false;
   49369                 :         958 :   bool saved_colon_doesnt_start_class_def_p;
   49370                 :         958 :   saved_colon_doesnt_start_class_def_p
   49371                 :         958 :     = parser->colon_doesnt_start_class_def_p;
   49372                 :         958 :   parser->colon_doesnt_start_class_def_p = true;
   49373                 :             : 
   49374                 :         990 :   while (true)
   49375                 :             :     {
   49376                 :         974 :       location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   49377                 :         974 :       type = cp_parser_type_id (parser);
   49378                 :         974 :       if (type == error_mark_node)
   49379                 :             :         ;
   49380                 :         974 :       else if (ARITHMETIC_TYPE_P (type)
   49381                 :         235 :                && (orig_reduc_id == NULL_TREE
   49382                 :         223 :                    || (TREE_CODE (type) != COMPLEX_TYPE
   49383                 :         215 :                        && (id_equal (orig_reduc_id, "min")
   49384                 :         211 :                            || id_equal (orig_reduc_id, "max")))))
   49385                 :          16 :         error_at (loc, "predeclared arithmetic type %qT in "
   49386                 :             :                        "%<#pragma omp declare reduction%>", type);
   49387                 :         958 :       else if (FUNC_OR_METHOD_TYPE_P (type)
   49388                 :         946 :                || TREE_CODE (type) == ARRAY_TYPE)
   49389                 :          20 :         error_at (loc, "function or array type %qT in "
   49390                 :             :                        "%<#pragma omp declare reduction%>", type);
   49391                 :         938 :       else if (TYPE_REF_P (type))
   49392                 :           4 :         error_at (loc, "reference type %qT in "
   49393                 :             :                        "%<#pragma omp declare reduction%>", type);
   49394                 :         934 :       else if (TYPE_QUALS_NO_ADDR_SPACE (type))
   49395                 :          16 :         error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
   49396                 :             :                   "type %qT in %<#pragma omp declare reduction%>", type);
   49397                 :             :       else
   49398                 :         918 :         types.safe_push (type);
   49399                 :             : 
   49400                 :         974 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
   49401                 :          16 :         cp_lexer_consume_token (parser->lexer);
   49402                 :             :       else
   49403                 :             :         break;
   49404                 :          16 :     }
   49405                 :             : 
   49406                 :             :   /* Restore the saved message.  */
   49407                 :         958 :   parser->type_definition_forbidden_message = saved_message;
   49408                 :         958 :   parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
   49409                 :         958 :   parser->colon_doesnt_start_class_def_p
   49410                 :         958 :     = saved_colon_doesnt_start_class_def_p;
   49411                 :             : 
   49412                 :         958 :   if (!cp_parser_require (parser, CPP_COLON, RT_COLON)
   49413                 :         958 :       || types.is_empty ())
   49414                 :             :     {
   49415                 :          72 :      fail:
   49416                 :          72 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49417                 :          72 :       goto done;
   49418                 :             :     }
   49419                 :             : 
   49420                 :         902 :   first_token = cp_lexer_peek_token (parser->lexer);
   49421                 :         902 :   cp = NULL;
   49422                 :         902 :   errs = errorcount;
   49423                 :        1652 :   FOR_EACH_VEC_ELT (types, i, type)
   49424                 :             :     {
   49425                 :         918 :       tree fntype
   49426                 :         918 :         = build_function_type_list (void_type_node,
   49427                 :             :                                     cp_build_reference_type (type, false),
   49428                 :             :                                     NULL_TREE);
   49429                 :         918 :       tree this_reduc_id = reduc_id;
   49430                 :         918 :       if (!dependent_type_p (type))
   49431                 :         644 :         this_reduc_id = omp_reduction_id (ERROR_MARK, reduc_id, type);
   49432                 :         918 :       tree fndecl = build_lang_decl (FUNCTION_DECL, this_reduc_id, fntype);
   49433                 :         918 :       DECL_SOURCE_LOCATION (fndecl) = pragma_tok->location;
   49434                 :         918 :       DECL_ARTIFICIAL (fndecl) = 1;
   49435                 :         918 :       DECL_EXTERNAL (fndecl) = 1;
   49436                 :         918 :       DECL_DECLARED_INLINE_P (fndecl) = 1;
   49437                 :         918 :       DECL_IGNORED_P (fndecl) = 1;
   49438                 :         918 :       DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1;
   49439                 :         918 :       SET_DECL_ASSEMBLER_NAME (fndecl, get_identifier ("<udr>"));
   49440                 :         918 :       DECL_ATTRIBUTES (fndecl)
   49441                 :         918 :         = tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
   49442                 :         918 :                      DECL_ATTRIBUTES (fndecl));
   49443                 :         918 :       bool block_scope = false;
   49444                 :         918 :       if (current_function_decl)
   49445                 :             :         {
   49446                 :         246 :           block_scope = true;
   49447                 :         246 :           DECL_CONTEXT (fndecl) = current_function_decl;
   49448                 :         246 :           DECL_LOCAL_DECL_P (fndecl) = true;
   49449                 :             :         }
   49450                 :             : 
   49451                 :         918 :       if (processing_template_decl)
   49452                 :         338 :         fndecl = push_template_decl (fndecl);
   49453                 :             : 
   49454                 :         918 :       if (block_scope)
   49455                 :             :         {
   49456                 :         246 :           if (!processing_template_decl)
   49457                 :          76 :             pushdecl (fndecl);
   49458                 :             :         }
   49459                 :         672 :       else if (current_class_type)
   49460                 :             :         {
   49461                 :         234 :           if (cp == NULL)
   49462                 :             :             {
   49463                 :        2420 :               while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   49464                 :        2190 :                 cp_lexer_consume_token (parser->lexer);
   49465                 :         230 :               cp = cp_token_cache_new (first_token,
   49466                 :             :                                        cp_lexer_peek_nth_token (parser->lexer,
   49467                 :             :                                                                 2));
   49468                 :             :             }
   49469                 :         234 :           DECL_STATIC_FUNCTION_P (fndecl) = 1;
   49470                 :         234 :           finish_member_declaration (fndecl);
   49471                 :         234 :           DECL_PENDING_INLINE_INFO (fndecl) = cp;
   49472                 :         234 :           DECL_PENDING_INLINE_P (fndecl) = 1;
   49473                 :         234 :           vec_safe_push (unparsed_funs_with_definitions, fndecl);
   49474                 :         234 :           continue;
   49475                 :         234 :         }
   49476                 :             :       else
   49477                 :             :         {
   49478                 :         438 :           DECL_CONTEXT (fndecl) = current_namespace;
   49479                 :         438 :           tree d = pushdecl (fndecl);
   49480                 :             :           /* We should never meet a matched duplicate decl.  */
   49481                 :         438 :           gcc_checking_assert (d == error_mark_node || d == fndecl);
   49482                 :             :         }
   49483                 :             : 
   49484                 :         684 :       tree block = NULL_TREE;
   49485                 :         684 :       if (!block_scope)
   49486                 :         438 :         start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
   49487                 :             :       else
   49488                 :         246 :         block = begin_omp_structured_block ();
   49489                 :         684 :       if (cp)
   49490                 :             :         {
   49491                 :          12 :           cp_parser_push_lexer_for_tokens (parser, cp);
   49492                 :          12 :           parser->lexer->in_pragma = true;
   49493                 :             :         }
   49494                 :             : 
   49495                 :         684 :       bool ok = cp_parser_omp_declare_reduction_exprs (fndecl, parser);
   49496                 :             : 
   49497                 :         684 :       if (cp)
   49498                 :          12 :         cp_parser_pop_lexer (parser);
   49499                 :         684 :       if (!block_scope)
   49500                 :         438 :         finish_function (/*inline_p=*/false);
   49501                 :             :       else
   49502                 :             :         {
   49503                 :         246 :           DECL_CONTEXT (fndecl) = current_function_decl;
   49504                 :         246 :           if (DECL_TEMPLATE_INFO (fndecl))
   49505                 :           0 :             DECL_CONTEXT (DECL_TI_TEMPLATE (fndecl)) = current_function_decl;
   49506                 :             :         }
   49507                 :         684 :       if (!ok)
   49508                 :          12 :         goto fail;
   49509                 :             : 
   49510                 :         672 :       if (block_scope)
   49511                 :             :         {
   49512                 :         242 :           block = finish_omp_structured_block (block);
   49513                 :         242 :           if (TREE_CODE (block) == BIND_EXPR)
   49514                 :          72 :             DECL_SAVED_TREE (fndecl) = BIND_EXPR_BODY (block);
   49515                 :         170 :           else if (TREE_CODE (block) == STATEMENT_LIST)
   49516                 :         170 :             DECL_SAVED_TREE (fndecl) = block;
   49517                 :         242 :           if (processing_template_decl)
   49518                 :         170 :             add_decl_expr (fndecl);
   49519                 :             :         }
   49520                 :             : 
   49521                 :         672 :       cp_check_omp_declare_reduction (fndecl);
   49522                 :         672 :       if (cp == NULL && types.length () > 1)
   49523                 :           8 :         cp = cp_token_cache_new (first_token,
   49524                 :             :                                  cp_lexer_peek_nth_token (parser->lexer, 2));
   49525                 :         672 :       if (errs != errorcount)
   49526                 :             :         break;
   49527                 :             :     }
   49528                 :             : 
   49529                 :         890 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   49530                 :             : 
   49531                 :         962 :  done:
   49532                 :             :   /* Free any declarators allocated.  */
   49533                 :         962 :   obstack_free (&declarator_obstack, p);
   49534                 :         962 : }
   49535                 :             : 
   49536                 :             : /* OpenMP 4.0
   49537                 :             :    #pragma omp declare simd declare-simd-clauses[optseq] new-line
   49538                 :             :    #pragma omp declare reduction (reduction-id : typename-list : expression) \
   49539                 :             :       initializer-clause[opt] new-line
   49540                 :             :    #pragma omp declare target new-line
   49541                 :             : 
   49542                 :             :    OpenMP 5.0
   49543                 :             :    #pragma omp declare variant (identifier) match (context-selector)  */
   49544                 :             : 
   49545                 :             : static bool
   49546                 :        4291 : cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
   49547                 :             :                        enum pragma_context context)
   49548                 :             : {
   49549                 :        4291 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49550                 :             :     {
   49551                 :        4291 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   49552                 :        4291 :       const char *p = IDENTIFIER_POINTER (id);
   49553                 :             : 
   49554                 :        4291 :       if (strcmp (p, "simd") == 0)
   49555                 :             :         {
   49556                 :        1099 :           cp_lexer_consume_token (parser->lexer);
   49557                 :        1099 :           cp_parser_omp_declare_simd (parser, pragma_tok,
   49558                 :             :                                       context, false);
   49559                 :        1099 :           return true;
   49560                 :             :         }
   49561                 :        3192 :       if (flag_openmp && strcmp (p, "variant") == 0)
   49562                 :             :         {
   49563                 :        1449 :           cp_lexer_consume_token (parser->lexer);
   49564                 :        1449 :           cp_parser_omp_declare_simd (parser, pragma_tok,
   49565                 :             :                                       context, true);
   49566                 :        1449 :           return true;
   49567                 :             :         }
   49568                 :        1743 :       cp_ensure_no_omp_declare_simd (parser);
   49569                 :        1743 :       if (strcmp (p, "reduction") == 0)
   49570                 :             :         {
   49571                 :         962 :           cp_lexer_consume_token (parser->lexer);
   49572                 :         962 :           cp_parser_omp_declare_reduction (parser, pragma_tok,
   49573                 :             :                                            context);
   49574                 :         962 :           return false;
   49575                 :             :         }
   49576                 :         781 :       if (!flag_openmp)  /* flag_openmp_simd  */
   49577                 :             :         {
   49578                 :           0 :           cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49579                 :           0 :           return false;
   49580                 :             :         }
   49581                 :         781 :       if (strcmp (p, "target") == 0)
   49582                 :             :         {
   49583                 :         781 :           cp_lexer_consume_token (parser->lexer);
   49584                 :         781 :           cp_parser_omp_declare_target (parser, pragma_tok);
   49585                 :         781 :           return false;
   49586                 :             :         }
   49587                 :             :     }
   49588                 :           0 :   cp_parser_error (parser, "expected %<simd%>, %<reduction%>, "
   49589                 :             :                            "%<target%> or %<variant%>");
   49590                 :           0 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   49591                 :           0 :   return false;
   49592                 :             : }
   49593                 :             : 
   49594                 :             : /* OpenMP 5.0
   49595                 :             :    #pragma omp requires clauses[optseq] new-line  */
   49596                 :             : 
   49597                 :             : static bool
   49598                 :         195 : cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
   49599                 :             : {
   49600                 :         195 :   enum omp_requires new_req = (enum omp_requires) 0;
   49601                 :             : 
   49602                 :         195 :   location_t loc = pragma_tok->location;
   49603                 :         434 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   49604                 :             :     {
   49605                 :         255 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   49606                 :         255 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   49607                 :          35 :         cp_lexer_consume_token (parser->lexer);
   49608                 :             : 
   49609                 :         255 :       if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49610                 :             :         {
   49611                 :         251 :           tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   49612                 :         251 :           const char *p = IDENTIFIER_POINTER (id);
   49613                 :         251 :           location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
   49614                 :         251 :           enum omp_requires this_req = (enum omp_requires) 0;
   49615                 :             : 
   49616                 :         251 :           if (!strcmp (p, "unified_address"))
   49617                 :             :             this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
   49618                 :         204 :           else if (!strcmp (p, "unified_shared_memory"))
   49619                 :             :             this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
   49620                 :         158 :           else if (!strcmp (p, "dynamic_allocators"))
   49621                 :             :             this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
   49622                 :         138 :           else if (!strcmp (p, "reverse_offload"))
   49623                 :             :             this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
   49624                 :          87 :           else if (!strcmp (p, "atomic_default_mem_order"))
   49625                 :             :             {
   49626                 :          83 :               cp_lexer_consume_token (parser->lexer);
   49627                 :             : 
   49628                 :          83 :               matching_parens parens;
   49629                 :          83 :               if (parens.require_open (parser))
   49630                 :             :                 {
   49631                 :          83 :                   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49632                 :             :                     {
   49633                 :          79 :                       id = cp_lexer_peek_token (parser->lexer)->u.value;
   49634                 :          79 :                       p = IDENTIFIER_POINTER (id);
   49635                 :             : 
   49636                 :          79 :                       if (!strcmp (p, "seq_cst"))
   49637                 :             :                         this_req
   49638                 :             :                           = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
   49639                 :          44 :                       else if (!strcmp (p, "relaxed"))
   49640                 :             :                         this_req
   49641                 :             :                           = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
   49642                 :          40 :                       else if (!strcmp (p, "release"))
   49643                 :             :                         this_req
   49644                 :             :                           = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE;
   49645                 :          32 :                       else if (!strcmp (p, "acq_rel"))
   49646                 :             :                         this_req
   49647                 :             :                           = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
   49648                 :          16 :                       else if (!strcmp (p, "acquire"))
   49649                 :             :                         this_req
   49650                 :             :                           = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE;
   49651                 :             :                     }
   49652                 :             :                   if (this_req == 0)
   49653                 :             :                     {
   49654                 :           8 :                       error_at (cp_lexer_peek_token (parser->lexer)->location,
   49655                 :             :                                 "expected %<acq_rel%>, %<acquire%>, "
   49656                 :             :                                 "%<relaxed%>, %<release%> or %<seq_cst%>");
   49657                 :           8 :                       switch (cp_lexer_peek_token (parser->lexer)->type)
   49658                 :             :                         {
   49659                 :             :                         case CPP_EOF:
   49660                 :             :                         case CPP_PRAGMA_EOL:
   49661                 :             :                         case CPP_CLOSE_PAREN:
   49662                 :             :                           break;
   49663                 :           4 :                         default:
   49664                 :           4 :                           if (cp_lexer_nth_token_is (parser->lexer, 2,
   49665                 :             :                                                      CPP_CLOSE_PAREN))
   49666                 :           4 :                             cp_lexer_consume_token (parser->lexer);
   49667                 :             :                           break;
   49668                 :             :                         }
   49669                 :             :                     }
   49670                 :             :                   else
   49671                 :          75 :                     cp_lexer_consume_token (parser->lexer);
   49672                 :             : 
   49673                 :          83 :                   if (!parens.require_close (parser))
   49674                 :           4 :                     cp_parser_skip_to_closing_parenthesis (parser,
   49675                 :             :                                                            /*recovering=*/true,
   49676                 :             :                                                            /*or_comma=*/false,
   49677                 :             :                                                            /*consume_paren=*/
   49678                 :             :                                                            true);
   49679                 :             : 
   49680                 :          83 :                   if (this_req == 0)
   49681                 :             :                     {
   49682                 :           8 :                       cp_parser_require_pragma_eol (parser, pragma_tok);
   49683                 :           8 :                       return false;
   49684                 :             :                     }
   49685                 :             :                 }
   49686                 :          75 :               p = NULL;
   49687                 :             :             }
   49688                 :             :           else
   49689                 :             :             {
   49690                 :           4 :               error_at (cloc, "expected %<unified_address%>, "
   49691                 :             :                               "%<unified_shared_memory%>, "
   49692                 :             :                               "%<dynamic_allocators%>, "
   49693                 :             :                                "%<reverse_offload%> "
   49694                 :             :                                "or %<atomic_default_mem_order%> clause");
   49695                 :           4 :               cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49696                 :           4 :               return false;
   49697                 :             :             }
   49698                 :          75 :           if (p)
   49699                 :         164 :             cp_lexer_consume_token (parser->lexer);
   49700                 :         239 :           if (this_req)
   49701                 :             :             {
   49702                 :         239 :               if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
   49703                 :             :                 {
   49704                 :         164 :                   if ((this_req & new_req) != 0)
   49705                 :          16 :                     error_at (cloc, "too many %qs clauses", p);
   49706                 :         164 :                   if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
   49707                 :         144 :                       && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
   49708                 :          12 :                     error_at (cloc, "%qs clause used lexically after first "
   49709                 :             :                                     "target construct or offloading API", p);
   49710                 :             :                 }
   49711                 :          75 :               else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
   49712                 :             :                 {
   49713                 :           4 :                   error_at (cloc, "too many %qs clauses",
   49714                 :             :                             "atomic_default_mem_order");
   49715                 :           4 :                   this_req = (enum omp_requires) 0;
   49716                 :             :                 }
   49717                 :          71 :               else if ((omp_requires_mask
   49718                 :             :                         & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
   49719                 :             :                 {
   49720                 :           8 :                   error_at (cloc, "more than one %<atomic_default_mem_order%>"
   49721                 :             :                                   " clause in a single compilation unit");
   49722                 :           8 :                   this_req
   49723                 :           8 :                     = (enum omp_requires)
   49724                 :           8 :                        (omp_requires_mask
   49725                 :             :                         & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
   49726                 :             :                 }
   49727                 :          63 :               else if ((omp_requires_mask
   49728                 :             :                         & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
   49729                 :           4 :                 error_at (cloc, "%<atomic_default_mem_order%> clause used "
   49730                 :             :                                 "lexically after first %<atomic%> construct "
   49731                 :             :                                 "without memory order clause");
   49732                 :         239 :               new_req = (enum omp_requires) (new_req | this_req);
   49733                 :         239 :               omp_requires_mask
   49734                 :         239 :                 = (enum omp_requires) (omp_requires_mask | this_req);
   49735                 :         239 :               continue;
   49736                 :             :             }
   49737                 :             :         }
   49738                 :             :       break;
   49739                 :             :     }
   49740                 :         183 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   49741                 :             : 
   49742                 :         183 :   if (new_req == 0)
   49743                 :           4 :     error_at (loc, "%<pragma omp requires%> requires at least one clause");
   49744                 :             :   return false;
   49745                 :             : }
   49746                 :             : 
   49747                 :             : 
   49748                 :             : /* OpenMP 5.1:
   49749                 :             :    #pragma omp nothing new-line  */
   49750                 :             : 
   49751                 :             : static void
   49752                 :          62 : cp_parser_omp_nothing (cp_parser *parser, cp_token *pragma_tok)
   49753                 :             : {
   49754                 :           0 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   49755                 :           0 : }
   49756                 :             : 
   49757                 :             : 
   49758                 :             : /* OpenMP 5.1
   49759                 :             :    #pragma omp error clauses[optseq] new-line  */
   49760                 :             : 
   49761                 :             : static bool
   49762                 :         324 : cp_parser_omp_error (cp_parser *parser, cp_token *pragma_tok,
   49763                 :             :                      enum pragma_context context)
   49764                 :             : {
   49765                 :         324 :   int at_compilation = -1;
   49766                 :         324 :   int severity_fatal = -1;
   49767                 :         324 :   tree message = NULL_TREE;
   49768                 :         324 :   bool bad = false;
   49769                 :         324 :   location_t loc = pragma_tok->location;
   49770                 :             : 
   49771                 :         818 :   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   49772                 :             :     {
   49773                 :         506 :       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
   49774                 :         506 :           && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
   49775                 :          73 :         cp_lexer_consume_token (parser->lexer);
   49776                 :             : 
   49777                 :         506 :       if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
   49778                 :             :         break;
   49779                 :             : 
   49780                 :         502 :       const char *p
   49781                 :         502 :         = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
   49782                 :         502 :       location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
   49783                 :         502 :       static const char *args[] = {
   49784                 :             :         "execution", "compilation", "warning", "fatal"
   49785                 :             :       };
   49786                 :         502 :       int *v = NULL;
   49787                 :         502 :       int idx = 0, n = -1;
   49788                 :         502 :       tree m = NULL_TREE;
   49789                 :             : 
   49790                 :         502 :       if (!strcmp (p, "at"))
   49791                 :             :         v = &at_compilation;
   49792                 :         323 :       else if (!strcmp (p, "severity"))
   49793                 :             :         {
   49794                 :             :           v = &severity_fatal;
   49795                 :             :           idx += 2;
   49796                 :             :         }
   49797                 :         179 :       else if (strcmp (p, "message"))
   49798                 :             :         {
   49799                 :           8 :           error_at (cloc,
   49800                 :             :                     "expected %<at%>, %<severity%> or %<message%> clause");
   49801                 :           8 :           cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   49802                 :           8 :           return false;
   49803                 :             :         }
   49804                 :             : 
   49805                 :         494 :       cp_lexer_consume_token (parser->lexer);
   49806                 :             : 
   49807                 :         494 :       matching_parens parens;
   49808                 :         494 :       if (parens.require_open (parser))
   49809                 :             :         {
   49810                 :         482 :           if (v == NULL)
   49811                 :             :             {
   49812                 :         167 :               m = cp_parser_assignment_expression (parser);
   49813                 :         167 :               if (type_dependent_expression_p (m))
   49814                 :           4 :                 m = build1 (IMPLICIT_CONV_EXPR, const_string_type_node, m);
   49815                 :             :               else
   49816                 :         163 :                 m = perform_implicit_conversion_flags (const_string_type_node, m,
   49817                 :             :                                                        tf_warning_or_error,
   49818                 :             :                                                        LOOKUP_NORMAL);
   49819                 :             :             }
   49820                 :             :           else
   49821                 :             :             {
   49822                 :         315 :               if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49823                 :             :                 {
   49824                 :         299 :                   tree val = cp_lexer_peek_token (parser->lexer)->u.value;
   49825                 :         299 :                   const char *q = IDENTIFIER_POINTER (val);
   49826                 :             : 
   49827                 :         299 :                   if (!strcmp (q, args[idx]))
   49828                 :             :                     n = 0;
   49829                 :         147 :                   else if (!strcmp (q, args[idx + 1]))
   49830                 :             :                     n = 1;
   49831                 :             :                 }
   49832                 :             :               if (n == -1)
   49833                 :             :                 {
   49834                 :          24 :                   error_at (cp_lexer_peek_token (parser->lexer)->location,
   49835                 :          24 :                             "expected %qs or %qs", args[idx], args[idx + 1]);
   49836                 :          24 :                   bad = true;
   49837                 :          24 :                   switch (cp_lexer_peek_token (parser->lexer)->type)
   49838                 :             :                     {
   49839                 :             :                     case CPP_EOF:
   49840                 :             :                     case CPP_PRAGMA_EOL:
   49841                 :             :                     case CPP_CLOSE_PAREN:
   49842                 :             :                       break;
   49843                 :          16 :                     default:
   49844                 :          16 :                       if (cp_lexer_nth_token_is (parser->lexer, 2,
   49845                 :             :                                                  CPP_CLOSE_PAREN))
   49846                 :           8 :                         cp_lexer_consume_token (parser->lexer);
   49847                 :             :                       break;
   49848                 :             :                     }
   49849                 :             :                 }
   49850                 :             :               else
   49851                 :         291 :                 cp_lexer_consume_token (parser->lexer);
   49852                 :             :             }
   49853                 :             : 
   49854                 :         482 :           if (!parens.require_close (parser))
   49855                 :          36 :             cp_parser_skip_to_closing_parenthesis (parser,
   49856                 :             :                                                    /*recovering=*/true,
   49857                 :             :                                                    /*or_comma=*/false,
   49858                 :             :                                                    /*consume_paren=*/
   49859                 :             :                                                    true);
   49860                 :             : 
   49861                 :         482 :           if (v == NULL)
   49862                 :             :             {
   49863                 :         167 :               if (message)
   49864                 :             :                 {
   49865                 :           4 :                   error_at (cloc, "too many %qs clauses", p);
   49866                 :           4 :                   bad = true;
   49867                 :             :                 }
   49868                 :             :               else
   49869                 :             :                 message = m;
   49870                 :             :             }
   49871                 :         315 :           else if (n != -1)
   49872                 :             :             {
   49873                 :         291 :               if (*v != -1)
   49874                 :             :                 {
   49875                 :           8 :                   error_at (cloc, "too many %qs clauses", p);
   49876                 :           8 :                   bad = true;
   49877                 :             :                 }
   49878                 :             :               else
   49879                 :         283 :                 *v = n;
   49880                 :             :             }
   49881                 :             :         }
   49882                 :             :       else
   49883                 :             :         bad = true;
   49884                 :             :     }
   49885                 :         316 :   cp_parser_require_pragma_eol (parser, pragma_tok);
   49886                 :         316 :   if (bad)
   49887                 :             :     return true;
   49888                 :             : 
   49889                 :         268 :   if (at_compilation == -1)
   49890                 :         117 :     at_compilation = 1;
   49891                 :         268 :   if (severity_fatal == -1)
   49892                 :         152 :     severity_fatal = 1;
   49893                 :         268 :   if (!at_compilation)
   49894                 :             :     {
   49895                 :          78 :       if (context != pragma_compound)
   49896                 :             :         {
   49897                 :          28 :           error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
   49898                 :             :                          "may only be used in compound statements");
   49899                 :          28 :           return true;
   49900                 :             :         }
   49901                 :          50 :       tree fndecl
   49902                 :          68 :         = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
   49903                 :             :                                                 : BUILT_IN_GOMP_WARNING);
   49904                 :          50 :       if (!message)
   49905                 :           9 :         message = build_zero_cst (const_string_type_node);
   49906                 :          50 :       tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
   49907                 :             :                                        build_all_ones_cst (size_type_node));
   49908                 :          50 :       add_stmt (stmt);
   49909                 :          50 :       return true;
   49910                 :             :     }
   49911                 :             : 
   49912                 :         190 :   if (in_discarded_stmt)
   49913                 :             :     return false;
   49914                 :             : 
   49915                 :         186 :   const char *msg = NULL;
   49916                 :         186 :   if (message)
   49917                 :             :     {
   49918                 :         100 :       msg = c_getstr (fold_for_warn (message));
   49919                 :         100 :       if (msg == NULL)
   49920                 :          24 :         msg = _("<message unknown at compile time>");
   49921                 :             :     }
   49922                 :          24 :   if (msg)
   49923                 :         141 :     emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
   49924                 :             :                      "%<pragma omp error%> encountered: %s", msg);
   49925                 :             :   else
   49926                 :          89 :     emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
   49927                 :             :                      "%<pragma omp error%> encountered");
   49928                 :             :   return false;
   49929                 :             : }
   49930                 :             : 
   49931                 :             : /* OpenMP 4.5:
   49932                 :             :    #pragma omp taskloop taskloop-clause[optseq] new-line
   49933                 :             :      for-loop
   49934                 :             : 
   49935                 :             :    #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
   49936                 :             :      for-loop  */
   49937                 :             : 
   49938                 :             : #define OMP_TASKLOOP_CLAUSE_MASK                                \
   49939                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   49940                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   49941                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   49942                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   49943                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)        \
   49944                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE)      \
   49945                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS)      \
   49946                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   49947                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
   49948                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   49949                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)  \
   49950                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)      \
   49951                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)        \
   49952                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)       \
   49953                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   49954                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   49955                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
   49956                 :             : 
   49957                 :             : static tree
   49958                 :        1154 : cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok,
   49959                 :             :                         char *p_name, omp_clause_mask mask, tree *cclauses,
   49960                 :             :                         bool *if_p)
   49961                 :             : {
   49962                 :        1154 :   tree clauses, sb, ret;
   49963                 :        1154 :   unsigned int save;
   49964                 :        1154 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   49965                 :             : 
   49966                 :        1154 :   strcat (p_name, " taskloop");
   49967                 :        1154 :   mask |= OMP_TASKLOOP_CLAUSE_MASK;
   49968                 :             :   /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
   49969                 :             :      clause.  */
   49970                 :        1154 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
   49971                 :         247 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
   49972                 :             : 
   49973                 :        1154 :   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
   49974                 :             :     {
   49975                 :         819 :       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
   49976                 :         819 :       const char *p = IDENTIFIER_POINTER (id);
   49977                 :             : 
   49978                 :         819 :       if (strcmp (p, "simd") == 0)
   49979                 :             :         {
   49980                 :         479 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   49981                 :         479 :           if (cclauses == NULL)
   49982                 :         193 :             cclauses = cclauses_buf;
   49983                 :             : 
   49984                 :         479 :           cp_lexer_consume_token (parser->lexer);
   49985                 :         479 :           if (!flag_openmp)  /* flag_openmp_simd  */
   49986                 :          12 :             return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
   49987                 :          12 :                                        cclauses, if_p);
   49988                 :         467 :           sb = begin_omp_structured_block ();
   49989                 :         467 :           save = cp_parser_begin_omp_structured_block (parser);
   49990                 :         467 :           ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
   49991                 :             :                                     cclauses, if_p);
   49992                 :         467 :           cp_parser_end_omp_structured_block (parser, save);
   49993                 :         467 :           tree body = finish_omp_structured_block (sb);
   49994                 :         467 :           if (ret == NULL)
   49995                 :             :             return ret;
   49996                 :         467 :           ret = make_node (OMP_TASKLOOP);
   49997                 :         467 :           TREE_TYPE (ret) = void_type_node;
   49998                 :         467 :           OMP_FOR_BODY (ret) = body;
   49999                 :         467 :           OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
   50000                 :         467 :           SET_EXPR_LOCATION (ret, loc);
   50001                 :         467 :           add_stmt (ret);
   50002                 :         467 :           return ret;
   50003                 :             :         }
   50004                 :             :     }
   50005                 :         675 :   if (!flag_openmp)  /* flag_openmp_simd  */
   50006                 :             :     {
   50007                 :           8 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   50008                 :           8 :       return NULL_TREE;
   50009                 :             :     }
   50010                 :             : 
   50011                 :         667 :   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
   50012                 :             :                                        cclauses == NULL);
   50013                 :         667 :   if (cclauses)
   50014                 :             :     {
   50015                 :         187 :       cp_omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
   50016                 :         187 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
   50017                 :             :     }
   50018                 :             : 
   50019                 :         667 :   keep_next_level (true);
   50020                 :         667 :   sb = begin_omp_structured_block ();
   50021                 :         667 :   save = cp_parser_begin_omp_structured_block (parser);
   50022                 :             : 
   50023                 :         667 :   ret = cp_parser_omp_for_loop (parser, OMP_TASKLOOP, clauses, cclauses,
   50024                 :             :                                 if_p);
   50025                 :             : 
   50026                 :         667 :   cp_parser_end_omp_structured_block (parser, save);
   50027                 :         667 :   add_stmt (finish_omp_structured_block (sb));
   50028                 :             : 
   50029                 :         667 :   return ret;
   50030                 :             : }
   50031                 :             : 
   50032                 :             : 
   50033                 :             : /* OpenACC 2.0:
   50034                 :             :    # pragma acc routine oacc-routine-clause[optseq] new-line
   50035                 :             :      function-definition
   50036                 :             : 
   50037                 :             :    # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
   50038                 :             : */
   50039                 :             : 
   50040                 :             : #define OACC_ROUTINE_CLAUSE_MASK                                        \
   50041                 :             :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)          \
   50042                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)                \
   50043                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)                \
   50044                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)                   \
   50045                 :             :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
   50046                 :             : 
   50047                 :             : /* Parse the OpenACC routine pragma.  This has an optional '( name )'
   50048                 :             :    component, which must resolve to a declared namespace-scope
   50049                 :             :    function.  The clauses are either processed directly (for a named
   50050                 :             :    function), or defered until the immediatley following declaration
   50051                 :             :    is parsed.  */
   50052                 :             : 
   50053                 :             : static void
   50054                 :        1330 : cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
   50055                 :             :                         enum pragma_context context)
   50056                 :             : {
   50057                 :        1330 :   gcc_checking_assert (context == pragma_external);
   50058                 :             :   /* The checking for "another pragma following this one" in the "no optional
   50059                 :             :      '( name )'" case makes sure that we dont re-enter.  */
   50060                 :        1330 :   gcc_checking_assert (parser->oacc_routine == NULL);
   50061                 :             : 
   50062                 :        1330 :   cp_oacc_routine_data data;
   50063                 :        1330 :   data.error_seen = false;
   50064                 :        1330 :   data.fndecl_seen = false;
   50065                 :        1330 :   data.tokens = vNULL;
   50066                 :        1330 :   data.clauses = NULL_TREE;
   50067                 :        1330 :   data.loc = pragma_tok->location;
   50068                 :             :   /* It is safe to take the address of a local variable; it will only be
   50069                 :             :      used while this scope is live.  */
   50070                 :        1330 :   parser->oacc_routine = &data;
   50071                 :             : 
   50072                 :             :   /* Look for optional '( name )'.  */
   50073                 :        1330 :   if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
   50074                 :             :     {
   50075                 :         604 :       matching_parens parens;
   50076                 :         604 :       parens.consume_open (parser); /* '(' */
   50077                 :             : 
   50078                 :             :       /* We parse the name as an id-expression.  If it resolves to
   50079                 :             :          anything other than a non-overloaded function at namespace
   50080                 :             :          scope, it's an error.  */
   50081                 :         604 :       location_t name_loc = cp_lexer_peek_token (parser->lexer)->location;
   50082                 :         604 :       tree name = cp_parser_id_expression (parser,
   50083                 :             :                                            /*template_keyword_p=*/false,
   50084                 :             :                                            /*check_dependency_p=*/false,
   50085                 :             :                                            /*template_p=*/NULL,
   50086                 :             :                                            /*declarator_p=*/false,
   50087                 :             :                                            /*optional_p=*/false);
   50088                 :         604 :       tree decl = (identifier_p (name)
   50089                 :         572 :                    ? cp_parser_lookup_name_simple (parser, name, name_loc)
   50090                 :         604 :                    : name);
   50091                 :         604 :       if (name != error_mark_node && decl == error_mark_node)
   50092                 :          20 :         cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, name_loc);
   50093                 :             : 
   50094                 :         604 :       if (decl == error_mark_node
   50095                 :        1156 :           || !parens.require_close (parser))
   50096                 :             :         {
   50097                 :          60 :           cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   50098                 :          60 :           parser->oacc_routine = NULL;
   50099                 :          88 :           return;
   50100                 :             :         }
   50101                 :             : 
   50102                 :         544 :       data.clauses
   50103                 :         544 :         = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
   50104                 :             :                                       "#pragma acc routine",
   50105                 :             :                                       cp_lexer_peek_token (parser->lexer));
   50106                 :             :       /* The clauses are in reverse order; fix that to make later diagnostic
   50107                 :             :          emission easier.  */
   50108                 :         544 :       data.clauses = nreverse (data.clauses);
   50109                 :             : 
   50110                 :         544 :       if (decl && is_overloaded_fn (decl)
   50111                 :        1072 :           && (TREE_CODE (decl) != FUNCTION_DECL
   50112                 :             :               || DECL_FUNCTION_TEMPLATE_P  (decl)))
   50113                 :             :         {
   50114                 :          12 :           error_at (name_loc,
   50115                 :             :                     "%<#pragma acc routine%> names a set of overloads");
   50116                 :          12 :           parser->oacc_routine = NULL;
   50117                 :          12 :           return;
   50118                 :             :         }
   50119                 :             : 
   50120                 :             :       /* Perhaps we should use the same rule as declarations in different
   50121                 :             :          namespaces?  */
   50122                 :         532 :       if (!DECL_NAMESPACE_SCOPE_P (decl))
   50123                 :             :         {
   50124                 :           0 :           error_at (name_loc,
   50125                 :             :                     "%qD does not refer to a namespace scope function", decl);
   50126                 :           0 :           parser->oacc_routine = NULL;
   50127                 :           0 :           return;
   50128                 :             :         }
   50129                 :             : 
   50130                 :         532 :       if (TREE_CODE (decl) != FUNCTION_DECL)
   50131                 :             :         {
   50132                 :          16 :           error_at (name_loc, "%qD does not refer to a function", decl);
   50133                 :          16 :           parser->oacc_routine = NULL;
   50134                 :          16 :           return;
   50135                 :             :         }
   50136                 :             : 
   50137                 :         516 :       cp_finalize_oacc_routine (parser, decl, false);
   50138                 :         516 :       parser->oacc_routine = NULL;
   50139                 :             :     }
   50140                 :             :   else /* No optional '( name )'.  */
   50141                 :             :     {
   50142                 :             :       /* Store away all pragma tokens.  */
   50143                 :        1618 :       while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
   50144                 :         892 :         cp_lexer_consume_token (parser->lexer);
   50145                 :         726 :       cp_parser_require_pragma_eol (parser, pragma_tok);
   50146                 :         726 :       struct cp_token_cache *cp
   50147                 :         726 :         = cp_token_cache_new (pragma_tok, cp_lexer_peek_token (parser->lexer));
   50148                 :         726 :       parser->oacc_routine->tokens.safe_push (cp);
   50149                 :             : 
   50150                 :             :       /* Emit a helpful diagnostic if there's another pragma following this
   50151                 :             :          one.  */
   50152                 :         726 :       if (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
   50153                 :             :         {
   50154                 :          36 :           cp_ensure_no_oacc_routine (parser);
   50155                 :          36 :           data.tokens.release ();
   50156                 :             :           /* ..., and then just keep going.  */
   50157                 :          36 :           return;
   50158                 :             :         }
   50159                 :             : 
   50160                 :             :       /* We only have to consider the pragma_external case here.  */
   50161                 :         690 :       cp_parser_declaration (parser, NULL_TREE);
   50162                 :         690 :       if (parser->oacc_routine
   50163                 :         175 :           && !parser->oacc_routine->fndecl_seen)
   50164                 :           7 :         cp_ensure_no_oacc_routine (parser);
   50165                 :             :       else
   50166                 :         683 :         parser->oacc_routine = NULL;
   50167                 :         690 :       data.tokens.release ();
   50168                 :             :     }
   50169                 :             : }
   50170                 :             : 
   50171                 :             : /* Finalize #pragma acc routine clauses after direct declarator has
   50172                 :             :    been parsed.  */
   50173                 :             : 
   50174                 :             : static tree
   50175                 :         650 : cp_parser_late_parsing_oacc_routine (cp_parser *parser, tree attrs)
   50176                 :             : {
   50177                 :         650 :   struct cp_token_cache *ce;
   50178                 :         650 :   cp_oacc_routine_data *data = parser->oacc_routine;
   50179                 :             : 
   50180                 :         650 :   if (!data->error_seen && data->fndecl_seen)
   50181                 :             :     {
   50182                 :          12 :       error_at (data->loc,
   50183                 :             :                 "%<#pragma acc routine%> not immediately followed by "
   50184                 :             :                 "a single function declaration or definition");
   50185                 :          12 :       data->error_seen = true;
   50186                 :             :     }
   50187                 :         650 :   if (data->error_seen)
   50188                 :             :     return attrs;
   50189                 :             : 
   50190                 :         638 :   gcc_checking_assert (data->tokens.length () == 1);
   50191                 :         638 :   ce = data->tokens[0];
   50192                 :             : 
   50193                 :         638 :   cp_parser_push_lexer_for_tokens (parser, ce);
   50194                 :         638 :   parser->lexer->in_pragma = true;
   50195                 :         638 :   gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);
   50196                 :             : 
   50197                 :         638 :   cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
   50198                 :         638 :   gcc_checking_assert (parser->oacc_routine->clauses == NULL_TREE);
   50199                 :         638 :   parser->oacc_routine->clauses
   50200                 :         638 :     = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
   50201                 :             :                                   "#pragma acc routine", pragma_tok);
   50202                 :             :   /* The clauses are in reverse order; fix that to make later diagnostic
   50203                 :             :      emission easier.  */
   50204                 :         638 :   parser->oacc_routine->clauses = nreverse (parser->oacc_routine->clauses);
   50205                 :         638 :   cp_parser_pop_lexer (parser);
   50206                 :             :   /* Later, cp_finalize_oacc_routine will process the clauses.  */
   50207                 :         638 :   parser->oacc_routine->fndecl_seen = true;
   50208                 :             : 
   50209                 :         638 :   return attrs;
   50210                 :             : }
   50211                 :             : 
   50212                 :             : /* Apply any saved OpenACC routine clauses to a just-parsed
   50213                 :             :    declaration.  */
   50214                 :             : 
   50215                 :             : static void
   50216                 :   255415384 : cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn)
   50217                 :             : {
   50218                 :   255415384 :   if (UNLIKELY (parser->oacc_routine != NULL))
   50219                 :             :     {
   50220                 :             :       /* Keep going if we're in error reporting mode.  */
   50221                 :        1203 :       if (parser->oacc_routine->error_seen
   50222                 :        1191 :           || fndecl == error_mark_node)
   50223                 :             :         return;
   50224                 :             : 
   50225                 :        1191 :       if (TREE_CODE (fndecl) != FUNCTION_DECL)
   50226                 :             :         {
   50227                 :          41 :           if (parser->oacc_routine->fndecl_seen)
   50228                 :             :             {
   50229                 :           8 :               error_at (parser->oacc_routine->loc,
   50230                 :             :                         "%<#pragma acc routine%> not immediately followed by"
   50231                 :             :                         " a single function declaration or definition");
   50232                 :           8 :               parser->oacc_routine = NULL;
   50233                 :           8 :               return;
   50234                 :             :             }
   50235                 :             : 
   50236                 :          33 :           cp_ensure_no_oacc_routine (parser);
   50237                 :          33 :           return;
   50238                 :             :         }
   50239                 :             : 
   50240                 :        1150 :       int compatible
   50241                 :        1150 :         = oacc_verify_routine_clauses (fndecl, &parser->oacc_routine->clauses,
   50242                 :             :                                        parser->oacc_routine->loc,
   50243                 :             :                                        "#pragma acc routine");
   50244                 :        1150 :       if (compatible < 0)
   50245                 :             :         {
   50246                 :         184 :           parser->oacc_routine = NULL;
   50247                 :         184 :           return;
   50248                 :             :         }
   50249                 :         966 :       if (compatible > 0)
   50250                 :             :         {
   50251                 :             :         }
   50252                 :             :       else
   50253                 :             :         {
   50254                 :        1030 :           if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
   50255                 :             :             {
   50256                 :          12 :               error_at (parser->oacc_routine->loc,
   50257                 :             :                         TREE_USED (fndecl)
   50258                 :             :                         ? G_("%<#pragma acc routine%> must be applied before"
   50259                 :             :                              " use")
   50260                 :             :                         : G_("%<#pragma acc routine%> must be applied before"
   50261                 :             :                              " definition"));
   50262                 :           8 :               parser->oacc_routine = NULL;
   50263                 :           8 :               return;
   50264                 :             :             }
   50265                 :             : 
   50266                 :             :           /* Set the routine's level of parallelism.  */
   50267                 :         714 :           tree dims = oacc_build_routine_dims (parser->oacc_routine->clauses);
   50268                 :         714 :           oacc_replace_fn_attrib (fndecl, dims);
   50269                 :             : 
   50270                 :             :           /* Add an "omp declare target" attribute.  */
   50271                 :         714 :           DECL_ATTRIBUTES (fndecl)
   50272                 :        1428 :             = tree_cons (get_identifier ("omp declare target"),
   50273                 :         714 :                          parser->oacc_routine->clauses,
   50274                 :         714 :                          DECL_ATTRIBUTES (fndecl));
   50275                 :             :         }
   50276                 :             :     }
   50277                 :             : }
   50278                 :             : 
   50279                 :             : /* Main entry point to OpenMP statement pragmas.  */
   50280                 :             : 
   50281                 :             : static void
   50282                 :       37293 : cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
   50283                 :             : {
   50284                 :       37293 :   tree stmt;
   50285                 :       37293 :   char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
   50286                 :       37293 :   omp_clause_mask mask (0);
   50287                 :             : 
   50288                 :       37293 :   switch (cp_parser_pragma_kind (pragma_tok))
   50289                 :             :     {
   50290                 :         388 :     case PRAGMA_OACC_ATOMIC:
   50291                 :         388 :       cp_parser_omp_atomic (parser, pragma_tok, true);
   50292                 :        4204 :       return;
   50293                 :         888 :     case PRAGMA_OACC_CACHE:
   50294                 :         888 :       stmt = cp_parser_oacc_cache (parser, pragma_tok);
   50295                 :         888 :       break;
   50296                 :         780 :     case PRAGMA_OACC_DATA:
   50297                 :         780 :       stmt = cp_parser_oacc_data (parser, pragma_tok, if_p);
   50298                 :         780 :       break;
   50299                 :         400 :     case PRAGMA_OACC_ENTER_DATA:
   50300                 :         400 :       stmt = cp_parser_oacc_enter_exit_data (parser, pragma_tok, true);
   50301                 :         400 :       break;
   50302                 :         397 :     case PRAGMA_OACC_EXIT_DATA:
   50303                 :         397 :       stmt = cp_parser_oacc_enter_exit_data (parser, pragma_tok, false);
   50304                 :         397 :       break;
   50305                 :          80 :     case PRAGMA_OACC_HOST_DATA:
   50306                 :          80 :       stmt = cp_parser_oacc_host_data (parser, pragma_tok, if_p);
   50307                 :          80 :       break;
   50308                 :        4836 :     case PRAGMA_OACC_KERNELS:
   50309                 :        4836 :     case PRAGMA_OACC_PARALLEL:
   50310                 :        4836 :     case PRAGMA_OACC_SERIAL:
   50311                 :        4836 :       strcpy (p_name, "#pragma acc");
   50312                 :        4836 :       stmt = cp_parser_oacc_compute (parser, pragma_tok, p_name, if_p);
   50313                 :        4836 :       break;
   50314                 :        4259 :     case PRAGMA_OACC_LOOP:
   50315                 :        4259 :       strcpy (p_name, "#pragma acc");
   50316                 :        4259 :       stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask, NULL,
   50317                 :             :                                   if_p);
   50318                 :        4259 :       break;
   50319                 :         237 :     case PRAGMA_OACC_UPDATE:
   50320                 :         237 :       stmt = cp_parser_oacc_update (parser, pragma_tok);
   50321                 :         237 :       break;
   50322                 :         162 :     case PRAGMA_OACC_WAIT:
   50323                 :         162 :       stmt = cp_parser_oacc_wait (parser, pragma_tok);
   50324                 :         162 :       break;
   50325                 :           0 :     case PRAGMA_OMP_ALLOCATE:
   50326                 :           0 :       cp_parser_omp_allocate (parser, pragma_tok);
   50327                 :           0 :       return;
   50328                 :        3272 :     case PRAGMA_OMP_ATOMIC:
   50329                 :        3272 :       cp_parser_omp_atomic (parser, pragma_tok, false);
   50330                 :        3272 :       return;
   50331                 :         330 :     case PRAGMA_OMP_CRITICAL:
   50332                 :         330 :       stmt = cp_parser_omp_critical (parser, pragma_tok, if_p);
   50333                 :         330 :       break;
   50334                 :        1741 :     case PRAGMA_OMP_DISTRIBUTE:
   50335                 :        1741 :       strcpy (p_name, "#pragma omp");
   50336                 :        1741 :       stmt = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask, NULL,
   50337                 :             :                                        if_p);
   50338                 :        1741 :       break;
   50339                 :        4633 :     case PRAGMA_OMP_FOR:
   50340                 :        4633 :       strcpy (p_name, "#pragma omp");
   50341                 :        4633 :       stmt = cp_parser_omp_for (parser, pragma_tok, p_name, mask, NULL,
   50342                 :             :                                 if_p);
   50343                 :        4633 :       break;
   50344                 :         622 :     case PRAGMA_OMP_LOOP:
   50345                 :         622 :       strcpy (p_name, "#pragma omp");
   50346                 :         622 :       stmt = cp_parser_omp_loop (parser, pragma_tok, p_name, mask, NULL,
   50347                 :             :                                  if_p);
   50348                 :         622 :       break;
   50349                 :         167 :     case PRAGMA_OMP_MASKED:
   50350                 :         167 :       strcpy (p_name, "#pragma omp");
   50351                 :         167 :       stmt = cp_parser_omp_masked (parser, pragma_tok, p_name, mask, NULL,
   50352                 :             :                                    if_p);
   50353                 :         167 :       break;
   50354                 :         410 :     case PRAGMA_OMP_MASTER:
   50355                 :         410 :       strcpy (p_name, "#pragma omp");
   50356                 :         410 :       stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
   50357                 :             :                                    if_p);
   50358                 :         410 :       break;
   50359                 :        5126 :     case PRAGMA_OMP_PARALLEL:
   50360                 :        5126 :       strcpy (p_name, "#pragma omp");
   50361                 :        5126 :       stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask, NULL,
   50362                 :             :                                      if_p);
   50363                 :        5126 :       break;
   50364                 :         133 :     case PRAGMA_OMP_SCOPE:
   50365                 :         133 :       stmt = cp_parser_omp_scope (parser, pragma_tok, if_p);
   50366                 :         133 :       break;
   50367                 :         314 :     case PRAGMA_OMP_SECTIONS:
   50368                 :         314 :       strcpy (p_name, "#pragma omp");
   50369                 :         314 :       stmt = cp_parser_omp_sections (parser, pragma_tok, p_name, mask, NULL);
   50370                 :         314 :       break;
   50371                 :        1238 :     case PRAGMA_OMP_SIMD:
   50372                 :        1238 :       strcpy (p_name, "#pragma omp");
   50373                 :        1238 :       stmt = cp_parser_omp_simd (parser, pragma_tok, p_name, mask, NULL,
   50374                 :             :                                  if_p);
   50375                 :        1238 :       break;
   50376                 :         434 :     case PRAGMA_OMP_SINGLE:
   50377                 :         434 :       stmt = cp_parser_omp_single (parser, pragma_tok, if_p);
   50378                 :         434 :       break;
   50379                 :        2478 :     case PRAGMA_OMP_TASK:
   50380                 :        2478 :       stmt = cp_parser_omp_task (parser, pragma_tok, if_p);
   50381                 :        2478 :       break;
   50382                 :         345 :     case PRAGMA_OMP_TASKGROUP:
   50383                 :         345 :       stmt = cp_parser_omp_taskgroup (parser, pragma_tok, if_p);
   50384                 :         345 :       break;
   50385                 :         673 :     case PRAGMA_OMP_TASKLOOP:
   50386                 :         673 :       strcpy (p_name, "#pragma omp");
   50387                 :         673 :       stmt = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask, NULL,
   50388                 :             :                                      if_p);
   50389                 :         673 :       break;
   50390                 :        2794 :     case PRAGMA_OMP_TEAMS:
   50391                 :        2794 :       strcpy (p_name, "#pragma omp");
   50392                 :        2794 :       stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL,
   50393                 :             :                                   if_p);
   50394                 :        2794 :       break;
   50395                 :         156 :     case PRAGMA_OMP_ASSUME:
   50396                 :         156 :       cp_parser_omp_assume (parser, pragma_tok, if_p);
   50397                 :         156 :       return;
   50398                 :           0 :     default:
   50399                 :           0 :       gcc_unreachable ();
   50400                 :             :     }
   50401                 :             : 
   50402                 :       33477 :   protected_set_expr_location (stmt, pragma_tok->location);
   50403                 :             : }
   50404                 :             : 
   50405                 :             : /* Transactional Memory parsing routines.  */
   50406                 :             : 
   50407                 :             : /* Parse a transaction attribute.
   50408                 :             : 
   50409                 :             :    txn-attribute:
   50410                 :             :         attribute
   50411                 :             :         [ [ identifier ] ]
   50412                 :             : 
   50413                 :             :    We use this instead of cp_parser_attributes_opt for transactions to avoid
   50414                 :             :    the pedwarn in C++98 mode.  */
   50415                 :             : 
   50416                 :             : static tree
   50417                 :         273 : cp_parser_txn_attribute_opt (cp_parser *parser)
   50418                 :             : {
   50419                 :         273 :   cp_token *token;
   50420                 :         273 :   tree attr_name, attr = NULL;
   50421                 :             : 
   50422                 :         273 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
   50423                 :           6 :     return cp_parser_attributes_opt (parser);
   50424                 :             : 
   50425                 :         267 :   if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
   50426                 :             :     return NULL_TREE;
   50427                 :          26 :   cp_lexer_consume_token (parser->lexer);
   50428                 :          26 :   if (!cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE))
   50429                 :           0 :     goto error1;
   50430                 :             : 
   50431                 :          26 :   token = cp_lexer_peek_token (parser->lexer);
   50432                 :          26 :   if (token->type == CPP_NAME || token->type == CPP_KEYWORD)
   50433                 :             :     {
   50434                 :          26 :       token = cp_lexer_consume_token (parser->lexer);
   50435                 :             : 
   50436                 :          52 :       attr_name = (token->type == CPP_KEYWORD
   50437                 :             :                    /* For keywords, use the canonical spelling,
   50438                 :             :                       not the parsed identifier.  */
   50439                 :          26 :                    ? ridpointers[(int) token->keyword]
   50440                 :             :                    : token->u.value);
   50441                 :          26 :       attr = build_tree_list (attr_name, NULL_TREE);
   50442                 :             :     }
   50443                 :             :   else
   50444                 :           0 :     cp_parser_error (parser, "expected identifier");
   50445                 :             : 
   50446                 :          26 :   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
   50447                 :          26 :  error1:
   50448                 :          26 :   cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
   50449                 :          26 :   return attr;
   50450                 :             : }
   50451                 :             : 
   50452                 :             : /* Parse a __transaction_atomic or __transaction_relaxed statement.
   50453                 :             : 
   50454                 :             :    transaction-statement:
   50455                 :             :      __transaction_atomic txn-attribute[opt] txn-noexcept-spec[opt]
   50456                 :             :        compound-statement
   50457                 :             :      __transaction_relaxed txn-noexcept-spec[opt] compound-statement
   50458                 :             : */
   50459                 :             : 
   50460                 :             : static tree
   50461                 :         297 : cp_parser_transaction (cp_parser *parser, cp_token *token)
   50462                 :             : {
   50463                 :         297 :   unsigned char old_in = parser->in_transaction;
   50464                 :         297 :   unsigned char this_in = 1, new_in;
   50465                 :         297 :   enum rid keyword = token->keyword;
   50466                 :         297 :   tree stmt, attrs, noex;
   50467                 :             : 
   50468                 :         297 :   cp_lexer_consume_token (parser->lexer);
   50469                 :             : 
   50470                 :         297 :   if (keyword == RID_TRANSACTION_RELAXED
   50471                 :         297 :       || keyword == RID_SYNCHRONIZED)
   50472                 :             :     this_in |= TM_STMT_ATTR_RELAXED;
   50473                 :             :   else
   50474                 :             :     {
   50475                 :         233 :       attrs = cp_parser_txn_attribute_opt (parser);
   50476                 :         233 :       if (attrs)
   50477                 :          20 :         this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
   50478                 :             :     }
   50479                 :             : 
   50480                 :             :   /* Parse a noexcept specification.  */
   50481                 :         233 :   if (keyword == RID_ATOMIC_NOEXCEPT)
   50482                 :           4 :     noex = boolean_true_node;
   50483                 :         293 :   else if (keyword == RID_ATOMIC_CANCEL)
   50484                 :             :     {
   50485                 :             :       /* cancel-and-throw is unimplemented.  */
   50486                 :           0 :       sorry ("%<atomic_cancel%>");
   50487                 :           0 :       noex = NULL_TREE;
   50488                 :             :     }
   50489                 :             :   else
   50490                 :         293 :     noex = cp_parser_noexcept_specification_opt (parser,
   50491                 :             :                                                  CP_PARSER_FLAGS_NONE,
   50492                 :             :                                                  /*require_constexpr=*/true,
   50493                 :             :                                                  /*consumed_expr=*/NULL,
   50494                 :             :                                                  /*return_cond=*/true);
   50495                 :             : 
   50496                 :             :   /* Keep track if we're in the lexical scope of an outer transaction.  */
   50497                 :         297 :   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
   50498                 :             : 
   50499                 :         297 :   stmt = begin_transaction_stmt (token->location, NULL, this_in);
   50500                 :             : 
   50501                 :         297 :   parser->in_transaction = new_in;
   50502                 :         297 :   cp_parser_compound_statement (parser, NULL, BCS_TRANSACTION, false);
   50503                 :         297 :   parser->in_transaction = old_in;
   50504                 :             : 
   50505                 :         297 :   finish_transaction_stmt (stmt, NULL, this_in, noex);
   50506                 :             : 
   50507                 :         297 :   return stmt;
   50508                 :             : }
   50509                 :             : 
   50510                 :             : /* Parse a __transaction_atomic or __transaction_relaxed expression.
   50511                 :             : 
   50512                 :             :    transaction-expression:
   50513                 :             :      __transaction_atomic txn-noexcept-spec[opt] ( expression )
   50514                 :             :      __transaction_relaxed txn-noexcept-spec[opt] ( expression )
   50515                 :             : */
   50516                 :             : 
   50517                 :             : static tree
   50518                 :          89 : cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
   50519                 :             : {
   50520                 :          89 :   unsigned char old_in = parser->in_transaction;
   50521                 :          89 :   unsigned char this_in = 1;
   50522                 :          89 :   cp_token *token;
   50523                 :          89 :   tree expr, noex;
   50524                 :          89 :   bool noex_expr;
   50525                 :          89 :   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   50526                 :             : 
   50527                 :          89 :   gcc_assert (keyword == RID_TRANSACTION_ATOMIC
   50528                 :             :       || keyword == RID_TRANSACTION_RELAXED);
   50529                 :             : 
   50530                 :          89 :   if (!flag_tm)
   50531                 :          15 :     error_at (loc,
   50532                 :             :               keyword == RID_TRANSACTION_RELAXED
   50533                 :             :               ? G_("%<__transaction_relaxed%> without transactional memory "
   50534                 :             :                   "support enabled")
   50535                 :             :               : G_("%<__transaction_atomic%> without transactional memory "
   50536                 :             :                    "support enabled"));
   50537                 :             : 
   50538                 :          94 :   token = cp_parser_require_keyword (parser, keyword,
   50539                 :             :       (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
   50540                 :             :           : RT_TRANSACTION_RELAXED));
   50541                 :          89 :   gcc_assert (token != NULL);
   50542                 :             : 
   50543                 :          89 :   if (keyword == RID_TRANSACTION_RELAXED)
   50544                 :           5 :     this_in |= TM_STMT_ATTR_RELAXED;
   50545                 :             : 
   50546                 :             :   /* Set this early.  This might mean that we allow transaction_cancel in
   50547                 :             :      an expression that we find out later actually has to be a constexpr.
   50548                 :             :      However, we expect that cxx_constant_value will be able to deal with
   50549                 :             :      this; also, if the noexcept has no constexpr, then what we parse next
   50550                 :             :      really is a transaction's body.  */
   50551                 :          89 :   parser->in_transaction = this_in;
   50552                 :             : 
   50553                 :             :   /* Parse a noexcept specification.  */
   50554                 :          89 :   noex = cp_parser_noexcept_specification_opt (parser,
   50555                 :             :                                                CP_PARSER_FLAGS_NONE,
   50556                 :             :                                                /*require_constexpr=*/false,
   50557                 :             :                                                &noex_expr,
   50558                 :             :                                                /*return_cond=*/true);
   50559                 :             : 
   50560                 :          57 :   if (!noex || !noex_expr
   50561                 :         146 :       || cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
   50562                 :             :     {
   50563                 :          77 :       matching_parens parens;
   50564                 :          77 :       parens.require_open (parser);
   50565                 :             : 
   50566                 :          77 :       expr = cp_parser_expression (parser);
   50567                 :          77 :       expr = finish_parenthesized_expr (expr);
   50568                 :             : 
   50569                 :          77 :       parens.require_close (parser);
   50570                 :             :     }
   50571                 :             :   else
   50572                 :             :     {
   50573                 :             :       /* The only expression that is available got parsed for the noexcept
   50574                 :             :          already.  noexcept is true then.  */
   50575                 :          12 :       expr = noex;
   50576                 :          12 :       noex = boolean_true_node;
   50577                 :             :     }
   50578                 :             : 
   50579                 :          89 :   expr = build_transaction_expr (token->location, expr, this_in, noex);
   50580                 :          89 :   parser->in_transaction = old_in;
   50581                 :             : 
   50582                 :          89 :   if (cp_parser_non_integral_constant_expression (parser, NIC_TRANSACTION))
   50583                 :           0 :     return error_mark_node;
   50584                 :             : 
   50585                 :          89 :   return (flag_tm ? expr : error_mark_node);
   50586                 :             : }
   50587                 :             : 
   50588                 :             : /* Parse a function-transaction-block.
   50589                 :             : 
   50590                 :             :    function-transaction-block:
   50591                 :             :      __transaction_atomic txn-attribute[opt] ctor-initializer[opt]
   50592                 :             :          function-body
   50593                 :             :      __transaction_atomic txn-attribute[opt] function-try-block
   50594                 :             :      __transaction_relaxed ctor-initializer[opt] function-body
   50595                 :             :      __transaction_relaxed function-try-block
   50596                 :             : */
   50597                 :             : 
   50598                 :             : static void
   50599                 :          24 : cp_parser_function_transaction (cp_parser *parser, enum rid keyword)
   50600                 :             : {
   50601                 :          24 :   unsigned char old_in = parser->in_transaction;
   50602                 :          24 :   unsigned char new_in = 1;
   50603                 :          24 :   tree compound_stmt, stmt, attrs;
   50604                 :          24 :   cp_token *token;
   50605                 :             : 
   50606                 :          24 :   gcc_assert (keyword == RID_TRANSACTION_ATOMIC
   50607                 :             :       || keyword == RID_TRANSACTION_RELAXED);
   50608                 :          24 :   token = cp_parser_require_keyword (parser, keyword,
   50609                 :             :       (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
   50610                 :             :           : RT_TRANSACTION_RELAXED));
   50611                 :          24 :   gcc_assert (token != NULL);
   50612                 :             : 
   50613                 :          24 :   if (keyword == RID_TRANSACTION_RELAXED)
   50614                 :             :     new_in |= TM_STMT_ATTR_RELAXED;
   50615                 :             :   else
   50616                 :             :     {
   50617                 :          24 :       attrs = cp_parser_txn_attribute_opt (parser);
   50618                 :          24 :       if (attrs)
   50619                 :          12 :         new_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
   50620                 :             :     }
   50621                 :             : 
   50622                 :          24 :   stmt = begin_transaction_stmt (token->location, &compound_stmt, new_in);
   50623                 :             : 
   50624                 :          24 :   parser->in_transaction = new_in;
   50625                 :             : 
   50626                 :          24 :   if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
   50627                 :          12 :     cp_parser_function_try_block (parser);
   50628                 :             :   else
   50629                 :          12 :     cp_parser_ctor_initializer_opt_and_function_body
   50630                 :          12 :       (parser, /*in_function_try_block=*/false);
   50631                 :             : 
   50632                 :          24 :   parser->in_transaction = old_in;
   50633                 :             : 
   50634                 :          24 :   finish_transaction_stmt (stmt, compound_stmt, new_in, NULL_TREE);
   50635                 :          24 : }
   50636                 :             : 
   50637                 :             : /* Parse a __transaction_cancel statement.
   50638                 :             : 
   50639                 :             :    cancel-statement:
   50640                 :             :      __transaction_cancel txn-attribute[opt] ;
   50641                 :             :      __transaction_cancel txn-attribute[opt] throw-expression ;
   50642                 :             : 
   50643                 :             :    ??? Cancel and throw is not yet implemented.  */
   50644                 :             : 
   50645                 :             : static tree
   50646                 :          16 : cp_parser_transaction_cancel (cp_parser *parser)
   50647                 :             : {
   50648                 :          16 :   cp_token *token;
   50649                 :          16 :   bool is_outer = false;
   50650                 :          16 :   tree stmt, attrs;
   50651                 :             : 
   50652                 :          16 :   token = cp_parser_require_keyword (parser, RID_TRANSACTION_CANCEL,
   50653                 :             :                                      RT_TRANSACTION_CANCEL);
   50654                 :          16 :   gcc_assert (token != NULL);
   50655                 :             : 
   50656                 :          16 :   attrs = cp_parser_txn_attribute_opt (parser);
   50657                 :          16 :   if (attrs)
   50658                 :           0 :     is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
   50659                 :             : 
   50660                 :             :   /* ??? Parse cancel-and-throw here.  */
   50661                 :             : 
   50662                 :          16 :   cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
   50663                 :             : 
   50664                 :          16 :   if (!flag_tm)
   50665                 :             :     {
   50666                 :           8 :       error_at (token->location, "%<__transaction_cancel%> without "
   50667                 :             :                 "transactional memory support enabled");
   50668                 :           8 :       return error_mark_node;
   50669                 :             :     }
   50670                 :           8 :   else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
   50671                 :             :     {
   50672                 :           0 :       error_at (token->location, "%<__transaction_cancel%> within a "
   50673                 :             :                 "%<__transaction_relaxed%>");
   50674                 :           0 :       return error_mark_node;
   50675                 :             :     }
   50676                 :           8 :   else if (is_outer)
   50677                 :             :     {
   50678                 :           0 :       if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
   50679                 :           0 :           && !is_tm_may_cancel_outer (current_function_decl))
   50680                 :             :         {
   50681                 :           0 :           error_at (token->location, "outer %<__transaction_cancel%> not "
   50682                 :             :                     "within outer %<__transaction_atomic%>");
   50683                 :           0 :           error_at (token->location,
   50684                 :             :                     "  or a %<transaction_may_cancel_outer%> function");
   50685                 :           0 :           return error_mark_node;
   50686                 :             :         }
   50687                 :             :     }
   50688                 :           8 :   else if (parser->in_transaction == 0)
   50689                 :             :     {
   50690                 :           0 :       error_at (token->location, "%<__transaction_cancel%> not within "
   50691                 :             :                 "%<__transaction_atomic%>");
   50692                 :           0 :       return error_mark_node;
   50693                 :             :     }
   50694                 :             : 
   50695                 :           8 :   stmt = build_tm_abort_call (token->location, is_outer);
   50696                 :           8 :   add_stmt (stmt);
   50697                 :             : 
   50698                 :           8 :   return stmt;
   50699                 :             : }
   50700                 :             : 
   50701                 :             : 
   50702                 :             : /* Special handling for the first token or line in the file.  The first
   50703                 :             :    thing in the file might be #pragma GCC pch_preprocess, which loads a
   50704                 :             :    PCH file, which is a GC collection point.  So we need to handle this
   50705                 :             :    first pragma without benefit of an existing lexer structure.
   50706                 :             : 
   50707                 :             :    Always returns one token to the caller in *FIRST_TOKEN.  This is
   50708                 :             :    either the true first token of the file, or the first token after
   50709                 :             :    the initial pragma.  */
   50710                 :             : 
   50711                 :             : static void
   50712                 :       99855 : cp_parser_initial_pragma (cp_token *first_token)
   50713                 :             : {
   50714                 :       99855 :   if (cp_parser_pragma_kind (first_token) != PRAGMA_GCC_PCH_PREPROCESS)
   50715                 :             :     return;
   50716                 :             : 
   50717                 :           6 :   cp_lexer_get_preprocessor_token (0, first_token);
   50718                 :             : 
   50719                 :           6 :   tree name = NULL;
   50720                 :           6 :   if (first_token->type == CPP_STRING)
   50721                 :             :     {
   50722                 :           6 :       name = first_token->u.value;
   50723                 :             : 
   50724                 :           6 :       cp_lexer_get_preprocessor_token (0, first_token);
   50725                 :             :     }
   50726                 :             : 
   50727                 :             :   /* Skip to the end of the pragma.  */
   50728                 :           6 :   if (first_token->type != CPP_PRAGMA_EOL)
   50729                 :             :     {
   50730                 :           0 :       error_at (first_token->location,
   50731                 :             :                 "malformed %<#pragma GCC pch_preprocess%>");
   50732                 :           0 :       do
   50733                 :           0 :         cp_lexer_get_preprocessor_token (0, first_token);
   50734                 :           0 :       while (first_token->type != CPP_PRAGMA_EOL);
   50735                 :             :     }
   50736                 :             : 
   50737                 :             :   /* Now actually load the PCH file.  */
   50738                 :           6 :   if (name)
   50739                 :           6 :     c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
   50740                 :             : 
   50741                 :             :   /* Read one more token to return to our caller.  We have to do this
   50742                 :             :      after reading the PCH file in, since its pointers have to be
   50743                 :             :      live.  */
   50744                 :           6 :   cp_lexer_get_preprocessor_token (0, first_token);
   50745                 :             : }
   50746                 :             : 
   50747                 :             : /* Parse a pragma GCC ivdep.  */
   50748                 :             : 
   50749                 :             : static bool
   50750                 :          73 : cp_parser_pragma_ivdep (cp_parser *parser, cp_token *pragma_tok)
   50751                 :             : {
   50752                 :           0 :   cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   50753                 :          73 :   return true;
   50754                 :             : }
   50755                 :             : 
   50756                 :             : /* Parse a pragma GCC unroll.  */
   50757                 :             : 
   50758                 :             : static tree
   50759                 :         276 : cp_parser_pragma_unroll (cp_parser *parser, cp_token *pragma_tok)
   50760                 :             : {
   50761                 :         276 :   location_t location = cp_lexer_peek_token (parser->lexer)->location;
   50762                 :         276 :   tree unroll = cp_parser_constant_expression (parser);
   50763                 :         276 :   unroll = cp_check_pragma_unroll (location, fold_non_dependent_expr (unroll));
   50764                 :         276 :   cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   50765                 :         276 :   return unroll;
   50766                 :             : }
   50767                 :             : 
   50768                 :             : /* Parse a pragma GCC novector.  */
   50769                 :             : 
   50770                 :             : static bool
   50771                 :         202 : cp_parser_pragma_novector (cp_parser *parser, cp_token *pragma_tok)
   50772                 :             : {
   50773                 :           0 :   cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   50774                 :         202 :   return true;
   50775                 :             : }
   50776                 :             : 
   50777                 :             : /* Normal parsing of a pragma token.  Here we can (and must) use the
   50778                 :             :    regular lexer.  */
   50779                 :             : 
   50780                 :             : static bool
   50781                 :     1935214 : cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
   50782                 :             : {
   50783                 :     1935214 :   cp_token *pragma_tok;
   50784                 :     1935214 :   unsigned int id;
   50785                 :     1935214 :   tree stmt;
   50786                 :     1935214 :   bool ret = false;
   50787                 :             : 
   50788                 :     1935214 :   pragma_tok = cp_lexer_consume_token (parser->lexer);
   50789                 :     1935214 :   gcc_assert (pragma_tok->type == CPP_PRAGMA);
   50790                 :     1935214 :   parser->lexer->in_pragma = true;
   50791                 :             : 
   50792                 :     1935214 :   id = cp_parser_pragma_kind (pragma_tok);
   50793                 :     1935214 :   if (parser->omp_for_parse_state
   50794                 :          38 :       && parser->omp_for_parse_state->in_intervening_code
   50795                 :             :       && id >= PRAGMA_OMP__START_
   50796                 :          38 :       && id <= PRAGMA_OMP__LAST_)
   50797                 :             :     {
   50798                 :          14 :       error_at (pragma_tok->location,
   50799                 :             :                 "intervening code must not contain OpenMP directives");
   50800                 :          14 :       parser->omp_for_parse_state->fail = true;
   50801                 :          14 :       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   50802                 :          14 :       return false;
   50803                 :             :     }
   50804                 :     1935200 :   if (id != PRAGMA_OMP_DECLARE && id != PRAGMA_OACC_ROUTINE)
   50805                 :     1929563 :     cp_ensure_no_omp_declare_simd (parser);
   50806                 :     1935200 :   switch (id)
   50807                 :             :     {
   50808                 :           4 :     case PRAGMA_GCC_PCH_PREPROCESS:
   50809                 :           4 :       error_at (pragma_tok->location,
   50810                 :             :                 "%<#pragma GCC pch_preprocess%> must be first");
   50811                 :           4 :       break;
   50812                 :             : 
   50813                 :         594 :     case PRAGMA_OMP_BARRIER:
   50814                 :         594 :       switch (context)
   50815                 :             :         {
   50816                 :         558 :         case pragma_compound:
   50817                 :         558 :           cp_parser_omp_barrier (parser, pragma_tok);
   50818                 :         558 :           return false;
   50819                 :          36 :         case pragma_stmt:
   50820                 :          36 :           error_at (pragma_tok->location, "%<#pragma %s%> may only be "
   50821                 :             :                     "used in compound statements", "omp barrier");
   50822                 :          36 :           ret = true;
   50823                 :          36 :           break;
   50824                 :           0 :         default:
   50825                 :           0 :           goto bad_stmt;
   50826                 :             :         }
   50827                 :          36 :       break;
   50828                 :             : 
   50829                 :         383 :     case PRAGMA_OMP_DEPOBJ:
   50830                 :         383 :       switch (context)
   50831                 :             :         {
   50832                 :         375 :         case pragma_compound:
   50833                 :         375 :           cp_parser_omp_depobj (parser, pragma_tok);
   50834                 :         375 :           return false;
   50835                 :           8 :         case pragma_stmt:
   50836                 :           8 :           error_at (pragma_tok->location, "%<#pragma %s%> may only be "
   50837                 :             :                     "used in compound statements", "omp depobj");
   50838                 :           8 :           ret = true;
   50839                 :           8 :           break;
   50840                 :           0 :         default:
   50841                 :           0 :           goto bad_stmt;
   50842                 :             :         }
   50843                 :           8 :       break;
   50844                 :             : 
   50845                 :         226 :     case PRAGMA_OMP_FLUSH:
   50846                 :         226 :       switch (context)
   50847                 :             :         {
   50848                 :         188 :         case pragma_compound:
   50849                 :         188 :           cp_parser_omp_flush (parser, pragma_tok);
   50850                 :         188 :           return false;
   50851                 :          38 :         case pragma_stmt:
   50852                 :          38 :           error_at (pragma_tok->location, "%<#pragma %s%> may only be "
   50853                 :             :                     "used in compound statements", "omp flush");
   50854                 :          38 :           ret = true;
   50855                 :          38 :           break;
   50856                 :           0 :         default:
   50857                 :           0 :           goto bad_stmt;
   50858                 :             :         }
   50859                 :          38 :       break;
   50860                 :             : 
   50861                 :         193 :     case PRAGMA_OMP_TASKWAIT:
   50862                 :         193 :       switch (context)
   50863                 :             :         {
   50864                 :         161 :         case pragma_compound:
   50865                 :         161 :           cp_parser_omp_taskwait (parser, pragma_tok);
   50866                 :         161 :           return false;
   50867                 :          32 :         case pragma_stmt:
   50868                 :          32 :           error_at (pragma_tok->location,
   50869                 :             :                     "%<#pragma %s%> may only be used in compound statements",
   50870                 :             :                     "omp taskwait");
   50871                 :          32 :           ret = true;
   50872                 :          32 :           break;
   50873                 :           0 :         default:
   50874                 :           0 :           goto bad_stmt;
   50875                 :             :         }
   50876                 :          32 :       break;
   50877                 :             : 
   50878                 :          49 :     case PRAGMA_OMP_TASKYIELD:
   50879                 :          49 :       switch (context)
   50880                 :             :         {
   50881                 :          17 :         case pragma_compound:
   50882                 :          17 :           cp_parser_omp_taskyield (parser, pragma_tok);
   50883                 :          17 :           return false;
   50884                 :          32 :         case pragma_stmt:
   50885                 :          32 :           error_at (pragma_tok->location,
   50886                 :             :                     "%<#pragma %s%> may only be used in compound statements",
   50887                 :             :                     "omp taskyield");
   50888                 :          32 :           ret = true;
   50889                 :          32 :           break;
   50890                 :           0 :         default:
   50891                 :           0 :           goto bad_stmt;
   50892                 :             :         }
   50893                 :          32 :       break;
   50894                 :             : 
   50895                 :         811 :     case PRAGMA_OMP_CANCEL:
   50896                 :         811 :       switch (context)
   50897                 :             :         {
   50898                 :         779 :         case pragma_compound:
   50899                 :         779 :           cp_parser_omp_cancel (parser, pragma_tok);
   50900                 :         779 :           return false;
   50901                 :          32 :         case pragma_stmt:
   50902                 :          32 :           error_at (pragma_tok->location,
   50903                 :             :                     "%<#pragma %s%> may only be used in compound statements",
   50904                 :             :                     "omp cancel");
   50905                 :          32 :           ret = true;
   50906                 :          32 :           break;
   50907                 :           0 :         default:
   50908                 :           0 :           goto bad_stmt;
   50909                 :             :         }
   50910                 :          32 :       break;
   50911                 :             : 
   50912                 :         700 :     case PRAGMA_OMP_CANCELLATION_POINT:
   50913                 :         700 :       return cp_parser_omp_cancellation_point (parser, pragma_tok, context);
   50914                 :             : 
   50915                 :         277 :     case PRAGMA_OMP_THREADPRIVATE:
   50916                 :         277 :       cp_parser_omp_threadprivate (parser, pragma_tok);
   50917                 :         277 :       return false;
   50918                 :             : 
   50919                 :        4291 :     case PRAGMA_OMP_DECLARE:
   50920                 :        4291 :       return cp_parser_omp_declare (parser, pragma_tok, context);
   50921                 :             : 
   50922                 :         541 :     case PRAGMA_OACC_DECLARE:
   50923                 :         541 :       cp_parser_oacc_declare (parser, pragma_tok);
   50924                 :         541 :       return false;
   50925                 :             : 
   50926                 :         412 :     case PRAGMA_OACC_ENTER_DATA:
   50927                 :         412 :       if (context == pragma_stmt)
   50928                 :             :         {
   50929                 :          12 :           error_at (pragma_tok->location,
   50930                 :             :                     "%<#pragma %s%> may only be used in compound statements",
   50931                 :             :                     "acc enter data");
   50932                 :          12 :           ret = true;
   50933                 :          12 :           break;
   50934                 :             :         }
   50935                 :         400 :       else if (context != pragma_compound)
   50936                 :           0 :         goto bad_stmt;
   50937                 :         400 :       cp_parser_omp_construct (parser, pragma_tok, if_p);
   50938                 :         400 :       return true;
   50939                 :             : 
   50940                 :         409 :     case PRAGMA_OACC_EXIT_DATA:
   50941                 :         409 :       if (context == pragma_stmt)
   50942                 :             :         {
   50943                 :          12 :           error_at (pragma_tok->location,
   50944                 :             :                     "%<#pragma %s%> may only be used in compound statements",
   50945                 :             :                     "acc exit data");
   50946                 :          12 :           ret = true;
   50947                 :          12 :           break;
   50948                 :             :         }
   50949                 :         397 :       else if (context != pragma_compound)
   50950                 :           0 :         goto bad_stmt;
   50951                 :         397 :       cp_parser_omp_construct (parser, pragma_tok, if_p);
   50952                 :         397 :       return true;
   50953                 :             : 
   50954                 :        1346 :     case PRAGMA_OACC_ROUTINE:
   50955                 :        1346 :       if (context != pragma_external)
   50956                 :             :         {
   50957                 :          16 :           error_at (pragma_tok->location,
   50958                 :             :                     "%<#pragma acc routine%> must be at file scope");
   50959                 :          16 :           ret = true;
   50960                 :          16 :           break;
   50961                 :             :         }
   50962                 :        1330 :       cp_parser_oacc_routine (parser, pragma_tok, context);
   50963                 :        1330 :       return false;
   50964                 :             : 
   50965                 :         253 :     case PRAGMA_OACC_UPDATE:
   50966                 :         253 :       if (context == pragma_stmt)
   50967                 :             :         {
   50968                 :          16 :           error_at (pragma_tok->location,
   50969                 :             :                     "%<#pragma %s%> may only be used in compound statements",
   50970                 :             :                     "acc update");
   50971                 :          16 :           ret = true;
   50972                 :          16 :           break;
   50973                 :             :         }
   50974                 :         237 :       else if (context != pragma_compound)
   50975                 :           0 :         goto bad_stmt;
   50976                 :         237 :       cp_parser_omp_construct (parser, pragma_tok, if_p);
   50977                 :         237 :       return true;
   50978                 :             : 
   50979                 :         174 :     case PRAGMA_OACC_WAIT:
   50980                 :         174 :       if (context == pragma_stmt)
   50981                 :             :         {
   50982                 :          12 :           error_at (pragma_tok->location,
   50983                 :             :                     "%<#pragma %s%> may only be used in compound statements",
   50984                 :             :                     "acc wait");
   50985                 :          12 :           ret = true;
   50986                 :          12 :           break;
   50987                 :             :         }
   50988                 :         162 :       else if (context != pragma_compound)
   50989                 :           0 :         goto bad_stmt;
   50990                 :         162 :       cp_parser_omp_construct (parser, pragma_tok, if_p);
   50991                 :         162 :       return true;
   50992                 :         128 :     case PRAGMA_OMP_ALLOCATE:
   50993                 :         128 :       cp_parser_omp_allocate (parser, pragma_tok);
   50994                 :         128 :       return false;
   50995                 :       36105 :     case PRAGMA_OACC_ATOMIC:
   50996                 :       36105 :     case PRAGMA_OACC_CACHE:
   50997                 :       36105 :     case PRAGMA_OACC_DATA:
   50998                 :       36105 :     case PRAGMA_OACC_HOST_DATA:
   50999                 :       36105 :     case PRAGMA_OACC_KERNELS:
   51000                 :       36105 :     case PRAGMA_OACC_LOOP:
   51001                 :       36105 :     case PRAGMA_OACC_PARALLEL:
   51002                 :       36105 :     case PRAGMA_OACC_SERIAL:
   51003                 :       36105 :     case PRAGMA_OMP_ASSUME:
   51004                 :       36105 :     case PRAGMA_OMP_ATOMIC:
   51005                 :       36105 :     case PRAGMA_OMP_CRITICAL:
   51006                 :       36105 :     case PRAGMA_OMP_DISTRIBUTE:
   51007                 :       36105 :     case PRAGMA_OMP_FOR:
   51008                 :       36105 :     case PRAGMA_OMP_LOOP:
   51009                 :       36105 :     case PRAGMA_OMP_MASKED:
   51010                 :       36105 :     case PRAGMA_OMP_MASTER:
   51011                 :       36105 :     case PRAGMA_OMP_PARALLEL:
   51012                 :       36105 :     case PRAGMA_OMP_SCOPE:
   51013                 :       36105 :     case PRAGMA_OMP_SECTIONS:
   51014                 :       36105 :     case PRAGMA_OMP_SIMD:
   51015                 :       36105 :     case PRAGMA_OMP_SINGLE:
   51016                 :       36105 :     case PRAGMA_OMP_TASK:
   51017                 :       36105 :     case PRAGMA_OMP_TASKGROUP:
   51018                 :       36105 :     case PRAGMA_OMP_TASKLOOP:
   51019                 :       36105 :     case PRAGMA_OMP_TEAMS:
   51020                 :       36105 :       if (context != pragma_stmt && context != pragma_compound)
   51021                 :           8 :         goto bad_stmt;
   51022                 :       36097 :       stmt = push_omp_privatization_clauses (false);
   51023                 :       36097 :       cp_parser_omp_construct (parser, pragma_tok, if_p);
   51024                 :       36097 :       pop_omp_privatization_clauses (stmt);
   51025                 :       36097 :       return true;
   51026                 :             : 
   51027                 :         227 :     case PRAGMA_OMP_REQUIRES:
   51028                 :         227 :       if (context != pragma_external)
   51029                 :             :         {
   51030                 :          32 :           error_at (pragma_tok->location,
   51031                 :             :                     "%<#pragma omp requires%> may only be used at file or "
   51032                 :             :                     "namespace scope");
   51033                 :          32 :           ret = true;
   51034                 :          32 :           break;
   51035                 :             :         }
   51036                 :         195 :       return cp_parser_omp_requires (parser, pragma_tok);
   51037                 :             : 
   51038                 :         144 :     case PRAGMA_OMP_ASSUMES:
   51039                 :         144 :       if (context != pragma_external)
   51040                 :             :         {
   51041                 :           4 :           error_at (pragma_tok->location,
   51042                 :             :                     "%<#pragma omp assumes%> may only be used at file or "
   51043                 :             :                     "namespace scope");
   51044                 :           4 :           ret = true;
   51045                 :           4 :           break;
   51046                 :             :         }
   51047                 :         140 :       return cp_parser_omp_assumes (parser, pragma_tok);
   51048                 :             : 
   51049                 :          62 :     case PRAGMA_OMP_NOTHING:
   51050                 :          62 :       cp_parser_omp_nothing (parser, pragma_tok);
   51051                 :          62 :       return false;
   51052                 :             : 
   51053                 :         324 :     case PRAGMA_OMP_ERROR:
   51054                 :         324 :       return cp_parser_omp_error (parser, pragma_tok, context);
   51055                 :             : 
   51056                 :        1317 :     case PRAGMA_OMP_ORDERED:
   51057                 :        1317 :       if (context != pragma_stmt && context != pragma_compound)
   51058                 :           8 :         goto bad_stmt;
   51059                 :        1309 :       stmt = push_omp_privatization_clauses (false);
   51060                 :        1309 :       ret = cp_parser_omp_ordered (parser, pragma_tok, context, if_p);
   51061                 :        1309 :       pop_omp_privatization_clauses (stmt);
   51062                 :        1309 :       return ret;
   51063                 :             : 
   51064                 :       11144 :     case PRAGMA_OMP_TARGET:
   51065                 :       11144 :       if (context != pragma_stmt && context != pragma_compound)
   51066                 :           8 :         goto bad_stmt;
   51067                 :       11136 :       stmt = push_omp_privatization_clauses (false);
   51068                 :       11136 :       ret = cp_parser_omp_target (parser, pragma_tok, context, if_p);
   51069                 :       11136 :       pop_omp_privatization_clauses (stmt);
   51070                 :       11136 :       return ret;
   51071                 :             : 
   51072                 :         305 :     case PRAGMA_OMP_BEGIN:
   51073                 :         305 :       cp_parser_omp_begin (parser, pragma_tok);
   51074                 :         305 :       return false;
   51075                 :             : 
   51076                 :         534 :     case PRAGMA_OMP_END:
   51077                 :         534 :       cp_parser_omp_end (parser, pragma_tok);
   51078                 :         534 :       return false;
   51079                 :             : 
   51080                 :          83 :     case PRAGMA_OMP_SCAN:
   51081                 :          83 :       error_at (pragma_tok->location,
   51082                 :             :                 "%<#pragma omp scan%> may only be used in "
   51083                 :             :                 "a loop construct with %<inscan%> %<reduction%> clause");
   51084                 :          83 :       break;
   51085                 :             : 
   51086                 :          25 :     case PRAGMA_OMP_SECTION:
   51087                 :          25 :       error_at (pragma_tok->location,
   51088                 :             :                 "%<#pragma omp section%> may only be used in "
   51089                 :             :                 "%<#pragma omp sections%> construct");
   51090                 :          25 :       break;
   51091                 :             : 
   51092                 :         527 :     case PRAGMA_IVDEP:
   51093                 :         527 :     case PRAGMA_UNROLL:
   51094                 :         527 :     case PRAGMA_NOVECTOR:
   51095                 :         527 :       {
   51096                 :         527 :         bool ivdep = false;
   51097                 :         527 :         tree unroll = NULL_TREE;
   51098                 :         527 :         bool novector = false;
   51099                 :         527 :         const char *pragma_str;
   51100                 :             : 
   51101                 :         527 :         switch (id)
   51102                 :             :           {
   51103                 :             :           case PRAGMA_IVDEP:
   51104                 :             :             pragma_str = "ivdep";
   51105                 :             :             break;
   51106                 :         260 :           case PRAGMA_UNROLL:
   51107                 :         260 :             pragma_str = "unroll";
   51108                 :         260 :             break;
   51109                 :         194 :           case PRAGMA_NOVECTOR:
   51110                 :         194 :             pragma_str = "novector";
   51111                 :         194 :             break;
   51112                 :             :           default:
   51113                 :             :             gcc_unreachable ();
   51114                 :             :         }
   51115                 :             : 
   51116                 :         527 :         if (context == pragma_external)
   51117                 :             :           {
   51118                 :           8 :             error_at (pragma_tok->location,
   51119                 :             :                       "%<#pragma GCC %s%> must be inside a function",
   51120                 :             :                       pragma_str);
   51121                 :           8 :             break;
   51122                 :             :           }
   51123                 :             : 
   51124                 :             :         cp_token *tok = pragma_tok;
   51125                 :             :         bool has_more = true;
   51126                 :        1102 :         do
   51127                 :             :           {
   51128                 :         551 :             switch (cp_parser_pragma_kind (tok))
   51129                 :             :               {
   51130                 :          73 :                 case PRAGMA_IVDEP:
   51131                 :          73 :                   {
   51132                 :          73 :                     if (tok != pragma_tok)
   51133                 :           8 :                       tok = cp_lexer_consume_token (parser->lexer);
   51134                 :          73 :                     ivdep = cp_parser_pragma_ivdep (parser, tok);
   51135                 :          73 :                     break;
   51136                 :             :                   }
   51137                 :         276 :                 case PRAGMA_UNROLL:
   51138                 :         276 :                   {
   51139                 :         276 :                     if (tok != pragma_tok)
   51140                 :          16 :                       tok = cp_lexer_consume_token (parser->lexer);
   51141                 :         276 :                     unroll = cp_parser_pragma_unroll (parser, tok);
   51142                 :         276 :                     break;
   51143                 :             :                   }
   51144                 :         202 :                 case PRAGMA_NOVECTOR:
   51145                 :         202 :                   {
   51146                 :         202 :                     if (tok != pragma_tok)
   51147                 :           8 :                       tok = cp_lexer_consume_token (parser->lexer);
   51148                 :         202 :                     novector = cp_parser_pragma_novector (parser, tok);
   51149                 :         202 :                     break;
   51150                 :             :                   }
   51151                 :             :                 default:
   51152                 :             :                   has_more = false;
   51153                 :             :                   break;
   51154                 :             :               }
   51155                 :         551 :             tok = cp_lexer_peek_token (the_parser->lexer);
   51156                 :        1070 :             has_more = has_more && tok->type == CPP_PRAGMA;
   51157                 :             :           }
   51158                 :             :         while (has_more);
   51159                 :             : 
   51160                 :         519 :         if (tok->type != CPP_KEYWORD
   51161                 :         519 :             || (tok->keyword != RID_FOR
   51162                 :          52 :                 && tok->keyword != RID_WHILE
   51163                 :          16 :                 && tok->keyword != RID_DO))
   51164                 :             :           {
   51165                 :           0 :             cp_parser_error (parser, "for, while or do statement expected");
   51166                 :           0 :             return false;
   51167                 :             :           }
   51168                 :         519 :         cp_parser_iteration_statement (parser, if_p, ivdep, unroll, novector);
   51169                 :         519 :         return true;
   51170                 :             :       }
   51171                 :             : 
   51172                 :     1873612 :     default:
   51173                 :     1873612 :       gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
   51174                 :     1873612 :       c_invoke_pragma_handler (id);
   51175                 :     1873612 :       break;
   51176                 :             : 
   51177                 :          24 :     bad_stmt:
   51178                 :          24 :       cp_parser_error (parser, "expected declaration specifiers");
   51179                 :          24 :       break;
   51180                 :             :     }
   51181                 :             : 
   51182                 :     1874038 :   cp_parser_skip_to_pragma_eol (parser, pragma_tok);
   51183                 :     1874038 :   return ret;
   51184                 :             : }
   51185                 :             : 
   51186                 :             : /* Helper for pragma_lex in preprocess-only mode; in this mode, we have not
   51187                 :             :    populated the lexer with any tokens (the tokens rather being read by
   51188                 :             :    c-ppoutput.c's machinery), so we need to read enough tokens now to handle
   51189                 :             :    a pragma.  */
   51190                 :             : static void
   51191                 :        6856 : maybe_read_tokens_for_pragma_lex ()
   51192                 :             : {
   51193                 :        6856 :   const auto lexer = the_parser->lexer;
   51194                 :        6856 :   if (!lexer->buffer->is_empty ())
   51195                 :             :     return;
   51196                 :             : 
   51197                 :             :   /* Read the rest of the tokens comprising the pragma line.  */
   51198                 :       11895 :   cp_token *tok;
   51199                 :       11895 :   do
   51200                 :             :     {
   51201                 :       11895 :       tok = vec_safe_push (lexer->buffer, cp_token ());
   51202                 :       11895 :       cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok);
   51203                 :       11895 :       gcc_assert (tok->type != CPP_EOF);
   51204                 :       11895 :     } while (tok->type != CPP_PRAGMA_EOL);
   51205                 :        5067 :   lexer->next_token = lexer->buffer->address ();
   51206                 :        5067 :   lexer->last_token = lexer->next_token + lexer->buffer->length () - 1;
   51207                 :             : }
   51208                 :             : 
   51209                 :             : /* The interface the pragma parsers have to the lexer.  */
   51210                 :             : 
   51211                 :             : enum cpp_ttype
   51212                 :     5286294 : pragma_lex (tree *value, location_t *loc)
   51213                 :             : {
   51214                 :     5286294 :   if (flag_preprocess_only)
   51215                 :        6856 :     maybe_read_tokens_for_pragma_lex ();
   51216                 :             : 
   51217                 :     5286294 :   cp_token *tok = cp_lexer_peek_token (the_parser->lexer);
   51218                 :     5286294 :   enum cpp_ttype ret = tok->type;
   51219                 :             : 
   51220                 :     5286294 :   *value = tok->u.value;
   51221                 :     5286294 :   if (loc)
   51222                 :     4374418 :     *loc = tok->location;
   51223                 :             : 
   51224                 :     5286294 :   if (ret == CPP_PRAGMA_EOL)
   51225                 :             :     ret = CPP_EOF;
   51226                 :     4962329 :   else if (ret == CPP_STRING)
   51227                 :     1133889 :     *value = cp_parser_string_literal (the_parser, /*translate=*/false,
   51228                 :             :                                        /*wide_ok=*/false);
   51229                 :             :   else
   51230                 :             :     {
   51231                 :     3828440 :       if (ret == CPP_KEYWORD)
   51232                 :      110585 :         ret = CPP_NAME;
   51233                 :     3828440 :       cp_lexer_consume_token (the_parser->lexer);
   51234                 :             :     }
   51235                 :             : 
   51236                 :     5286294 :   return ret;
   51237                 :             : }
   51238                 :             : 
   51239                 :             : void
   51240                 :        5067 : pragma_lex_discard_to_eol ()
   51241                 :             : {
   51242                 :             :   /* We have already read all the tokens, so we just need to discard
   51243                 :             :      them here.  */
   51244                 :        5067 :   const auto lexer = the_parser->lexer;
   51245                 :        5067 :   lexer->next_token = lexer->last_token;
   51246                 :        5067 :   lexer->buffer->truncate (0);
   51247                 :        5067 : }
   51248                 :             : 
   51249                 :             : 
   51250                 :             : /* External interface.  */
   51251                 :             : 
   51252                 :             : /* Parse one entire translation unit.  */
   51253                 :             : 
   51254                 :             : void
   51255                 :       99893 : c_parse_file (void)
   51256                 :             : {
   51257                 :       99893 :   static bool already_called = false;
   51258                 :             : 
   51259                 :       99893 :   if (already_called)
   51260                 :           0 :     fatal_error (input_location,
   51261                 :             :                  "multi-source compilation not implemented for C++");
   51262                 :       99893 :   already_called = true;
   51263                 :             : 
   51264                 :             :   /* cp_lexer_new_main is called before doing any GC allocation
   51265                 :             :      because tokenization might load a PCH file.  */
   51266                 :       99893 :   cp_lexer_new_main ();
   51267                 :             : 
   51268                 :       99853 :   cp_parser_translation_unit (the_parser);
   51269                 :       99762 :   class_decl_loc_t::diag_mismatched_tags ();
   51270                 :             : 
   51271                 :       99762 :   the_parser = NULL;
   51272                 :             : 
   51273                 :       99762 :   finish_translation_unit ();
   51274                 :       99762 : }
   51275                 :             : 
   51276                 :             : /* Create an identifier for a generic parameter type (a synthesized
   51277                 :             :    template parameter implied by `auto' or a concept identifier). */
   51278                 :             : 
   51279                 :             : static GTY(()) int generic_parm_count;
   51280                 :             : static tree
   51281                 :      306241 : make_generic_type_name ()
   51282                 :             : {
   51283                 :      306241 :   char buf[32];
   51284                 :      306241 :   sprintf (buf, "auto:%d", ++generic_parm_count);
   51285                 :      306241 :   return get_identifier (buf);
   51286                 :             : }
   51287                 :             : 
   51288                 :             : /* Add an implicit template type parameter to the CURRENT_TEMPLATE_PARMS
   51289                 :             :    (creating a new template parameter list if necessary).  Returns the newly
   51290                 :             :    created template type parm.  */
   51291                 :             : 
   51292                 :             : static tree
   51293                 :      306243 : synthesize_implicit_template_parm  (cp_parser *parser, tree constr)
   51294                 :             : {
   51295                 :             :   /* A requires-clause is not a function and cannot have placeholders.  */
   51296                 :      306243 :   if (current_binding_level->requires_expression)
   51297                 :             :     {
   51298                 :           2 :       error ("placeholder type not allowed in this context");
   51299                 :           2 :       return error_mark_node;
   51300                 :             :     }
   51301                 :             : 
   51302                 :      306241 :   gcc_assert (current_binding_level->kind == sk_function_parms);
   51303                 :             : 
   51304                 :             :   /* We are either continuing a function template that already contains implicit
   51305                 :             :      template parameters, creating a new fully-implicit function template, or
   51306                 :             :      extending an existing explicit function template with implicit template
   51307                 :             :      parameters.  */
   51308                 :             : 
   51309                 :      306241 :   cp_binding_level *const entry_scope = current_binding_level;
   51310                 :             : 
   51311                 :      306241 :   bool become_template = false;
   51312                 :      306241 :   cp_binding_level *parent_scope = 0;
   51313                 :             : 
   51314                 :      306241 :   if (parser->implicit_template_scope)
   51315                 :             :     {
   51316                 :      118458 :       gcc_assert (parser->implicit_template_parms);
   51317                 :             : 
   51318                 :      118458 :       current_binding_level = parser->implicit_template_scope;
   51319                 :             :     }
   51320                 :             :   else
   51321                 :             :     {
   51322                 :             :       /* Roll back to the existing template parameter scope (in the case of
   51323                 :             :          extending an explicit function template) or introduce a new template
   51324                 :             :          parameter scope ahead of the function parameter scope (or class scope
   51325                 :             :          in the case of out-of-line member definitions).  The function scope is
   51326                 :             :          added back after template parameter synthesis below.  */
   51327                 :             : 
   51328                 :             :       cp_binding_level *scope = entry_scope;
   51329                 :             : 
   51330                 :      375566 :       while (scope->kind == sk_function_parms)
   51331                 :             :         {
   51332                 :      187783 :           parent_scope = scope;
   51333                 :      187783 :           scope = scope->level_chain;
   51334                 :             :         }
   51335                 :      375293 :       if (current_class_type && !LAMBDA_TYPE_P (current_class_type))
   51336                 :             :         {
   51337                 :             :           /* If not defining a class, then any class scope is a scope level in
   51338                 :             :              an out-of-line member definition.  In this case simply wind back
   51339                 :             :              beyond the first such scope to inject the template parameter list.
   51340                 :             :              Otherwise wind back to the class being defined.  The latter can
   51341                 :             :              occur in class member friend declarations such as:
   51342                 :             : 
   51343                 :             :                class A {
   51344                 :             :                  void foo (auto);
   51345                 :             :                };
   51346                 :             :                class B {
   51347                 :             :                  friend void A::foo (auto);
   51348                 :             :                };
   51349                 :             : 
   51350                 :             :             The template parameter list synthesized for the friend declaration
   51351                 :             :             must be injected in the scope of 'B'.  This can also occur in
   51352                 :             :             erroneous cases such as:
   51353                 :             : 
   51354                 :             :                struct A {
   51355                 :             :                  struct B {
   51356                 :             :                    void foo (auto);
   51357                 :             :                  };
   51358                 :             :                  void B::foo (auto) {}
   51359                 :             :                };
   51360                 :             : 
   51361                 :             :             Here the attempted definition of 'B::foo' within 'A' is ill-formed
   51362                 :             :             but, nevertheless, the template parameter list synthesized for the
   51363                 :             :             declarator should be injected into the scope of 'A' as if the
   51364                 :             :             ill-formed template was specified explicitly.  */
   51365                 :             : 
   51366                 :        5489 :           while (scope->kind == sk_class && !scope->defining_class_p)
   51367                 :             :             {
   51368                 :          66 :               parent_scope = scope;
   51369                 :          66 :               scope = scope->level_chain;
   51370                 :             :             }
   51371                 :             :         }
   51372                 :             : 
   51373                 :      187783 :       current_binding_level = scope;
   51374                 :             : 
   51375                 :      187783 :       if (scope->kind != sk_template_parms
   51376                 :      187783 :           || !function_being_declared_is_template_p (parser))
   51377                 :             :         {
   51378                 :             :           /* Introduce a new template parameter list for implicit template
   51379                 :             :              parameters.  */
   51380                 :             : 
   51381                 :      187724 :           become_template = true;
   51382                 :             : 
   51383                 :      187724 :           parser->implicit_template_scope
   51384                 :      187724 :               = begin_scope (sk_template_parms, NULL);
   51385                 :             : 
   51386                 :      187724 :           ++processing_template_decl;
   51387                 :             : 
   51388                 :      187724 :           parser->fully_implicit_function_template_p = true;
   51389                 :      187724 :           ++parser->num_template_parameter_lists;
   51390                 :             :         }
   51391                 :             :       else
   51392                 :             :         {
   51393                 :             :           /* Synthesize implicit template parameters at the end of the explicit
   51394                 :             :              template parameter list.  */
   51395                 :             : 
   51396                 :          59 :           gcc_assert (current_template_parms);
   51397                 :             : 
   51398                 :          59 :           parser->implicit_template_scope = scope;
   51399                 :             : 
   51400                 :          59 :           tree v = INNERMOST_TEMPLATE_PARMS (current_template_parms);
   51401                 :          59 :           parser->implicit_template_parms
   51402                 :          59 :             = TREE_VEC_ELT (v, TREE_VEC_LENGTH (v) - 1);
   51403                 :             :         }
   51404                 :             :     }
   51405                 :             : 
   51406                 :             :   /* Synthesize a new template parameter and track the current template
   51407                 :             :      parameter chain with implicit_template_parms.  */
   51408                 :             : 
   51409                 :      306241 :   tree proto = constr ? DECL_INITIAL (constr) : NULL_TREE;
   51410                 :      306241 :   tree synth_id = make_generic_type_name ();
   51411                 :      306241 :   bool non_type = false;
   51412                 :             : 
   51413                 :             :   /* Synthesize the type template parameter.  */
   51414                 :      306241 :   gcc_assert(!proto || TREE_CODE (proto) == TYPE_DECL);
   51415                 :      306241 :   tree synth_tmpl_parm = finish_template_type_parm (class_type_node, synth_id);
   51416                 :             : 
   51417                 :      306241 :   if (become_template)
   51418                 :      187724 :     current_template_parms = tree_cons (size_int (current_template_depth + 1),
   51419                 :             :                                         NULL_TREE, current_template_parms);
   51420                 :             : 
   51421                 :             :   /* Attach the constraint to the parm before processing.  */
   51422                 :      306241 :   tree node = build_tree_list (NULL_TREE, synth_tmpl_parm);
   51423                 :      306241 :   TREE_TYPE (node) = constr;
   51424                 :      306241 :   tree new_parm
   51425                 :      306241 :     = process_template_parm (parser->implicit_template_parms,
   51426                 :             :                              input_location,
   51427                 :             :                              node,
   51428                 :             :                              /*non_type=*/non_type,
   51429                 :             :                              /*param_pack=*/false);
   51430                 :             :   // Process_template_parm returns the list of parms, and
   51431                 :             :   // parser->implicit_template_parms holds the final node of the parm
   51432                 :             :   // list.  We really want to manipulate the newly appended element.
   51433                 :      306241 :   gcc_checking_assert (!parser->implicit_template_parms
   51434                 :             :                        || parser->implicit_template_parms == new_parm);
   51435                 :      306241 :   if (parser->implicit_template_parms)
   51436                 :      118517 :     new_parm = TREE_CHAIN (new_parm);
   51437                 :      306241 :   gcc_checking_assert (!TREE_CHAIN (new_parm));
   51438                 :             : 
   51439                 :             :   // Record the last implicit parm node
   51440                 :      306241 :   parser->implicit_template_parms = new_parm;
   51441                 :             : 
   51442                 :             :   /* Mark the synthetic declaration "virtual". This is used when
   51443                 :             :      comparing template-heads to determine if whether an abbreviated
   51444                 :             :      function template is equivalent to an explicit template.
   51445                 :             : 
   51446                 :             :      Note that DECL_ARTIFICIAL is used elsewhere for template
   51447                 :             :      parameters.  */
   51448                 :      306241 :   if (TREE_VALUE (new_parm) != error_mark_node)
   51449                 :      306241 :     DECL_IMPLICIT_TEMPLATE_PARM_P (TREE_VALUE (new_parm)) = true;
   51450                 :             : 
   51451                 :      306241 :   tree new_decl = get_local_decls ();
   51452                 :      306241 :   if (non_type)
   51453                 :             :     /* Return the TEMPLATE_PARM_INDEX, not the PARM_DECL.  */
   51454                 :             :     new_decl = DECL_INITIAL (new_decl);
   51455                 :             : 
   51456                 :             :   /* If creating a fully implicit function template, start the new implicit
   51457                 :             :      template parameter list with this synthesized type, otherwise grow the
   51458                 :             :      current template parameter list.  */
   51459                 :             : 
   51460                 :      306241 :   if (become_template)
   51461                 :             :     {
   51462                 :      187724 :       parent_scope->level_chain = current_binding_level;
   51463                 :             : 
   51464                 :      187724 :       tree new_parms = make_tree_vec (1);
   51465                 :      187724 :       TREE_VEC_ELT (new_parms, 0) = parser->implicit_template_parms;
   51466                 :      187724 :       TREE_VALUE (current_template_parms) = new_parms;
   51467                 :             :     }
   51468                 :             :   else
   51469                 :             :     {
   51470                 :      118517 :       tree& new_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
   51471                 :      118517 :       int new_parm_idx = TREE_VEC_LENGTH (new_parms);
   51472                 :      118517 :       new_parms = grow_tree_vec (new_parms, new_parm_idx + 1);
   51473                 :      118517 :       TREE_VEC_ELT (new_parms, new_parm_idx) = parser->implicit_template_parms;
   51474                 :             :     }
   51475                 :             : 
   51476                 :             :   /* If the new parameter was constrained, we need to add that to the
   51477                 :             :      constraints in the template parameter list.  */
   51478                 :      306241 :   if (tree req = TEMPLATE_PARM_CONSTRAINTS (new_parm))
   51479                 :             :     {
   51480                 :        5156 :       tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
   51481                 :        5156 :       reqs = combine_constraint_expressions (reqs, req);
   51482                 :        5156 :       TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
   51483                 :             :     }
   51484                 :             : 
   51485                 :      306241 :   current_binding_level = entry_scope;
   51486                 :             : 
   51487                 :      306241 :   return new_decl;
   51488                 :             : }
   51489                 :             : 
   51490                 :             : /* Finish the declaration of a fully implicit function template.  Such a
   51491                 :             :    template has no explicit template parameter list so has not been through the
   51492                 :             :    normal template head and tail processing.  synthesize_implicit_template_parm
   51493                 :             :    tries to do the head; this tries to do the tail.  MEMBER_DECL_OPT should be
   51494                 :             :    provided if the declaration is a class member such that its template
   51495                 :             :    declaration can be completed.  If MEMBER_DECL_OPT is provided the finished
   51496                 :             :    form is returned.  Otherwise NULL_TREE is returned. */
   51497                 :             : 
   51498                 :             : static tree
   51499                 :      187724 : finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
   51500                 :             : {
   51501                 :      187724 :   gcc_assert (parser->fully_implicit_function_template_p);
   51502                 :             : 
   51503                 :      187401 :   if (member_decl_opt && member_decl_opt != error_mark_node
   51504                 :      375119 :       && DECL_VIRTUAL_P (member_decl_opt))
   51505                 :             :     {
   51506                 :           3 :       error_at (DECL_SOURCE_LOCATION (member_decl_opt),
   51507                 :             :                 "implicit templates may not be %<virtual%>");
   51508                 :           3 :       DECL_VIRTUAL_P (member_decl_opt) = false;
   51509                 :             :     }
   51510                 :             : 
   51511                 :      187724 :   if (member_decl_opt)
   51512                 :      187401 :     member_decl_opt = finish_member_template_decl (member_decl_opt);
   51513                 :      187724 :   end_template_decl ();
   51514                 :             : 
   51515                 :      187724 :   parser->fully_implicit_function_template_p = false;
   51516                 :      187724 :   parser->implicit_template_parms = 0;
   51517                 :      187724 :   parser->implicit_template_scope = 0;
   51518                 :      187724 :   --parser->num_template_parameter_lists;
   51519                 :             : 
   51520                 :      187724 :   return member_decl_opt;
   51521                 :             : }
   51522                 :             : 
   51523                 :             : /* Like finish_fully_implicit_template, but to be used in error
   51524                 :             :    recovery, rearranging scopes so that we restore the state we had
   51525                 :             :    before synthesize_implicit_template_parm inserted the implement
   51526                 :             :    template parms scope.  */
   51527                 :             : 
   51528                 :             : static void
   51529                 :          69 : abort_fully_implicit_template (cp_parser *parser)
   51530                 :             : {
   51531                 :          69 :   cp_binding_level *return_to_scope = current_binding_level;
   51532                 :             : 
   51533                 :          69 :   if (parser->implicit_template_scope
   51534                 :           3 :       && return_to_scope != parser->implicit_template_scope)
   51535                 :             :     {
   51536                 :           3 :       cp_binding_level *child = return_to_scope;
   51537                 :           3 :       for (cp_binding_level *scope = child->level_chain;
   51538                 :           3 :            scope != parser->implicit_template_scope;
   51539                 :           0 :            scope = child->level_chain)
   51540                 :           0 :         child = scope;
   51541                 :           3 :       child->level_chain = parser->implicit_template_scope->level_chain;
   51542                 :           3 :       parser->implicit_template_scope->level_chain = return_to_scope;
   51543                 :           3 :       current_binding_level = parser->implicit_template_scope;
   51544                 :           3 :     }
   51545                 :             :   else
   51546                 :          66 :     return_to_scope = return_to_scope->level_chain;
   51547                 :             : 
   51548                 :          69 :   finish_fully_implicit_template (parser, NULL);
   51549                 :             : 
   51550                 :          69 :   gcc_assert (current_binding_level == return_to_scope);
   51551                 :          69 : }
   51552                 :             : 
   51553                 :             : /* Helper function for diagnostics that have complained about things
   51554                 :             :    being used with 'extern "C"' linkage.
   51555                 :             : 
   51556                 :             :    Attempt to issue a note showing where the 'extern "C"' linkage began.  */
   51557                 :             : 
   51558                 :             : void
   51559                 :          34 : maybe_show_extern_c_location (void)
   51560                 :             : {
   51561                 :          34 :   if (the_parser->innermost_linkage_specification_location != UNKNOWN_LOCATION)
   51562                 :          34 :     inform (the_parser->innermost_linkage_specification_location,
   51563                 :             :             "%<extern \"C\"%> linkage started here");
   51564                 :          34 : }
   51565                 :             : 
   51566                 :             : #include "gt-cp-parser.h"
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.